import React, { useEffect, useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { FileText, File as FileIcon, Image as ImageIcon, Loader2, Check } from "lucide-react";
import { Button } from "@/components/ui/button";
import { apiRequest } from "@/lib/queryClient";
import { useToast } from "@/hooks/use-toast";
import type { CloudFile } from "@repo/db/types";

interface ServerAttachmentsPickerModalProps {
  open: boolean;
  onClose: () => void;
  // When set, lists only this patient's saved attachments. When omitted, lists
  // recently saved attachments across all patients (used where no patient is in scope yet).
  patientId?: number;
  onFilesSelected: (files: File[]) => void;
}

function fileIcon(mime: string | undefined | null) {
  if (mime?.startsWith("image/")) return ImageIcon;
  if (mime === "application/pdf") return FileText;
  return FileIcon;
}

function AttachmentThumbnail({ file }: { file: CloudFile }) {
  const [src, setSrc] = useState<string | null>(null);

  useEffect(() => {
    if (!file.mimeType?.startsWith("image/")) return;
    let objectUrl: string | null = null;
    let cancelled = false;

    (async () => {
      const res = await apiRequest("GET", `/api/cloud-storage/files/${file.id}/content`);
      if (!res.ok || cancelled) return;
      const blob = await res.blob();
      objectUrl = URL.createObjectURL(blob);
      if (!cancelled) setSrc(objectUrl);
    })();

    return () => {
      cancelled = true;
      if (objectUrl) URL.revokeObjectURL(objectUrl);
    };
  }, [file.id, file.mimeType]);

  if (file.mimeType?.startsWith("image/")) {
    return src ? (
      <img src={src} alt={file.name} className="h-full w-full object-cover" />
    ) : (
      <Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
    );
  }

  const Icon = fileIcon(file.mimeType);
  return <Icon className="h-8 w-8 text-muted-foreground" />;
}

export function ServerAttachmentsPickerModal({
  open,
  onClose,
  patientId,
  onFilesSelected,
}: ServerAttachmentsPickerModalProps) {
  const { toast } = useToast();
  const [selectedIds, setSelectedIds] = useState<Set<number>>(new Set());
  const [isAdding, setIsAdding] = useState(false);

  const endpoint = patientId
    ? `/api/claims/patient-attachments?patientId=${patientId}`
    : `/api/claims/recent-attachments?limit=40`;

  const { data, isLoading, isError } = useQuery<CloudFile[]>({
    queryKey: ["/api/claims/attachments-picker", patientId ?? "recent"],
    queryFn: async () => {
      const res = await apiRequest("GET", endpoint);
      const json = await res.json();
      if (!res.ok || json.error) {
        throw new Error(json.message || "Failed to load attachments");
      }
      return (json.data ?? []) as CloudFile[];
    },
    enabled: open,
  });

  useEffect(() => {
    if (!open) setSelectedIds(new Set());
  }, [open]);

  if (!open) return null;

  const files = data ?? [];

  const toggleSelected = (id: number) => {
    setSelectedIds((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  };

  const handleAddSelected = async () => {
    if (selectedIds.size === 0) return;
    setIsAdding(true);
    try {
      const selectedFiles = files.filter((f) => selectedIds.has(f.id as number));
      const built = await Promise.all(
        selectedFiles.map(async (f) => {
          const res = await apiRequest("GET", `/api/cloud-storage/files/${f.id}/content`);
          const blob = await res.blob();
          return new File([blob], f.name, { type: f.mimeType || blob.type });
        })
      );
      onFilesSelected(built);
      onClose();
    } catch (err) {
      toast({
        title: "Failed to add files",
        description: "Could not fetch one or more attachments from the server.",
        variant: "destructive",
      });
    } finally {
      setIsAdding(false);
    }
  };

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center">
      <div
        className="absolute inset-0 bg-black/40"
        onClick={() => {
          if (!isAdding) onClose();
        }}
      />

      <div className="relative w-full max-w-2xl mx-4 bg-white rounded-lg shadow-lg flex flex-col max-h-[80vh]">
        <div className="p-4 border-b">
          <h3 className="text-lg font-medium">Choose from Server Attachments</h3>
          <p className="text-sm text-muted-foreground mt-1">
            {patientId
              ? "Previously saved screenshots and files for this patient."
              : "Recently saved screenshots and files across all patients."}
          </p>
        </div>

        <div className="p-4 overflow-y-auto flex-1" style={{ minHeight: "200px" }}>
          {isLoading ? (
            <div className="flex items-center justify-center h-32">
              <Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
            </div>
          ) : isError ? (
            <p className="text-sm text-red-500 text-center py-8">
              Failed to load attachments.
            </p>
          ) : files.length === 0 ? (
            <p className="text-sm text-muted-foreground text-center py-8">
              {patientId
                ? "No screenshots saved yet for this patient."
                : "No screenshots saved yet."}
            </p>
          ) : (
            <div className="grid grid-cols-2 md:grid-cols-4 gap-3">
              {files.map((file) => {
                const isSelected = selectedIds.has(file.id as number);
                return (
                  <button
                    type="button"
                    key={file.id}
                    onClick={() => toggleSelected(file.id as number)}
                    className={`relative border rounded-md overflow-hidden text-left ${
                      isSelected ? "ring-2 ring-primary border-primary" : "hover:bg-muted/40"
                    }`}
                  >
                    <div className="h-24 flex items-center justify-center bg-gray-50">
                      <AttachmentThumbnail file={file} />
                    </div>
                    <div className="p-2">
                      <p className="text-xs font-medium truncate">{file.name}</p>
                    </div>
                    {isSelected && (
                      <div className="absolute top-1 right-1 bg-primary text-primary-foreground rounded-full p-0.5">
                        <Check className="h-3 w-3" />
                      </div>
                    )}
                  </button>
                );
              })}
            </div>
          )}
        </div>

        <div className="flex items-center justify-end gap-2 p-4 border-t">
          <Button variant="ghost" type="button" onClick={onClose} disabled={isAdding}>
            Cancel
          </Button>
          <Button
            type="button"
            onClick={handleAddSelected}
            disabled={selectedIds.size === 0 || isAdding}
          >
            {isAdding ? "Adding..." : `Add Selected (${selectedIds.size})`}
          </Button>
        </div>
      </div>
    </div>
  );
}
