"use client";

import { useState } from "react";
import {
  Camera,
  FileText,
  Zap,
  ClipboardCheck,
  Download,
  Loader2,
  LayoutGrid,
  List,
} from "lucide-react";

export type RawFileType =
  | "photo_pack"
  | "site_note"
  | "rd_sap_site_note"
  | "pas_2023_ventilation"
  | "pas_2023_condition"
  | "pas_significance"
  | "par_photo_pack"
  | "pas_2023_property"
  | "pas_2023_occupancy"
  | "ecmk_site_note"
  | "ecmk_rd_sap_site_note"
  | "unknown";

type Document = {
  id: string;
  s3FileKey: string;
  s3FileBucket: string;
  docType: RawFileType;
  s3UploadTimestamp: string;
};

type GroupConfig = {
  label: string;
  types: RawFileType[];
  icon: React.ComponentType<{ className?: string }>;
};

const GROUPS: GroupConfig[] = [
  {
    label: "Photos",
    types: ["photo_pack", "par_photo_pack"],
    icon: Camera,
  },
  {
    label: "Energy Performance",
    types: ["site_note", "ecmk_site_note", "rd_sap_site_note", "ecmk_rd_sap_site_note"],
    icon: Zap,
  },
  {
    label: "PAS Condition & Other",
    types: ["pas_2023_condition", "pas_2023_ventilation", "pas_2023_occupancy", "pas_2023_property", "pas_significance"],
    icon: ClipboardCheck,
  },
];

function getGroupForType(docType: RawFileType): GroupConfig | undefined {
  return GROUPS.find((g) => g.types.includes(docType));
}

const DOC_TYPE_LABELS: Record<RawFileType, string> = {
  photo_pack: "Photo Pack",
  par_photo_pack: "Photo Pack",
  site_note: "Site Note",
  ecmk_site_note: "Site Note",
  rd_sap_site_note: "RdSAP Report",
  ecmk_rd_sap_site_note: "RdSAP Report",
  pas_2023_condition: "Condition Report",
  pas_2023_ventilation: "Ventilation Report",
  pas_2023_occupancy: "Occupancy Report",
  pas_2023_property: "Property Report",
  pas_significance: "Significance Report",
  unknown: "Document",
};

function getDisplayLabel(docType: RawFileType): string {
  return DOC_TYPE_LABELS[docType] ?? "Document";
}

function extractFilename(s3Key: string): string {
  const parts = s3Key.split("/");
  return parts[parts.length - 1] ?? s3Key;
}

function formatDate(iso: string): string {
  const d = new Date(iso);
  return d.toLocaleDateString("en-GB", {
    day: "2-digit",
    month: "short",
    year: "numeric",
  });
}

async function fetchPresignedUrl(key: string, bucket: string): Promise<string> {
  const res = await fetch("/api/sign-document-url", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ key, bucket }),
  });
  if (!res.ok) throw new Error("Failed to get download URL");
  const data = await res.json();
  return data.url;
}

function DocumentCard({
  doc,
  viewMode,
}: {
  doc: Document;
  viewMode: "grid" | "list";
}) {
  const [loading, setLoading] = useState(false);

  const group = getGroupForType(doc.docType);
  const Icon = group?.icon ?? FileText;
  const filename = extractFilename(doc.s3FileKey);
  const label = getDisplayLabel(doc.docType);
  const date = formatDate(doc.s3UploadTimestamp);

  async function handleDownload() {
    setLoading(true);
    try {
      const url = await fetchPresignedUrl(doc.s3FileKey, doc.s3FileBucket);
      window.open(url, "_blank");
    } catch {
      // silently fail — could add a toast here
    } finally {
      setLoading(false);
    }
  }

  if (viewMode === "list") {
    return (
      <div className="group flex items-center gap-4 bg-white rounded-xl px-5 py-4 shadow-sm hover:shadow-md transition-shadow">
        <div className="w-10 h-10 rounded-xl bg-[#eff6fc] flex items-center justify-center text-[#3943b7] flex-shrink-0">
          <Icon className="w-5 h-5" />
        </div>
        <div className="flex-1 min-w-0">
          <p className="text-sm font-semibold text-[#15173e] truncate">
            {filename}
          </p>
          <p className="text-xs text-slate-400 mt-0.5">
            {label} · {date}
          </p>
        </div>
        <button
          onClick={handleDownload}
          disabled={loading}
          className="w-9 h-9 rounded-full bg-[#15173e] text-white flex items-center justify-center hover:opacity-80 active:scale-95 transition-all disabled:opacity-50"
        >
          {loading ? (
            <Loader2 className="w-4 h-4 animate-spin" />
          ) : (
            <Download className="w-4 h-4" />
          )}
        </button>
      </div>
    );
  }

  return (
    <div className="group bg-white p-6 rounded-2xl shadow-sm hover:-translate-y-1 hover:shadow-md transition-all duration-300">
      <div className="flex justify-between items-start mb-5">
        <div className="w-11 h-11 rounded-xl bg-[#eff6fc] flex items-center justify-center text-[#3943b7]">
          <Icon className="w-5 h-5" />
        </div>
      </div>
      <p className="text-xs font-bold uppercase tracking-widest text-slate-400 mb-1">
        {label}
      </p>
      <h3 className="text-sm font-semibold text-[#15173e] mb-1 leading-snug break-all line-clamp-2">
        {filename}
      </h3>
      <div className="flex items-center justify-between pt-4 mt-4 border-t border-slate-100">
        <span className="text-xs text-slate-400">{date}</span>
        <button
          onClick={handleDownload}
          disabled={loading}
          className="w-9 h-9 rounded-full bg-[#15173e] text-white flex items-center justify-center group-hover:scale-110 active:scale-95 transition-transform disabled:opacity-50"
        >
          {loading ? (
            <Loader2 className="w-4 h-4 animate-spin" />
          ) : (
            <Download className="w-4 h-4" />
          )}
        </button>
      </div>
    </div>
  );
}

export function DocumentsClient({ documents }: { documents: Document[] }) {
  const [activeFilter, setActiveFilter] = useState("All");
  const [viewMode, setViewMode] = useState<"grid" | "list">("grid");

  // Only show groups that have at least one document
  const presentGroups = GROUPS.filter((g) =>
    documents.some((d) => g.types.includes(d.docType))
  );

  const filteredDocs =
    activeFilter === "All"
      ? documents
      : documents.filter((d) => {
          const group = getGroupForType(d.docType);
          return group?.label === activeFilter;
        });

  // For grouped display: group the filtered docs
  const groupsToShow =
    activeFilter === "All"
      ? presentGroups
      : presentGroups.filter((g) => g.label === activeFilter);

  return (
    <div>
      {/* Header */}
      <div className="mb-8">
        <h1 className="text-3xl font-extrabold text-[#15173e] tracking-tight">
          Documents
        </h1>
      </div>

      {/* Controls */}
      <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4 mb-8">
        {/* Filter pills */}
        <div className="flex flex-wrap gap-2">
          <button
            onClick={() => setActiveFilter("All")}
            className={`px-4 py-2 rounded-full text-sm font-semibold transition-colors ${
              activeFilter === "All"
                ? "bg-[#15173e] text-white shadow"
                : "bg-white text-slate-600 hover:bg-slate-100"
            }`}
          >
            All Documents
          </button>
          {presentGroups.map((g) => (
            <button
              key={g.label}
              onClick={() => setActiveFilter(g.label)}
              className={`px-4 py-2 rounded-full text-sm font-medium transition-colors ${
                activeFilter === g.label
                  ? "bg-[#15173e] text-white shadow"
                  : "bg-white text-slate-600 hover:bg-slate-100"
              }`}
            >
              {g.label}
            </button>
          ))}
        </div>

        {/* View toggle */}
        <div className="bg-slate-100 rounded-xl p-1 flex self-start sm:self-auto">
          <button
            onClick={() => setViewMode("grid")}
            className={`px-4 py-2 rounded-lg text-xs font-bold flex items-center gap-1.5 transition-all ${
              viewMode === "grid"
                ? "bg-white text-[#15173e] shadow-sm"
                : "text-slate-400"
            }`}
          >
            <LayoutGrid className="w-3.5 h-3.5" />
            Grid
          </button>
          <button
            onClick={() => setViewMode("list")}
            className={`px-4 py-2 rounded-lg text-xs font-bold flex items-center gap-1.5 transition-all ${
              viewMode === "list"
                ? "bg-white text-[#15173e] shadow-sm"
                : "text-slate-400"
            }`}
          >
            <List className="w-3.5 h-3.5" />
            List
          </button>
        </div>
      </div>

      {/* Empty state */}
      {filteredDocs.length === 0 && (
        <div className="py-16 text-center text-slate-400 text-sm">
          No documents found.
        </div>
      )}

      {/* Document groups */}
      {filteredDocs.length > 0 && (
        <div className="space-y-10">
          {groupsToShow.map((group) => {
            const groupDocs = filteredDocs.filter((d) =>
              group.types.includes(d.docType)
            );
            if (groupDocs.length === 0) return null;
            return (
              <div key={group.label}>
                {/* Section header */}
                <div className="flex items-center gap-4 mb-4">
                  <h2 className="text-xs font-black uppercase tracking-widest text-slate-400 whitespace-nowrap">
                    {group.label}
                  </h2>
                  <div className="h-px flex-1 bg-slate-200" />
                </div>

                {/* Cards */}
                {viewMode === "grid" ? (
                  <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-5">
                    {groupDocs.map((doc) => (
                      <DocumentCard key={doc.id} doc={doc} viewMode="grid" />
                    ))}
                  </div>
                ) : (
                  <div className="flex flex-col gap-2">
                    {groupDocs.map((doc) => (
                      <DocumentCard key={doc.id} doc={doc} viewMode="list" />
                    ))}
                  </div>
                )}
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}
