"use client";

import { useMemo, useState } from "react";
import { usePenaltyTypesReference } from "@/hooks/usePenaltyTypesReference";
import type { PenaltyValueKindDTO } from "@/lib/types/PenaltyTypesReferenceDTO";
import { ProtestViewModel } from "../../lib/view-models/ProtestViewModel";
import { Modal } from "@/components/shared/Modal";
import { Button } from "@/ui/Button";
import { Card } from "@/ui/Card";
import { Stack } from "@/ui/Stack";
import { Text } from "@/ui/Text";
import { Heading } from "@/ui/Heading";
import { Icon } from "@/ui/Icon";
import { TextArea } from "@/ui/TextArea";
import { Input } from "@/ui/Input";
import { Grid } from "@/ui/Grid";
import {
  AlertCircle,
  Video,
  Clock,
  Grid3x3,
  TrendingDown,
  CheckCircle,
  XCircle,
  AlertTriangle,
  ShieldAlert,
  Ban,
  DollarSign,
  FileWarning,
  type LucideIcon,
} from "lucide-react";

type PenaltyType = string;

interface ReviewProtestModalProps {
  protest: ProtestViewModel | null;
  onClose: () => void;
  onAccept: (
    protestId: string,
    penaltyType: PenaltyType,
    penaltyValue: number,
    stewardNotes: string
  ) => Promise<void>;
  onReject: (protestId: string, stewardNotes: string) => Promise<void>;
}

export function ReviewProtestModal({
  protest,
  onClose,
  onAccept,
  onReject,
}: ReviewProtestModalProps) {
  const [decision, setDecision] = useState<"accept" | "reject" | null>(null);
  const [penaltyType, setPenaltyType] = useState<PenaltyType>("time_penalty");
  const [penaltyValue, setPenaltyValue] = useState<number>(5);
  const [stewardNotes, setStewardNotes] = useState("");
  const [submitting, setSubmitting] = useState(false);
  const [showConfirmation, setShowConfirmation] = useState(false);

  const { data: penaltyTypesReferenceResult, isLoading: penaltyTypesLoading } = usePenaltyTypesReference();

  const penaltyOptions = useMemo(() => {
    const refs = penaltyTypesReferenceResult?.isOk() ? penaltyTypesReferenceResult.unwrap().penaltyTypes : [];
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    return refs.map((ref: any) => ({
      type: ref.type as PenaltyType,
      name: getPenaltyName(ref.type),
      requiresValue: ref.requiresValue,
      valueLabel: getPenaltyValueLabel(ref.valueKind),
      defaultValue: getPenaltyDefaultValue(ref.type, ref.valueKind),
      Icon: getPenaltyIcon(ref.type),
      colorClass: getPenaltyColor(ref.type),
    }));
  }, [penaltyTypesReferenceResult]);

  const selectedPenalty = useMemo(() => {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    return penaltyOptions.find((p: any) => p.type === penaltyType);
  }, [penaltyOptions, penaltyType]);

  if (!protest) return null;

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

    setSubmitting(true);
    try {
      if (decision === "accept") {
        await onAccept(protest.id, penaltyType, penaltyValue, stewardNotes);
      } else {
        await onReject(protest.id, stewardNotes);
      }
      onClose();
    } catch (err) {
      alert(err instanceof Error ? err.message : "Failed to submit decision");
    } finally {
      setSubmitting(false);
      setShowConfirmation(false);
    }
  };

  function getPenaltyIcon(type: PenaltyType) {
    switch (type) {
      case "time_penalty":
        return Clock;
      case "grid_penalty":
        return Grid3x3;
      case "points_deduction":
        return TrendingDown;
      case "disqualification":
        return XCircle;
      case "warning":
        return AlertTriangle;
      case "license_points":
        return ShieldAlert;
      case "probation":
        return FileWarning;
      case "fine":
        return DollarSign;
      case "race_ban":
        return Ban;
      default:
        return AlertCircle;
    }
  }

  function getPenaltyName(type: PenaltyType) {
    switch (type) {
      case "time_penalty":
        return "Time Penalty";
      case "grid_penalty":
        return "Grid Penalty";
      case "points_deduction":
        return "Points Deduction";
      case "disqualification":
        return "Disqualification";
      case "warning":
        return "Warning";
      case "license_points":
        return "License Points";
      case "probation":
        return "Probation";
      case "fine":
        return "Fine";
      case "race_ban":
        return "Race Ban";
      default:
        return type.replaceAll("_", " ");
    }
  }

  function getPenaltyValueLabel(valueKind: PenaltyValueKindDTO): string {
    switch (valueKind) {
      case "seconds":
        return "seconds";
      case "grid_positions":
        return "grid positions";
      case "points":
        return "points";
      case "races":
        return "races";
      case "none":
        return "";
    }
  }

  function getPenaltyDefaultValue(type: PenaltyType, valueKind: PenaltyValueKindDTO): number {
    if (type === "license_points") return 2;
    if (type === "race_ban") return 1;
    switch (valueKind) {
      case "seconds":
        return 5;
      case "grid_positions":
        return 3;
      case "points":
        return 5;
      case "races":
        return 1;
      case "none":
        return 0;
    }
  }

  function getPenaltyColor(type: PenaltyType) {
    switch (type) {
      case "time_penalty":
        return "text-blue-400 bg-blue-500/10 border-blue-500/30";
      case "grid_penalty":
        return "text-purple-400 bg-purple-500/10 border-purple-500/30";
      case "points_deduction":
        return "text-red-400 bg-red-500/10 border-red-500/30";
      case "disqualification":
        return "text-red-500 bg-red-500/10 border-red-500/30";
      case "warning":
        return "text-yellow-400 bg-yellow-500/10 border-yellow-500/30";
      case "license_points":
        return "text-orange-400 bg-orange-500/10 border-orange-500/30";
      case "probation":
        return "text-amber-400 bg-amber-500/10 border-amber-500/30";
      case "fine":
        return "text-green-400 bg-green-500/10 border-green-500/30";
      case "race_ban":
        return "text-red-600 bg-red-600/10 border-red-600/30";
      default:
        return "text-warning-amber bg-warning-amber/10 border-warning-amber/30";
    }
  }

  if (showConfirmation) {
    return (
      <Modal title="Confirm Decision" isOpen={true} onOpenChange={() => setShowConfirmation(false)}>
        <Stack gap={6} p={6}>
          <Stack align="center">
            <Stack gap={4}>
              {decision === "accept" ? (
                <Stack direction="row" justify="center">
                  <Stack h="16" w="16" rounded="full" bg="bg-orange-500/20" align="center" justify="center">
                    <Icon icon={AlertCircle} size={8} color="text-orange-400" />
                  </Stack>
                </Stack>
              ) : (
                <Stack direction="row" justify="center">
                  <Stack h="16" w="16" rounded="full" bg="bg-gray-500/20" align="center" justify="center">
                    <Icon icon={XCircle} size={8} color="text-gray-400" />
                  </Stack>
                </Stack>
              )}
              <Stack align="center">
                <Heading level={3} weight="bold" color="text-white">Confirm Decision</Heading>
                <Text color="text-gray-400" mt={2} block textAlign="center">
                  {decision === "accept"
                    ? (selectedPenalty?.requiresValue
                        ? `Issue ${penaltyValue} ${selectedPenalty.valueLabel} penalty?`
                        : `Issue ${selectedPenalty?.name ?? penaltyType} penalty?`)
                    : "Reject this protest?"}
                </Text>
              </Stack>
            </Stack>
          </Stack>

          <Card p={4} className="bg-gray-800/50">
            <Text size="sm" color="text-gray-300" block>{stewardNotes}</Text>
          </Card>

          <Stack direction="row" gap={3}>
            <Button
              variant="secondary"
              fullWidth
              onClick={() => setShowConfirmation(false)}
              disabled={submitting}
            >
              Cancel
            </Button>
            <Button
              variant="primary"
              fullWidth
              onClick={handleSubmit}
              disabled={submitting}
            >
              {submitting ? "Submitting..." : "Confirm Decision"}
            </Button>
          </Stack>
        </Stack>
      </Modal>
    );
  }

  return (
    <Modal title="Review Protest" isOpen={true} onOpenChange={onClose}>
      <Stack gap={6} p={6}>
        <Stack direction="row" align="start" gap={4}>
          <Stack h="12" w="12" rounded="full" bg="bg-orange-500/20" align="center" justify="center" flexShrink={0}>
            <Icon icon={AlertCircle} size={6} color="text-orange-400" />
          </Stack>
          <Stack flexGrow={1}>
            <Heading level={2} weight="bold" color="text-white">Review Protest</Heading>
            <Text color="text-gray-400" mt={1} block>
              Protest #{protest.id.substring(0, 8)}
            </Text>
          </Stack>
        </Stack>

        <Stack gap={4}>
          <Card p={4} className="bg-gray-800/50">
            <Stack gap={3}>
              <Stack direction="row" align="center" justify="between">
                <Text size="sm" color="text-gray-400">Filed Date</Text>
                <Text size="sm" color="text-white" weight="medium">
                  {protest.formattedSubmittedAt}
                </Text>
              </Stack>
              <Stack direction="row" align="center" justify="between">
                <Text size="sm" color="text-gray-400">Incident Lap</Text>
                <Text size="sm" color="text-white" weight="medium">
                  Lap {protest.incident?.lap || 'N/A'}
                </Text>
              </Stack>
              <Stack direction="row" align="center" justify="between">
                <Text size="sm" color="text-gray-400">Status</Text>
                <Stack as="span" px={2} py={1} rounded="sm" bg="bg-orange-500/20">
                  <Text size="xs" weight="medium" color="text-orange-400">
                    {protest.statusDisplay}
                  </Text>
                </Stack>
              </Stack>
            </Stack>
          </Card>

          <Stack>
            <Text as="label" size="sm" weight="medium" color="text-gray-400" block mb={2}>
              Description
            </Text>
            <Card p={4} className="bg-gray-800/50">
              <Text color="text-gray-300" block>{protest.incident?.description || protest.description}</Text>
            </Card>
          </Stack>

          {protest.comment && (
            <Stack>
              <Text as="label" size="sm" weight="medium" color="text-gray-400" block mb={2}>
                Additional Comment
              </Text>
              <Card p={4} className="bg-gray-800/50">
                <Text color="text-gray-300" block>{protest.comment}</Text>
              </Card>
            </Stack>
          )}

          {protest.proofVideoUrl && (
            <Stack>
              <Text as="label" size="sm" weight="medium" color="text-gray-400" block mb={2}>
                Evidence
              </Text>
              <Card p={4} className="bg-gray-800/50">
                <Stack
                  as="a"
                  {...({
                    href: protest.proofVideoUrl,
                    target: "_blank",
                    rel: "noopener noreferrer"
                  } as any)}
                  direction="row"
                  align="center"
                  gap={2}
                  color="text-orange-400"
                  className="transition-all hover:text-orange-300"
                >
                  <Icon icon={Video} size={4} />
                  <Text size="sm">View video evidence</Text>
                </Stack>
              </Card>
            </Stack>
          )}
        </Stack>
        <Stack borderTop borderColor="border-gray-800" pt={6}>
          <Stack gap={4}>
            <Heading level={3} weight="semibold" color="text-white">Stewarding Decision</Heading>

            <Grid cols={2} gap={3}>
              <Button
                variant={decision === "accept" ? "primary" : "secondary"}
                fullWidth
                onClick={() => setDecision("accept")}
              >
                <Stack direction="row" align="center" gap={2} center>
                  <Icon icon={CheckCircle} size={4} />
                  Accept Protest
                </Stack>
              </Button>
              <Button
                variant={decision === "reject" ? "primary" : "secondary"}
                fullWidth
                onClick={() => setDecision("reject")}
              >
                <Stack direction="row" align="center" gap={2} center>
                  <Icon icon={XCircle} size={4} />
                  Reject Protest
                </Stack>
              </Button>
            </Grid>

            {decision === "accept" && (
              <Stack gap={4}>
                <Stack>
                  <Text as="label" size="sm" weight="medium" color="text-gray-400" block mb={2}>
                    Penalty Type
                  </Text>

                  {penaltyTypesLoading ? (
                    <Text size="sm" color="text-gray-500">Loading penalty types…</Text>
                  ) : (
                    <Grid cols={3} gap={2}>
                      {penaltyOptions.map(({ type, name, Icon: PenaltyIcon, colorClass, defaultValue }: { type: string; name: string; Icon: LucideIcon; colorClass: string; defaultValue: number }) => {
                        const isSelected = penaltyType === type;
                        return (
                          <Stack
                            key={type}
                            as="button"
                            onClick={() => {
                              setPenaltyType(type);
                              setPenaltyValue(defaultValue);
                            }}
                            p={3}
                            rounded="lg"
                            border
                            {...({ borderWidth: isSelected ? "2px" : "1px" } as any)}
                            className={`transition-all ${isSelected ? colorClass : "bg-iron-gray/50 border-charcoal-outline hover:border-gray-600"}`}
                          >
                            <Icon icon={PenaltyIcon} size={5} className="mx-auto mb-1" color={isSelected ? undefined : "text-gray-400"} />
                            <Text size="xs" weight="medium" color={isSelected ? undefined : "text-gray-400"} block textAlign="center">{name}</Text>
                          </Stack>
                        );
                      })}
                    </Grid>
                  )}
                </Stack>

                {selectedPenalty?.requiresValue && (
                  <Stack>
                    <Text as="label" size="sm" weight="medium" color="text-gray-400" block mb={2}>
                      Penalty Value ({selectedPenalty.valueLabel})
                    </Text>
                    <Input
                      type="number"
                      value={penaltyValue}
                      onChange={(e: React.ChangeEvent<HTMLInputElement>) => setPenaltyValue(Number(e.target.value))}
                      min={1}
                    />
                  </Stack>
                )}
              </Stack>
            )}

            <Stack>
              <Text as="label" size="sm" weight="medium" color="text-gray-400" block mb={2}>
                Steward Notes *
              </Text>
              <TextArea
                value={stewardNotes}
                onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => setStewardNotes(e.target.value)}
                placeholder="Explain your decision and reasoning..."
                rows={4}
              />
            </Stack>
          </Stack>
        </Stack>

        <Stack direction="row" gap={3} pt={4} borderTop borderColor="border-gray-800">
          <Button
            variant="secondary"
            fullWidth
            onClick={onClose}
            disabled={submitting}
          >
            Cancel
          </Button>
          <Button
            variant="primary"
            fullWidth
            onClick={() => setShowConfirmation(true)}
            disabled={!decision || !stewardNotes.trim() || submitting}
          >
            Submit Decision
          </Button>
        </Stack>
      </Stack>
    </Modal>
  );
}
