import { useEffect, useState } from "react";
import {
  Alert,
  Button,
  Code,
  Divider,
  Group,
  List,
  Loader,
  Modal,
  Stack,
  Text,
  TextInput,
  Title,
} from "@mantine/core";
import { IconAlertTriangle, IconArchive, IconTrash } from "@tabler/icons-react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { notifications } from "@mantine/notifications";
import { isAxiosError } from "axios";
import {
  deleteDance,
  fetchDeleteDancePreview,
  updateDanceListingStatus,
  type DeleteDancePreview,
} from "@/api/adminDances";

interface Props {
  danceId: number | null;
  /** Optional fallback name shown while the preview is loading. */
  danceName?: string;
  opened: boolean;
  onClose: () => void;
  /** Called after a successful hard-delete or archive. */
  onSuccess?: () => void;
}

export function DeleteDanceModal({
  danceId,
  danceName,
  opened,
  onClose,
  onSuccess,
}: Props) {
  const queryClient = useQueryClient();
  const [step, setStep] = useState<1 | 2>(1);
  const [confirmName, setConfirmName] = useState("");
  const [confirmError, setConfirmError] = useState<string | null>(null);

  const previewQuery = useQuery<DeleteDancePreview>({
    queryKey: ["dance-delete-preview", danceId],
    queryFn: () => fetchDeleteDancePreview(danceId as number),
    enabled: opened && danceId !== null,
    staleTime: 0,
  });

  useEffect(() => {
    if (!opened) {
      setStep(1);
      setConfirmName("");
      setConfirmError(null);
    }
  }, [opened]);

  const archiveMutation = useMutation({
    mutationFn: () => updateDanceListingStatus(danceId as number, "ARCHIVED"),
    onSuccess: () => {
      notifications.show({
        title: "Ball arxivat",
        message: "El ball s'ha mogut a l'arxiu i ja no apareixerà al catàleg públic.",
        color: "yellow",
      });
      queryClient.invalidateQueries({ queryKey: ["dance"] });
      queryClient.invalidateQueries({ queryKey: ["admin-dances"] });
      onSuccess?.();
      onClose();
    },
    onError: () => {
      notifications.show({
        title: "Error",
        message: "No s'ha pogut arxivar el ball.",
        color: "red",
      });
    },
  });

  const deleteMutation = useMutation({
    mutationFn: () => deleteDance(danceId as number, confirmName.trim()),
    onSuccess: () => {
      notifications.show({
        title: "Ball eliminat",
        message: "El ball s'ha eliminat permanentment.",
        color: "red",
      });
      queryClient.invalidateQueries({ queryKey: ["dance"] });
      queryClient.invalidateQueries({ queryKey: ["admin-dances"] });
      onSuccess?.();
      onClose();
    },
    onError: (error) => {
      let message = "No s'ha pogut eliminar el ball.";
      if (isAxiosError(error) && error.response?.data) {
        const data = error.response.data as { detail?: string };
        if (data.detail) message = data.detail;
      }
      notifications.show({ title: "Error", message, color: "red" });
    },
  });

  const preview = previewQuery.data;
  const displayName = preview?.danceName ?? danceName ?? `#${danceId}`;
  const hasBlockers = preview && preview.blockers.length > 0;

  return (
    <Modal opened={opened} onClose={onClose} title="Eliminar ball" centered size="lg">
      <Stack gap="md">
        {previewQuery.isLoading && (
          <Group gap="xs">
            <Loader size="sm" />
            <Text size="sm" c="dimmed">Calculant impacte de l'esborrat…</Text>
          </Group>
        )}

        {previewQuery.isError && (
          <Alert color="red" icon={<IconAlertTriangle size={16} />}>
            No s'ha pogut carregar el resum d'esborrat.
          </Alert>
        )}

        {preview && step === 1 && (
          <>
            <Title order={4}>«{preview.danceName}»</Title>

            {hasBlockers ? (
              <>
                <Alert color="red" icon={<IconAlertTriangle size={16} />}>
                  <Text fw={600} mb={4}>No es pot eliminar permanentment</Text>
                  <List size="sm" spacing={4}>
                    {preview.blockers.map((b, i) => (
                      <List.Item key={i}>
                        {b.message}
                        {b.referencedIds.length > 0 && (
                          <Text size="xs" c="dimmed">
                            IDs: {b.referencedIds.join(", ")}
                          </Text>
                        )}
                      </List.Item>
                    ))}
                  </List>
                </Alert>
                <Text size="sm">
                  Pots <b>arxivar</b> el ball: deixarà d'aparèixer al catàleg
                  públic però es preserva tot l'historial. És reversible.
                </Text>
              </>
            ) : (
              <>
                <Alert color="orange" icon={<IconAlertTriangle size={16} />}>
                  <Text size="sm">
                    Aquesta acció és <b>permanent i no es pot desfer</b>.
                    S'eliminaran les dades següents:
                  </Text>
                </Alert>
                <CascadeSummaryView preview={preview} />
              </>
            )}

            <Divider />
            <Group justify="space-between">
              <Button variant="subtle" onClick={onClose}>
                Cancel·lar
              </Button>
              <Group gap="xs">
                <Button
                  color="yellow"
                  leftSection={<IconArchive size={16} />}
                  onClick={() => archiveMutation.mutate()}
                  loading={archiveMutation.isPending}
                >
                  Arxivar
                </Button>
                {!hasBlockers && (
                  <Button
                    color="red"
                    leftSection={<IconTrash size={16} />}
                    onClick={() => setStep(2)}
                  >
                    Continuar amb l'esborrat
                  </Button>
                )}
              </Group>
            </Group>
          </>
        )}

        {preview && step === 2 && !hasBlockers && (
          <>
            <Alert color="red" icon={<IconAlertTriangle size={16} />}>
              <Text fw={600}>Confirmació final</Text>
              <Text size="sm">
                Per eliminar permanentment el ball, escriu el seu nom exacte:
              </Text>
              <Code block mt={4}>{preview.danceName}</Code>
            </Alert>

            <TextInput
              label="Nom del ball"
              placeholder={preview.danceName}
              value={confirmName}
              onChange={(e) => {
                setConfirmName(e.currentTarget.value);
                if (confirmError) setConfirmError(null);
              }}
              error={confirmError}
              autoFocus
            />

            <Group justify="space-between">
              <Button variant="subtle" onClick={() => setStep(1)}>
                Tornar
              </Button>
              <Button
                color="red"
                leftSection={<IconTrash size={16} />}
                disabled={confirmName.trim() !== preview.danceName}
                loading={deleteMutation.isPending}
                onClick={() => deleteMutation.mutate()}
              >
                Eliminar permanentment
              </Button>
            </Group>
          </>
        )}
      </Stack>

      <Text size="xs" c="dimmed" mt="md">
        Ball #{danceId} — {displayName}
      </Text>
    </Modal>
  );
}

function CascadeSummaryView({ preview }: { preview: DeleteDancePreview }) {
  const c = preview.willCascade;
  return (
    <Stack gap={4}>
      <SummaryRow label="Associacions amb cançons" value={c.danceSongAssociations} />
      <SummaryRow label="Associacions amb coreògrafs" value={c.choreographerAssociations} />
      <SummaryRow label="Enllaços (YouTube, stepsheet, etc.)" value={c.links} />
      <SummaryRow label="Fitxa tècnica (LineDanceSpec)" value={c.hasLineDanceSpec ? "Sí" : "No"} />
      <SummaryRow
        label="Vídeos d'imports YouTube (es desvinculen)"
        value={c.channelVideosToOrphan}
      />
      <SummaryRow
        label="Propostes que perdran el vincle"
        value={c.danceSuggestionsToOrphan}
      />
      <SummaryRow
        label="Enllaços orfes que es netejaran"
        value={c.orphanLinksToCleanup}
      />
    </Stack>
  );
}

function SummaryRow({ label, value }: { label: string; value: number | string }) {
  return (
    <Group justify="space-between">
      <Text size="sm">{label}</Text>
      <Text size="sm" fw={600}>{value}</Text>
    </Group>
  );
}
