import { Anchor, Box, Group, HoverCard, Stack, Text } from "@mantine/core";
import { IconBrandJira, IconAlertCircle } from "@tabler/icons-react";
import { CSSProperties, useEffect, useState } from "react";
import * as api from "../api";
import type { CardJiraSyncState } from "../api";
import { formatDateTimeShort } from "./format";

// Pull state every POLL_MS so the indicator catches up with async dispatcher
// pushes without needing SSE. 10s is a reasonable balance: short enough that a
// drag-to-Jira shows green within one tick, long enough that the polling is
// not a noticeable load.
const POLL_MS = 10000;

type Tone = "gray" | "yellow" | "green" | "red";

function tone(state: CardJiraSyncState): Tone {
  if (state.inflight) return "yellow";
  if (state.last_error) return "red";
  if (state.jira_key) return "green";
  return "gray";
}

const TONE_COLOR: Record<Tone, string> = {
  gray: "var(--mantine-color-gray-5)",
  yellow: "var(--mantine-color-yellow-5)",
  green: "var(--mantine-color-green-5)",
  red: "var(--mantine-color-red-6)",
};

const TONE_LABEL: Record<Tone, string> = {
  gray: "Sin sincronizar con Jira",
  yellow: "Sincronizando...",
  green: "Sincronizada con Jira",
  red: "Error de sincronizacion",
};

interface Props {
  cardId: string;
  // Pollen-down so the parent can refresh when needed (e.g. after a move
  // animation finishes) without waiting for the next tick.
  refreshTick?: number;
}

export function JiraSyncIndicator({ cardId, refreshTick }: Props) {
  const [state, setState] = useState<CardJiraSyncState | null>(null);
  const [err, setErr] = useState<string | null>(null);

  useEffect(() => {
    let cancelled = false;
    const load = async () => {
      try {
        const s = await api.getCardJiraSync(cardId);
        if (!cancelled) {
          setState(s);
          setErr(null);
        }
      } catch (e) {
        if (!cancelled) setErr((e as Error).message);
      }
    };
    load();
    const t = setInterval(load, POLL_MS);
    return () => {
      cancelled = true;
      clearInterval(t);
    };
  }, [cardId, refreshTick]);

  if (err && !state) {
    return (
      <Box title={err} style={dotStyle("var(--mantine-color-gray-3)")} aria-label="Jira sync state unavailable" />
    );
  }
  if (!state) {
    // Initial render — fade in a placeholder dot so the layout does not shift
    // when the fetch resolves.
    return <Box style={dotStyle("var(--mantine-color-gray-2)")} aria-label="Cargando estado Jira" />;
  }
  const t = tone(state);
  return (
    <HoverCard width={300} shadow="md" openDelay={150} closeDelay={120} withinPortal>
      <HoverCard.Target>
        <Box
          role="status"
          aria-label={TONE_LABEL[t]}
          onClick={(e) => e.stopPropagation()}
          onPointerDown={(e) => e.stopPropagation()}
          style={dotStyle(TONE_COLOR[t])}
        />
      </HoverCard.Target>
      <HoverCard.Dropdown onClick={(e) => e.stopPropagation()}>
        <Stack gap={6}>
          <Group gap={6} wrap="nowrap" justify="space-between">
            <Group gap={6} wrap="nowrap">
              <IconBrandJira size={14} />
              <Text size="sm" fw={600}>{TONE_LABEL[t]}</Text>
            </Group>
            {state.issue_url && (
              <Anchor
                size="xs"
                href={state.issue_url}
                target="_blank"
                rel="noopener noreferrer"
                onClick={(e) => e.stopPropagation()}
              >
                Abrir en Jira
              </Anchor>
            )}
          </Group>
          {state.jira_key && (
            <Text size="xs">
              <Text component="span" c="dimmed">Issue:</Text>{" "}
              <Text component="span" fw={600}>{state.jira_key}</Text>
            </Text>
          )}
          {state.last_status && (
            <Text size="xs">
              <Text component="span" c="dimmed">Status:</Text>{" "}
              <Text component="span">{state.last_status}</Text>
            </Text>
          )}
          {state.last_sync_at && (
            <Text size="xs">
              <Text component="span" c="dimmed">Ultimo sync:</Text>{" "}
              <Text component="span">{formatDateTimeShort(state.last_sync_at)}</Text>
            </Text>
          )}
          {state.last_error && (
            <Group gap={6} wrap="nowrap" align="flex-start">
              <IconAlertCircle size={14} color="var(--mantine-color-red-6)" />
              <Text size="xs" c="red" style={{ wordBreak: "break-word" }}>{state.last_error}</Text>
            </Group>
          )}
          {!state.jira_key && (
            <Text size="xs" c="dimmed">
              La card todavia no se ha empujado a Jira. Editala o muevela para
              disparar el sync, o usa la opcion "Importar de Jira" si ya existe
              alli.
            </Text>
          )}
        </Stack>
      </HoverCard.Dropdown>
    </HoverCard>
  );
}

function dotStyle(color: string): CSSProperties {
  return {
    width: 10,
    height: 10,
    borderRadius: "50%",
    background: color,
    cursor: "default",
    boxShadow: "0 0 0 2px var(--mantine-color-body)",
    transition: "background 120ms ease",
  };
}
