'use client';

import { useState, useRef, useEffect } from 'react';
import {
  File, FileText, FileImage, FileVideo, FileArchive,
  Download, Pencil, Trash2, MoreVertical, Loader2,
} from 'lucide-react';
import type { FileRecord } from '@/lib/types';

function fileIcon(mime: string) {
  if (!mime) return File;
  if (mime.startsWith('image/'))  return FileImage;
  if (mime.startsWith('video/'))  return FileVideo;
  if (mime.includes('pdf') || mime.includes('word') || mime.includes('text')) return FileText;
  if (mime.includes('zip') || mime.includes('tar') || mime.includes('gz'))   return FileArchive;
  return File;
}

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

function formatDate(d: string) {
  return new Date(d).toLocaleDateString('en-US', { day: 'numeric', month: 'short', year: 'numeric' });
}

interface Props {
  files:       FileRecord[];
  onRename:    (file: FileRecord) => void;
  onDelete:    (file: FileRecord) => void;
  showFolder?: boolean;
  folderName?: string;
}

function ActionMenu({ file, onRename, onDelete }: {
  file: FileRecord;
  onRename: (file: FileRecord) => void;
  onDelete: (file: FileRecord) => void;
}) {
  const [open, setOpen] = useState(false);
  const btnRef = useRef<HTMLButtonElement>(null);
  const [pos, setPos] = useState({ top: 0, left: 0 });

  useEffect(() => {
    if (open && btnRef.current) {
      const rect = btnRef.current.getBoundingClientRect();
      setPos({ top: rect.bottom + 4, left: rect.right - 144 });
    }
  }, [open]);

  return (
    <>
      <button
        ref={btnRef}
        onClick={() => setOpen(!open)}
        className="rounded-lg p-1.5 text-slate-400 hover:bg-slate-100 transition-colors"
      >
        <MoreVertical className="h-4 w-4" />
      </button>
      {open && (
        <>
          <div className="fixed inset-0 z-40" onClick={() => setOpen(false)} />
          <div
            className="fixed z-50 w-36 rounded-lg border border-slate-200 bg-white py-1 shadow-lg"
            style={{ top: pos.top, left: pos.left }}
          >
            <button
              onClick={() => { setOpen(false); onRename(file); }}
              className="flex w-full items-center gap-2 px-3 py-2 text-sm text-slate-700 hover:bg-slate-50"
            >
              <Pencil className="h-3.5 w-3.5" /> Rename
            </button>
            <button
              onClick={() => { setOpen(false); onDelete(file); }}
              className="flex w-full items-center gap-2 px-3 py-2 text-sm text-red-600 hover:bg-red-50"
            >
              <Trash2 className="h-3.5 w-3.5" /> Delete
            </button>
          </div>
        </>
      )}
    </>
  );
}

export default function FileList({ files, onRename, onDelete, showFolder }: Props) {
  const [downloading, setDownloading] = useState<number | null>(null);

  async function download(file: FileRecord) {
    setDownloading(file.id);
    try {
      const res  = await fetch(`/api/files/${file.id}/download`);
      const json = await res.json();
      if (json.url) {
        const a   = document.createElement('a');
        a.href    = json.url;
        a.download = file.name;
        a.click();
      }
    } finally {
      setDownloading(null);
    }
  }

  if (files.length === 0) {
    return (
      <div className="flex flex-col items-center justify-center py-16 text-slate-400">
        <File className="mb-2 h-10 w-10 opacity-30" />
        <p className="text-sm">No files here yet</p>
      </div>
    );
  }

  return (
    <div className="overflow-x-auto">
      <table className="w-full text-sm">
        <thead>
          <tr className="border-b border-slate-200 text-left text-xs font-semibold uppercase tracking-wider text-slate-400">
            <th className="pb-2 pr-4">Name</th>
            {showFolder && <th className="pb-2 pr-4 hidden sm:table-cell">Folder</th>}
            <th className="pb-2 pr-4 hidden md:table-cell">Size</th>
            <th className="pb-2 pr-4 hidden lg:table-cell">Uploaded</th>
            <th className="pb-2 text-right">Actions</th>
          </tr>
        </thead>
        <tbody className="divide-y divide-slate-100">
          {files.map((file) => {
            const Icon = fileIcon(file.mime_type);
            return (
              <tr key={file.id} className="group hover:bg-slate-50">
                <td className="py-2.5 pr-4">
                  <div className="flex items-center gap-2">
                    <Icon className="h-4 w-4 flex-shrink-0 text-blue-500" />
                    <span className="truncate font-medium text-slate-700 max-w-[180px] sm:max-w-xs">
                      {file.name}
                    </span>
                  </div>
                </td>
                {showFolder && (
                  <td className="py-2.5 pr-4 text-slate-400 hidden sm:table-cell">
                    {file.folder_name}
                  </td>
                )}
                <td className="py-2.5 pr-4 text-slate-400 hidden md:table-cell">
                  {formatSize(file.size)}
                </td>
                <td className="py-2.5 pr-4 text-slate-400 hidden lg:table-cell">
                  {formatDate(file.created_at)}
                </td>
                <td className="py-2.5 text-right">
                  <div className="flex items-center justify-end gap-1">
                    <button
                      onClick={() => download(file)}
                      disabled={downloading === file.id}
                      className="rounded-lg p-1.5 text-slate-400 hover:bg-blue-50 hover:text-blue-600 transition-colors"
                      title="Download"
                    >
                      {downloading === file.id
                        ? <Loader2 className="h-4 w-4 animate-spin" />
                        : <Download className="h-4 w-4" />}
                    </button>
                    <ActionMenu file={file} onRename={onRename} onDelete={onDelete} />
                  </div>
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}
