import {
  ActionIcon,
  Alert,
  Anchor,
  Box,
  Group,
  Loader,
  Stack,
  Text,
  Tooltip,
} from "@mantine/core";
import { IconDownload, IconFileSpreadsheet, IconUpload, IconX } from "@tabler/icons-react";
import { useRef, useState } from "react";
import { uploadFiles } from "@/lib/features/chatbot/agent/action";

type FileUploadFieldProps = {
  value: string[];
  onChange: (urls: string[]) => void;
  onUploadingChange?: (uploading: boolean) => void;
  label?: string;
  description?: string;
  error?: React.ReactNode;
};

const ACCEPTED_EXTENSIONS = [".csv", ".xls", ".xlsx"];
const ACCEPTED_MIME = [
  "text/csv",
  "application/vnd.ms-excel",
  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
];

function getFileName(url: string): string {
  try {
    const decoded = decodeURIComponent(url);
    const parts = decoded.split("/");
    const last = parts[parts.length - 1] ?? url;
    // Strip the uuid prefix (32 hex chars + underscore)
    return last.replace(/^[0-9a-f]{32}_/, "");
  } catch {
    return url;
  }
}

export default function FileUploadField({ value, onChange, onUploadingChange, label, description, error }: FileUploadFieldProps) {
  const inputRef = useRef<HTMLInputElement>(null);
  const [uploading, setUploading] = useState(false);
  const [uploadError, setUploadError] = useState<string | null>(null);
  const [dragging, setDragging] = useState(false);

  const setUploadingState = (v: boolean) => {
    setUploading(v);
    onUploadingChange?.(v);
  };

  const handleFiles = async (files: FileList | null) => {
    if (!files || files.length === 0) return;

    const fileArr = Array.from(files);
    const invalid = fileArr.filter((f) => {
      const ext = "." + f.name.split(".").pop()?.toLowerCase();
      return !ACCEPTED_EXTENSIONS.includes(ext);
    });
    if (invalid.length > 0) {
      setUploadError(`Unsupported file(s): ${invalid.map((f) => f.name).join(", ")}. Allowed: .csv, .xls, .xlsx`);
      return;
    }

    setUploadError(null);
    setUploadingState(true);
    try {
      const result = await uploadFiles(fileArr);
      if (result.success && result.urls?.length) {
        onChange([...value, ...result.urls]);
      } else {
        setUploadError("Upload returned no URLs. Please try again.");
      }
    } catch (e: any) {
      setUploadError(e?.message ?? "Upload failed.");
    } finally {
      setUploadingState(false);
      if (inputRef.current) inputRef.current.value = "";
    }
  };

  const handleRemove = (url: string) => {
    onChange(value.filter((u) => u !== url));
  };

  const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    setDragging(false);
    handleFiles(e.dataTransfer.files);
  };

  return (
    <Stack gap="xs">
      {label && (
        <Text size="sm" fw={500}>
          {label}
        </Text>
      )}
      {description && (
        <Text size="xs" c="dimmed" mt={-4}>
          {description}
        </Text>
      )}

      {/* Drop zone */}
      <Box
        onDragOver={(e) => { e.preventDefault(); setDragging(true); }}
        onDragLeave={() => setDragging(false)}
        onDrop={handleDrop}
        onClick={() => !uploading && inputRef.current?.click()}
        style={{
          border: `2px dashed ${dragging ? "var(--mantine-color-blue-5)" : "var(--mantine-color-gray-4)"}`,
          borderRadius: 8,
          padding: "20px 16px",
          textAlign: "center",
          cursor: uploading ? "default" : "pointer",
          background: dragging ? "var(--mantine-color-blue-0)" : "var(--mantine-color-gray-0)",
          transition: "border-color 0.15s, background 0.15s",
        }}
      >
        <input
          ref={inputRef}
          type="file"
          accept={ACCEPTED_MIME.join(",")}
          multiple
          style={{ display: "none" }}
          onChange={(e) => handleFiles(e.currentTarget.files)}
        />
        {uploading ? (
          <Group justify="center" gap="xs">
            <Loader size="xs" />
            <Text size="sm" c="dimmed">Uploading…</Text>
          </Group>
        ) : (
          <Group justify="center" gap="xs">
            <IconUpload size={18} color="var(--mantine-color-blue-6)" />
            <Text size="sm" c="blue">
              Click or drag &amp; drop files here
            </Text>
            <Text size="xs" c="dimmed">
              (.csv, .xls, .xlsx — multiple allowed)
            </Text>
          </Group>
        )}
      </Box>

      {/* Uploaded files list */}
      {value.length > 0 && (
        <Stack gap={4}>
          {value.map((url) => (
            <Group key={url} gap="xs" align="center" p={6} style={{ border: "1px solid var(--mantine-color-gray-3)", borderRadius: 6 }}>
              <IconFileSpreadsheet size={16} color="var(--mantine-color-green-6)" />
              <Text size="xs" style={{ flex: 1, wordBreak: "break-all" }}>
                {getFileName(url)}
              </Text>
              <Tooltip label="Download">
                <ActionIcon
                  size="xs"
                  variant="subtle"
                  color="blue"
                  component="a"
                  href={url}
                  download={getFileName(url)}
                  target="_blank"
                  rel="noopener noreferrer"
                >
                  <IconDownload size={12} />
                </ActionIcon>
              </Tooltip>
              <Tooltip label="Remove">
                <ActionIcon size="xs" variant="subtle" color="red" onClick={() => handleRemove(url)}>
                  <IconX size={12} />
                </ActionIcon>
              </Tooltip>
            </Group>
          ))}
        </Stack>
      )}

      {(uploadError || error) && (
        <Alert color="red" icon={<IconX size={14} />} p="xs">
          <Text size="xs">{uploadError ?? error}</Text>
        </Alert>
      )}
    </Stack>
  );
}
