import { Box, Button, ColorPicker, Group, Modal, Stack, TextInput, Tooltip } from "@mantine/core";
import { IconPalette } from "@tabler/icons-react";
import { useEffect, useState } from "react";
import { CARD_COLORS, colorBorder, colorSwatch } from "./colors";

interface Props {
  value: string;
  onChange: (color: string) => void;
  options?: { value: string; label: string }[];
  // Si se da, el "+" delega en el padre (recomendado dentro de Menu/Popover).
  // Sin esto, ColorPickerGrid abre Modal interno (puede colisionar con cierres del padre).
  onOpenCustom?: () => void;
}

const SWATCH = 26;

export function ColorPickerGrid({ value, onChange, options = CARD_COLORS, onOpenCustom }: Props) {
  const [pickerOpen, setPickerOpen] = useState(false);
  const [custom, setCustom] = useState(value && value.startsWith("#") ? value : "#888888");
  const isCustomActive = !!value && value.startsWith("#") && !options.some((o) => o.value === value);

  return (
    <>
      <Group gap={6} maw={280}>
        {options.map((c) => {
          const selected = value === c.value;
          return (
            <Tooltip key={c.value || "default"} label={c.label} withArrow>
              <Box
                role="button"
                onClick={(e) => { e.stopPropagation(); onChange(c.value); }}
                aria-label={c.label}
                style={{
                  width: SWATCH,
                  height: SWATCH,
                  borderRadius: "50%",
                  background: colorSwatch(c.value),
                  border: `2px solid ${selected ? "var(--mantine-color-white)" : colorBorder(c.value)}`,
                  boxShadow: selected ? "0 0 0 2px var(--mantine-color-blue-5)" : undefined,
                  cursor: "pointer",
                  flexShrink: 0,
                  transition: "transform .1s",
                }}
              />
            </Tooltip>
          );
        })}
        <Tooltip label="Color personalizado" withArrow>
          <Box
            role="button"
            onMouseDown={(e) => { e.stopPropagation(); }}
            onClick={(e) => {
              e.stopPropagation();
              if (onOpenCustom) onOpenCustom();
              else setPickerOpen(true);
            }}
            aria-label="Color personalizado"
            style={{
              width: SWATCH,
              height: SWATCH,
              borderRadius: "50%",
              background: isCustomActive ? custom : "transparent",
              border: `2px dashed ${isCustomActive ? custom : "var(--mantine-color-gray-5)"}`,
              boxShadow: isCustomActive ? "0 0 0 2px var(--mantine-color-blue-5)" : undefined,
              cursor: "pointer",
              flexShrink: 0,
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
              color: "var(--mantine-color-gray-3)",
            }}
          >
            <IconPalette size={14} />
          </Box>
        </Tooltip>
      </Group>

      {!onOpenCustom && (
        <CustomColorModal
          opened={pickerOpen}
          onClose={() => setPickerOpen(false)}
          value={custom}
          onAccept={(v) => { setCustom(v); onChange(v); }}
        />
      )}
    </>
  );
}

interface ModalProps {
  opened: boolean;
  onClose: () => void;
  value: string;
  // Disparado solo cuando el usuario pulsa "Aceptar". Mientras arrastra el picker
  // el cambio queda local — no fuga al resto de la app.
  onAccept: (v: string) => void;
}

const HEX_RE = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;

export function CustomColorModal({ opened, onClose, value, onAccept }: ModalProps) {
  const [local, setLocal] = useState(value || "#888888");
  const [hexInput, setHexInput] = useState(value || "#888888");

  // Reset state cuando abre con un value nuevo (cada vez que se abre).
  useEffect(() => {
    if (opened) {
      const v = value && HEX_RE.test(value) ? value : "#888888";
      setLocal(v);
      setHexInput(v);
    }
  }, [opened, value]);

  const onHexChange = (v: string) => {
    let s = v.trim();
    if (s && !s.startsWith("#")) s = "#" + s;
    setHexInput(s);
    if (HEX_RE.test(s)) setLocal(s);
  };
  const onPickerChange = (v: string) => {
    setLocal(v);
    setHexInput(v);
  };
  const accept = () => { onAccept(local); onClose(); };

  return (
    <Modal
      opened={opened}
      onClose={onClose}
      title="Color personalizado"
      size="auto"
      centered
      withinPortal
      zIndex={2000}
      closeOnClickOutside
      closeOnEscape={false}
      trapFocus={false}
      withCloseButton={false}
    >
      <Stack
        gap="sm"
        onMouseDown={(e) => e.stopPropagation()}
        onPointerDown={(e) => e.stopPropagation()}
        onClick={(e) => e.stopPropagation()}
      >
        <ColorPicker
          value={local}
          onChange={onPickerChange}
          format="hex"
          swatches={["#1c7ed6", "#15aabf", "#12b886", "#37b24d", "#82c91e", "#fab005", "#fd7e14", "#fa5252", "#e64980", "#be4bdb", "#7950f2", "#4c6ef5", "#868e96", "#212529"]}
          fullWidth
        />
        <Group align="end" gap="xs">
          <TextInput
            label="Hex"
            value={hexInput}
            onChange={(e) => onHexChange(e.currentTarget.value)}
            error={hexInput && !HEX_RE.test(hexInput) ? "Hex invalido" : undefined}
            size="xs"
            style={{ flex: 1 }}
            placeholder="#rrggbb"
          />
          <Box
            style={{
              width: 32,
              height: 32,
              borderRadius: 4,
              background: HEX_RE.test(hexInput) ? hexInput : "transparent",
              border: "1px solid var(--mantine-color-dark-4)",
            }}
          />
        </Group>
        <Group justify="flex-end" gap="xs">
          <Button variant="default" size="xs" onClick={onClose}>Cancelar</Button>
          <Button size="xs" onClick={accept} disabled={!HEX_RE.test(local)}>Aceptar</Button>
        </Group>
      </Stack>
    </Modal>
  );
}
