import {
  ActionIcon,
  Anchor,
  Badge,
  Box,
  Button,
  FileButton,
  Group,
  Image,
  Loader,
  Paper,
  Stack,
  Text,
  Tooltip,
} from "@mantine/core";
import { notifications } from "@mantine/notifications";
import {
  IconDownload,
  IconFile,
  IconFileSpreadsheet,
  IconFileText,
  IconFileTypePdf,
  IconPhoto,
  IconTrash,
  IconUpload,
} from "@tabler/icons-react";
import { useCallback, useEffect, useState } from "react";
import * as api from "../api";
import type { CardFile } from "../types";

interface Props {
  cardId: string;
  refreshKey?: number;
}

function formatSize(bytes: number): string {
  if (bytes < 1024) return `${bytes} B`;
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
  return `${(bytes / 1024 / 1024).toFixed(2)} MB`;
}

function isImage(mime: string): boolean {
  return mime.startsWith("image/");
}

function fileIcon(mime: string, size = 18) {
  const m = mime.toLowerCase();
  if (m.startsWith("image/")) return <IconPhoto size={size} />;
  if (m === "application/pdf") return <IconFileTypePdf size={size} />;
  if (
    m.includes("spreadsheet") ||
    m.includes("excel") ||
    m === "text/csv" ||
    m === "application/vnd.ms-excel"
  ) {
    return <IconFileSpreadsheet size={size} />;
  }
  if (m.startsWith("text/")) return <IconFileText size={size} />;
  return <IconFile size={size} />;
}

function sourceBadge(s: CardFile["source"]) {
  if (s === "description") return { color: "blue", label: "descripcion" };
  if (s === "chat") return { color: "teal", label: "chat" };
  return { color: "gray", label: "subido" };
}

export function CardFilesPanel({ cardId, refreshKey }: Props) {
  const [files, setFiles] = useState<CardFile[]>([]);
  const [loading, setLoading] = useState(true);
  const [uploading, setUploading] = useState(false);

  const reload = useCallback(async () => {
    try {
      const list = await api.listCardFiles(cardId);
      setFiles(list);
    } catch (e) {
      notifications.show({ color: "red", message: (e as Error).message });
    } finally {
      setLoading(false);
    }
  }, [cardId]);

  useEffect(() => {
    reload();
  }, [reload, refreshKey]);

  const onUpload = async (file: File | null) => {
    if (!file) return;
    setUploading(true);
    try {
      const cf = await api.uploadCardFile(cardId, file, "upload");
      setFiles((prev) => [...prev, cf]);
    } catch (e) {
      notifications.show({ color: "red", message: (e as Error).message });
    } finally {
      setUploading(false);
    }
  };

  const onDelete = async (id: string) => {
    if (!window.confirm("¿Borrar este archivo?")) return;
    try {
      await api.deleteCardFile(id);
      setFiles((prev) => prev.filter((f) => f.id !== id));
    } catch (e) {
      notifications.show({ color: "red", message: (e as Error).message });
    }
  };

  return (
    <Stack gap="xs" p={4}>
      <Group justify="space-between">
        <Text size="xs" c="dimmed">
          {files.length} archivo{files.length === 1 ? "" : "s"}
        </Text>
        <FileButton onChange={onUpload} disabled={uploading}>
          {(props) => (
            <Button
              size="xs"
              variant="light"
              leftSection={<IconUpload size={14} />}
              loading={uploading}
              {...props}
            >
              Subir
            </Button>
          )}
        </FileButton>
      </Group>

      {loading ? (
        <Group justify="center" p="md">
          <Loader size="sm" />
        </Group>
      ) : files.length === 0 ? (
        <Stack gap="xs" p="md" align="center" justify="center" style={{ minHeight: 160 }}>
          <Text size="sm" c="dimmed">
            Sin archivos
          </Text>
          <Text size="xs" c="dimmed" ta="center">
            Sube archivos con el boton, arrastra al chat o a la descripcion.
          </Text>
        </Stack>
      ) : (
        <Stack gap={6}>
          {files.map((f) => {
            const badge = sourceBadge(f.source);
            return (
              <Paper key={f.id} withBorder p="xs" radius="sm">
                <Group gap="xs" wrap="nowrap" align="flex-start">
                  {isImage(f.mime) ? (
                    <Anchor href={f.url} target="_blank" rel="noopener noreferrer">
                      <Image
                        src={f.url}
                        alt={f.filename}
                        w={64}
                        h={64}
                        fit="cover"
                        radius="sm"
                      />
                    </Anchor>
                  ) : (
                    <Box
                      style={{
                        width: 64,
                        height: 64,
                        display: "flex",
                        alignItems: "center",
                        justifyContent: "center",
                        background: "var(--mantine-color-gray-1)",
                        borderRadius: 4,
                      }}
                    >
                      {fileIcon(f.mime, 28)}
                    </Box>
                  )}
                  <Box style={{ flex: 1, minWidth: 0 }}>
                    <Anchor href={f.url} target="_blank" rel="noopener noreferrer" size="sm" style={{ wordBreak: "break-all" }}>
                      {f.filename}
                    </Anchor>
                    <Group gap={6} mt={4}>
                      <Badge size="xs" variant="light" color={badge.color}>
                        {badge.label}
                      </Badge>
                      <Text size="xs" c="dimmed">{formatSize(f.size)}</Text>
                      <Text size="xs" c="dimmed">{f.mime || "?"}</Text>
                    </Group>
                  </Box>
                  <Group gap={4} wrap="nowrap">
                    <Tooltip label="Descargar" withArrow>
                      <ActionIcon
                        component="a"
                        href={f.url}
                        download={f.filename}
                        variant="subtle"
                        size="sm"
                        aria-label="Descargar"
                      >
                        <IconDownload size={14} />
                      </ActionIcon>
                    </Tooltip>
                    <Tooltip label="Borrar" withArrow>
                      <ActionIcon
                        variant="subtle"
                        color="red"
                        size="sm"
                        onClick={() => onDelete(f.id)}
                        aria-label="Borrar"
                      >
                        <IconTrash size={14} />
                      </ActionIcon>
                    </Tooltip>
                  </Group>
                </Group>
              </Paper>
            );
          })}
        </Stack>
      )}
    </Stack>
  );
}
