'use client';

import { useEffectiveDriverId } from "@/hooks/useEffectiveDriverId";
import { useInject } from '@/lib/di/hooks/useInject';
import { PROTEST_SERVICE_TOKEN } from '@/lib/di/tokens';
import {
  AlertCircle,
  AlertTriangle,
  CheckCircle,
  Clock,
  Gavel,
  Grid3x3,
  MessageCircle,
  Shield,
  ShieldAlert,
  TrendingDown,
  XCircle,
} from 'lucide-react';
import { useParams, useRouter } from 'next/navigation';
import { useEffect, useMemo, useState } from 'react';

import { useLeagueAdminStatus } from "@/hooks/league/useLeagueAdminStatus";
import { useProtestDetail } from "@/hooks/league/useProtestDetail";
import { routes } from '@/lib/routing/RouteConfig';
import { ProtestDetailTemplate } from '@/templates/ProtestDetailTemplate';
import { ProtestDecisionCommandModel } from '@/lib/command-models/protests/ProtestDecisionCommandModel';
import { ClientWrapperProps } from '@/lib/contracts/components/ComponentContracts';
import { ViewData } from '@/lib/contracts/view-data/ViewData';

const PENALTY_UI: Record<string, any> = {
  time_penalty: {
    label: 'Time Penalty',
    description: 'Add seconds to race result',
    icon: Clock,
    color: 'text-blue-400 bg-blue-500/10 border-blue-500/20',
    defaultValue: 5,
  },
  grid_penalty: {
    label: 'Grid Penalty',
    description: 'Grid positions for next race',
    icon: Grid3x3,
    color: 'text-purple-400 bg-purple-500/10 border-purple-500/20',
    defaultValue: 3,
  },
  points_deduction: {
    label: 'Points Deduction',
    description: 'Deduct championship points',
    icon: TrendingDown,
    color: 'text-red-400 bg-red-500/10 border-red-500/20',
    defaultValue: 5,
  },
  disqualification: {
    label: 'Disqualification',
    description: 'Disqualify from race',
    icon: XCircle,
    color: 'text-red-500 bg-red-500/10 border-red-500/20',
    defaultValue: 0,
  },
  warning: {
    label: 'Warning',
    description: 'Official warning only',
    icon: AlertTriangle,
    color: 'text-yellow-400 bg-yellow-500/10 border-yellow-500/20',
    defaultValue: 0,
  },
  license_points: {
    label: 'License Points',
    description: 'Safety rating penalty',
    icon: ShieldAlert,
    color: 'text-orange-400 bg-orange-500/10 border-orange-500/20',
    defaultValue: 2,
  },
};

export function ProtestDetailPageClient({ viewData: initialViewData }: Partial<ClientWrapperProps<ViewData>>) {
  const params = useParams();
  const router = useRouter();
  const leagueId = params.id as string;
  const protestId = params.protestId as string;
  const currentDriverId = useEffectiveDriverId();
  const protestService = useInject(PROTEST_SERVICE_TOKEN);

  // Decision state
  const [showDecisionPanel, setShowDecisionPanel] = useState(false);
  const [decision, setDecision] = useState<'uphold' | 'dismiss' | null>(null);
  const [penaltyType, setPenaltyType] = useState<string>('time_penalty');
  const [penaltyValue, setPenaltyValue] = useState<number>(5);
  const [stewardNotes, setStewardNotes] = useState('');
  const [submitting, setSubmitting] = useState(false);
  const [newComment, setNewComment] = useState('');

  // Check admin status using hook
  const { data: isAdmin, isLoading: adminLoading } = useLeagueAdminStatus(leagueId, currentDriverId || '');

  // Load protest detail using hook
  const { data: detail, isLoading: detailLoading, error, retry } = useProtestDetail(leagueId, protestId, isAdmin || false);

  // Use initial data if available
  const protestDetail = (detail || initialViewData) as any;

  // Set initial penalty values when data loads
  useEffect(() => {
    if (protestDetail?.initialPenaltyType) {
      setPenaltyType(protestDetail.initialPenaltyType);
      setPenaltyValue(protestDetail.initialPenaltyValue);
    }
  }, [protestDetail]);

  const penaltyTypes = useMemo(() => {
    const referenceItems = protestDetail?.penaltyTypes ?? [];
    return referenceItems.map((ref: any) => {
      const ui = PENALTY_UI[ref.type] ?? {
        icon: Gavel,
        color: 'text-gray-400 bg-gray-500/10 border-gray-500/20',
      };

      return {
        ...ref,
        icon: ui.icon,
        color: ui.color,
      };
    });
  }, [protestDetail?.penaltyTypes]);

  const selectedPenalty = useMemo(() => {
    return penaltyTypes.find((p: any) => p.type === penaltyType);
  }, [penaltyTypes, penaltyType]);

  const handleSubmitDecision = async () => {
    if (!decision || !stewardNotes.trim() || !protestDetail || !currentDriverId) return;

    setSubmitting(true);
    try {
      const protest = protestDetail.protest || protestDetail;

      const defaultUpheldReason = protestDetail.defaultReasons?.upheld;
      const defaultDismissedReason = protestDetail.defaultReasons?.dismissed;

      if (decision === 'uphold') {
        const requiresValue = selectedPenalty?.requiresValue ?? true;

        const commandModel = new ProtestDecisionCommandModel({
          decision,
          penaltyType,
          penaltyValue,
          stewardNotes,
        });

        const options: any = { requiresValue };

        if (defaultUpheldReason) {
          options.defaultUpheldReason = defaultUpheldReason;
        }
        if (defaultDismissedReason) {
          options.defaultDismissedReason = defaultDismissedReason;
        }

        const penaltyCommand = commandModel.toApplyPenaltyCommand(
          protest.raceId || protestDetail.race?.id,
          protest.accusedDriverId || protestDetail.accusedDriver?.id,
          currentDriverId,
          protest.id || protestDetail.protestId,
          options,
        );

        const result = await protestService.applyPenalty(penaltyCommand);
        if (result.isErr()) {
          throw new Error(result.getError().message);
        }
      } else {
        const warningRef = protestDetail.penaltyTypes.find((p: any) => p.type === 'warning');
        const requiresValue = warningRef?.requiresValue ?? false;

        const commandModel = new ProtestDecisionCommandModel({
          decision,
          penaltyType: 'warning',
          penaltyValue: 0,
          stewardNotes,
        });

        const options: any = { requiresValue };

        if (defaultUpheldReason) {
          options.defaultUpheldReason = defaultUpheldReason;
        }
        if (defaultDismissedReason) {
          options.defaultDismissedReason = defaultDismissedReason;
        }

        const penaltyCommand = commandModel.toApplyPenaltyCommand(
          protest.raceId || protestDetail.race?.id,
          protest.accusedDriverId || protestDetail.accusedDriver?.id,
          currentDriverId,
          protest.id || protestDetail.protestId,
          options,
        );

        const result = await protestService.applyPenalty(penaltyCommand);
        if (result.isErr()) {
          throw new Error(result.getError().message);
        }
      }

      router.push(routes.league.stewarding(leagueId));
    } catch (err) {
      alert(err instanceof Error ? err.message : 'Failed to submit decision');
    } finally {
      setSubmitting(false);
    }
  };

  const handleRequestDefense = async () => {
    if (!protestDetail || !currentDriverId) return;

    try {
      const result = await protestService.requestDefense({
        protestId: protestDetail.protest?.id || protestDetail.protestId,
        stewardId: currentDriverId,
      });
      if (result.isErr()) {
        throw new Error(result.getError().message);
      }
      window.location.reload();
    } catch (err) {
      alert(err instanceof Error ? err.message : 'Failed to request defense');
    }
  };

  const getStatusConfig = (status: string) => {
    switch (status) {
      case 'pending':
        return { label: 'Pending Review', bg: 'bg-warning-amber/20', color: 'text-warning-amber', borderColor: 'border-warning-amber/30', icon: Clock };
      case 'under_review':
        return { label: 'Under Review', bg: 'bg-blue-500/20', color: 'text-blue-400', borderColor: 'border-blue-500/30', icon: Shield };
      case 'awaiting_defense':
        return { label: 'Awaiting Defense', bg: 'bg-purple-500/20', color: 'text-purple-400', borderColor: 'border-purple-500/30', icon: MessageCircle };
      case 'upheld':
        return { label: 'Upheld', bg: 'bg-red-500/20', color: 'text-red-400', borderColor: 'border-red-500/30', icon: CheckCircle };
      case 'dismissed':
        return { label: 'Dismissed', bg: 'bg-gray-500/20', color: 'text-gray-400', borderColor: 'border-gray-500/30', icon: XCircle };
      default:
        return { label: status, bg: 'bg-gray-500/20', color: 'text-gray-400', borderColor: 'border-gray-500/30', icon: AlertCircle };
    }
  };

  return (
    <ProtestDetailTemplate
      viewData={{}}
      protestDetail={protestDetail}
      leagueId={leagueId}
      showDecisionPanel={showDecisionPanel}
      setShowDecisionPanel={setShowDecisionPanel}
      decision={decision}
      setDecision={setDecision}
      penaltyType={penaltyType}
      setPenaltyType={setPenaltyType}
      penaltyValue={penaltyValue}
      setPenaltyValue={setPenaltyValue}
      stewardNotes={stewardNotes}
      setStewardNotes={setStewardNotes}
      submitting={submitting}
      newComment={newComment}
      setNewComment={setNewComment}
      penaltyTypes={penaltyTypes}
      selectedPenalty={selectedPenalty}
      onSubmitDecision={handleSubmitDecision}
      onRequestDefense={handleRequestDefense}
      getStatusConfig={getStatusConfig}
    />
  );
}
