"use client";

import { useRef, useState, type FormEvent, type ReactNode } from "react";
import { useRouter } from "next/navigation";
import Link from "next/link";
import { Download, Eye, Upload } from "lucide-react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { formatDateTimeCL } from "@/lib/date-format";
import { BitacoraArchivoDeleteDialog } from "@/components/bitacora/bitacora-archivo-delete-dialog";
import { BitacoraArchivoRenameDialog } from "@/components/bitacora/bitacora-archivo-rename-dialog";

export function BitacoraFilesPanel({
  hitoId,
  archivos,
  canManage,
}: {
  hitoId: string;
  archivos: Array<{ id: string; nombre: string; mimeType: string; tamano: number; createdAt: Date; deletedAt: Date | null }>;
  canManage: boolean;
}) {
  const router = useRouter();
  const inputRef = useRef<HTMLInputElement | null>(null);
  const formRef = useRef<HTMLFormElement | null>(null);
  const [isUploading, setIsUploading] = useState(false);

  async function handleUpload(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const file = inputRef.current?.files?.[0];
    if (!file) {
      toast.error("Selecciona un archivo.");
      return;
    }

    const formData = new FormData();
    formData.append("archivo", file);

    try {
      setIsUploading(true);
      const response = await fetch(`/api/bitacora/hitos/${hitoId}/archivos`, {
        method: "POST",
        body: formData,
      });

      const contentType = response.headers.get("content-type") ?? "";
      const payload = contentType.includes("application/json") ? await response.json() : { success: false, error: await response.text() };

      if (!response.ok || !payload?.success) {
        toast.error(payload?.error ?? "No fue posible subir el archivo.");
        return;
      }

      toast.success("Archivo subido correctamente.");
      formRef.current?.reset();
      if (inputRef.current) inputRef.current.value = "";
      router.refresh();
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "No fue posible subir el archivo.");
    } finally {
      setIsUploading(false);
    }
  }

  return (
    <Card className="border-border shadow-sm">
      <CardHeader>
        <CardTitle>Archivos asociados</CardTitle>
      </CardHeader>
      <CardContent className="space-y-6">
        {canManage ? (
          <form ref={formRef} onSubmit={handleUpload} className="space-y-3 rounded-lg border border-border bg-muted p-4" encType="multipart/form-data">
            <Input
              ref={inputRef}
              type="file"
              name="archivo"
              accept=".pdf,.docx,.xlsx,.jpg,.jpeg,.png,.dwg,.zip,application/pdf,image/jpeg,image/png,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/zip,application/x-zip-compressed,application/acad,application/octet-stream"
              disabled={isUploading}
            />
            <div className="flex justify-end">
              <Button type="submit" size="sm" disabled={isUploading}>
                <Upload className="h-4 w-4" />
                {isUploading ? "Subiendo..." : "Subir archivo"}
              </Button>
            </div>
          </form>
        ) : null}

        <div className="space-y-3">
          {archivos.length === 0 ? (
            <p className="text-sm text-muted-foreground">Sin archivos asociados.</p>
          ) : (
            archivos.map((archivo) => (
              <div key={archivo.id} className="flex flex-col gap-3 rounded-lg border border-border bg-card p-4 sm:flex-row sm:items-center sm:justify-between">
                <div className="space-y-1">
                  <p className="font-medium text-foreground">{archivo.nombre}</p>
                  <p className="text-xs text-muted-foreground">
                    {formatDateTimeCL(archivo.createdAt)} · {formatBytes(archivo.tamano)} · {archivo.mimeType}
                  </p>
                </div>
                <div className="flex flex-wrap gap-2">
                  <ActionButton href={`/api/bitacora/archivos/${archivo.id}/view`} title="Ver archivo" target="_blank">
                    <Eye className="h-4 w-4" />
                  </ActionButton>
                  <ActionButton href={`/api/bitacora/archivos/${archivo.id}/download`} title="Descargar archivo">
                    <Download className="h-4 w-4" />
                  </ActionButton>
                  {canManage ? (
                    <>
                      <BitacoraArchivoRenameDialog archivoId={archivo.id} hitoId={hitoId} nombreActual={archivo.nombre} />
                      <BitacoraArchivoDeleteDialog archivoId={archivo.id} hitoId={hitoId} />
                    </>
                  ) : null}
                </div>
              </div>
            ))
          )}
        </div>
      </CardContent>
    </Card>
  );
}

function ActionButton({ href, title, target, children }: { href: string; title: string; target?: string; children: ReactNode }) {
  return (
    <Button asChild size="icon" variant="ghost" className="h-8 w-8" title={title} aria-label={title}>
      <Link href={href} target={target} rel={target === "_blank" ? "noopener noreferrer" : undefined}>
        {children}
      </Link>
    </Button>
  );
}

function formatBytes(value: number) {
  if (value < 1024) return `${value} B`;
  const kb = value / 1024;
  if (kb < 1024) return `${kb.toFixed(1)} KB`;
  return `${(kb / 1024).toFixed(1)} MB`;
}
