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

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

/**
 * Two-step delete modal for songs. Mirrors {@link DeleteDanceModal} but for
 * songs (no archive option — songs don't have a listing_status concept yet).
 *
 * Uses the project-wide hard-delete pattern (see ADR-004 and patterns.md).
 */
export function DeleteSongModal({
  songId,
  songTitle,
  songArtist,
  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<DeleteSongPreview>({
    queryKey: ["song-delete-preview", songId],
    queryFn: () => fetchDeleteSongPreview(songId as number),
    enabled: opened && songId !== null,
    staleTime: 0,
  });

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

  const deleteMutation = useMutation({
    mutationFn: () =>
      deleteSong(songId as number, confirmName.trim()),
    onSuccess: () => {
      notifications.show({
        title: "Cançó eliminada",
        message: "La cançó s'ha eliminat permanentment.",
        color: "red",
      });
      queryClient.invalidateQueries({ queryKey: ["song"] });
      queryClient.invalidateQueries({ queryKey: ["songs"] });
      onSuccess?.();
      onClose();
    },
    onError: (error) => {
      let message = "No s'ha pogut eliminar la cançó.";
      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 expectedConfirmation = preview
    ? `${preview.songTitle} — ${preview.songArtist}`
    : "";
  const displayName = preview
    ? `${preview.songTitle} — ${preview.songArtist}`
    : songTitle && songArtist
      ? `${songTitle} — ${songArtist}`
      : `#${songId}`;
  const hasBlockers = preview && preview.blockers.length > 0;

  return (
    <Modal opened={opened} onClose={onClose} title="Eliminar cançó" 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.songTitle}» — {preview.songArtist}</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}</List.Item>
                  ))}
                </List>
              </Alert>
            ) : (
              <>
                <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>
              {!hasBlockers && (
                <Button
                  color="red"
                  leftSection={<IconTrash size={16} />}
                  onClick={() => setStep(2)}
                >
                  Continuar amb l'esborrat
                </Button>
              )}
            </Group>
          </>
        )}

        {preview && step === 2 && !hasBlockers && (
          <>
            <Alert color="red" icon={<IconAlertTriangle size={16} />}>
              <Text fw={600}>Confirmació final</Text>
              <Text size="sm">
                Per eliminar permanentment la cançó, escriu el text exacte
                (títol, espai, em-dash, espai, artista):
              </Text>
              <Code block mt={4}>{expectedConfirmation}</Code>
            </Alert>

            <TextInput
              label="Confirmació"
              placeholder={expectedConfirmation}
              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() !== expectedConfirmation}
                loading={deleteMutation.isPending}
                onClick={() => deleteMutation.mutate()}
              >
                Eliminar permanentment
              </Button>
            </Group>
          </>
        )}
      </Stack>

      <Text size="xs" c="dimmed" mt="md">
        Cançó #{songId} — {displayName}
      </Text>
    </Modal>
  );
}

function CascadeSummaryView({ preview }: { preview: DeleteSongPreview }) {
  const c = preview.willCascade;
  return (
    <Stack gap={4}>
      <SummaryRow label="Enllaços (Spotify, YouTube, etc.)" value={c.links} />
      <SummaryRow
        label="Setlists d'events que perdran la cançó"
        value={c.eventSetlistItemsToOrphan}
      />
      <SummaryRow
        label="Propostes de ball que s'eliminaran (CASCADE)"
        value={c.danceSuggestionsToCascadeDelete}
      />
    </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>
  );
}
