import {
  Popover,
  PopoverButton,
  PopoverPanel,
  Transition,
} from '@headlessui/react';
import { File, Paperclip, Plus, Trash } from 'lucide-react';
import { Fragment, useRef, useState } from 'react';
import { useChat } from '@/lib/hooks/useChat';
import { AnimatePresence } from 'motion/react';
import { motion } from 'framer-motion';

const UPLOAD_TIMEOUT_MS = 300000;

const AttachSmall = () => {
  const { files, setFiles, setFileIds, fileIds, embeddingModelProvider } = useChat();

  if (!embeddingModelProvider?.providerId) return null;

  const [loading, setLoading] = useState(false);
  const [uploadError, setUploadError] = useState<string | null>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const abortRef = useRef<AbortController | null>(null);

  const handleChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const fileList = e.target.files;
    if (!fileList?.length) return;

    const controller = new AbortController();
    abortRef.current = controller;
    const timeoutId = setTimeout(() => controller.abort(), UPLOAD_TIMEOUT_MS);
    setLoading(true);
    setUploadError(null);

    const data = new FormData();
    for (let i = 0; i < fileList.length; i++) {
      data.append('files', fileList[i]);
    }
    const provider = localStorage.getItem('embeddingModelProviderId');
    const model = localStorage.getItem('embeddingModelKey');
    data.append('embedding_model_provider_id', provider!);
    data.append('embedding_model_key', model!);

    try {
      const res = await fetch(`/api/uploads`, {
        method: 'POST',
        body: data,
        signal: controller.signal,
      });
      const resData = await res.json();

      if (!res.ok) throw new Error(resData.error ?? 'Upload failed');

      setFiles([...files, ...(resData.files ?? [])]);
      setFileIds([...fileIds, ...(resData.files ?? []).map((f: { fileId: string }) => f.fileId)]);
    } catch (err) {
      const msg = err instanceof Error ? err.message : 'Upload failed';
      const isAbort = (err as Error)?.name === 'AbortError';
      setUploadError(isAbort ? 'Cancelled' : msg);
    } finally {
      clearTimeout(timeoutId);
      setLoading(false);
      abortRef.current = null;
      e.target.value = '';
    }
  };

  return loading ? (
    <div className="flex flex-row items-center space-x-2 p-1 text-xs text-[#EA580C]">
      Uploading…
    </div>
  ) : uploadError ? (
    <div className="p-1 text-xs text-red-500">
      {uploadError}
      <button type="button" onClick={() => setUploadError(null)} className="ml-1 underline">
        Dismiss
      </button>
    </div>
  ) : files.length > 0 ? (
    <Popover className="max-w-[15rem] md:max-w-md lg:max-w-lg">
      {({ open }) => (
        <>
          <PopoverButton
            type="button"
            className="flex flex-row items-center justify-between space-x-1 p-1 text-black/50 dark:text-white/50 rounded-xl hover:bg-light-secondary dark:hover:bg-dark-secondary active:scale-95 transition duration-200 hover:text-black dark:hover:text-white"
          >
            <File size={20} className="text-[#EA580C]" />
          </PopoverButton>
          <AnimatePresence>
            {open && (
              <PopoverPanel
                className="absolute z-10 w-64 md:w-[350px] right-0 bottom-full mb-2"
                static
              >
                <motion.div
                  initial={{ opacity: 0, scale: 0.9 }}
                  animate={{ opacity: 1, scale: 1 }}
                  exit={{ opacity: 0, scale: 0.9 }}
                  transition={{ duration: 0.1, ease: 'easeOut' }}
                  className="origin-bottom-right bg-light-primary dark:bg-dark-primary border rounded-md border-light-200 dark:border-dark-200 w-full max-h-[200px] md:max-h-none overflow-y-auto flex flex-col"
                >
                  <div className="flex flex-row items-center justify-between px-3 py-2">
                    <h4 className="text-black/70 dark:text-white/70 font-medium text-sm">
                      Attached files
                    </h4>
                    <div className="flex flex-row items-center space-x-4">
                      <button
                        type="button"
                        onClick={() => fileInputRef.current?.click()}
                        className="flex flex-row items-center space-x-1 text-black/70 dark:text-white/70 hover:text-black hover:dark:text-white transition duration-200"
                      >
                        <input
                          type="file"
                          onChange={handleChange}
                          ref={fileInputRef}
                          accept=".pdf,.docx,.txt"
                          multiple
                          hidden
                        />
                        <Plus size={16} />
                        <p className="text-xs">Add</p>
                      </button>
                      <button
                        onClick={() => {
                          setFiles([]);
                          setFileIds([]);
                        }}
                        className="flex flex-row items-center space-x-1 text-black/70 dark:text-white/70 hover:text-black hover:dark:text-white transition duration-200"
                      >
                        <Trash size={13} />
                        <p className="text-xs">Clear</p>
                      </button>
                    </div>
                  </div>
                  <div className="h-[0.5px] mx-2 bg-white/10" />
                  <div className="flex flex-col items-center">
                    {files.map((file, i) => (
                      <div
                        key={i}
                        className="flex flex-row items-center justify-start w-full space-x-3 p-3"
                      >
                        <div className="bg-light-100 dark:bg-dark-100 flex items-center justify-center w-9 h-9 rounded-md">
                          <File
                            size={16}
                            className="text-black/70 dark:text-white/70"
                          />
                        </div>
                        <p className="text-black/70 dark:text-white/70 text-xs">
                          {file.fileName.length > 25
                            ? file.fileName
                                .replace(/\.\w+$/, '')
                                .substring(0, 25) +
                              '...' +
                              file.fileExtension
                            : file.fileName}
                        </p>
                      </div>
                    ))}
                  </div>
                </motion.div>
              </PopoverPanel>
            )}
          </AnimatePresence>
        </>
      )}
    </Popover>
  ) : (
    <button
      type="button"
      onClick={() => fileInputRef.current?.click()}
      className="flex flex-row items-center space-x-1 text-black/50 dark:text-white/50 rounded-xl hover:bg-light-secondary dark:hover:bg-dark-secondary transition duration-200 hover:text-black dark:hover:text-white p-1"
    >
      <input
        type="file"
        onChange={handleChange}
        ref={fileInputRef}
        accept=".pdf,.docx,.txt"
        multiple
        hidden
      />
      <Paperclip size={16} />
    </button>
  );
};

export default AttachSmall;
