"use client";

import { useQuery, useMutation } from "@tanstack/react-query";
import { useRef } from "react";
import { motion, AnimatePresence } from "framer-motion";
import {
  FileDown,
  FileText,
  FileX,
  Loader2,
  FolderOpen,
  X,
  ExternalLink,
  HardHat,
} from "lucide-react";
import {
  Drawer,
  DrawerClose,
  DrawerContent,
  DrawerHeader,
  DrawerTitle,
  DrawerDescription,
} from "@/app/shadcn_components/ui/drawer";
import type { PropertyDocument, DocStatus } from "./types";
import { EXPECTED_RETROFIT_ASSESSMENT_DOC_TYPES, SURVEY_ALL_DOC_TYPES } from "./types";

// Human-readable labels for all DB fileType enum values
const DOC_TYPE_LABELS: Record<string, string> = {
  // Survey / retrofit assessment docs
  photo_pack: "Photo Pack",
  site_note: "Site Note",
  rd_sap_site_note: "RdSAP Site Note",
  pas_2023_ventilation: "PAS 2023 Ventilation",
  pas_2023_condition: "PAS 2023 Condition Report",
  pas_significance: "PAS Significance",
  par_photo_pack: "PAR Photo Pack",
  pas_2023_property: "PAS 2023 Property Report",
  pas_2023_occupancy: "PAS 2023 Occupancy Report",
  ecmk_site_note: "ECMK Site Note",
  ecmk_rd_sap_site_note: "ECMK RdSAP Site Note",
  ecmk_survey_xml: "ECMK Survey XML",
  // Install docs — photos
  pre_photo: "Pre-Install Photos",
  mid_photo: "Mid-Install Photos",
  post_photo: "Post-Install Photos",
  loft_hatch_photo: "Loft Hatch & Draft Excluder Photos",
  dmev_photos: "DMEV Photos (Wetrooms)",
  door_undercut_photos: "Door Undercut Photos",
  trickle_vent_photos: "Trickle Vent Photos",
  // Install docs — pre-installation
  pre_installation_building_inspection: "PIBI / Tech Survey",
  point_of_work_risk_assessment: "Point of Work Risk Assessment",
  // Install docs — compliance & lodgement
  claim_of_compliance: "DOCC 2030 (Claim of Compliance)",
  mcs_compliance_certificate: "MCS Compliance Certificate",
  certificate_of_conformity: "Certificate of Conformity",
  minor_works_electrical_certificate: "Minor Works Electrical Certificate",
  trustmark_licence_numbers: "TrustMark Licence Numbers",
  operative_competency: "Operative Competency",
  // Install docs — ventilation
  ventilation_assessment_checklist: "Ventilation Assessment Checklist",
  anemometer_readings: "Anemometer Readings",
  commissioning_records: "Commissioning Records",
  part_f_ventilation_document: "Approved Document Part F",
  // Install docs — handover & warranties
  handover_pack: "Handover Pack",
  insurance_guarantee: "Insurance Backed Guarantee (IBG)",
  workmanship_warranty: "Workmanship Warranty",
  g98_notification: "G98 / G99 Notification",
  // Install docs — qualifications & other
  installer_qualifications: "Installer Qualifications",
  installer_feedback: "Installer Feedback",
  contractor_other: "Other",
};

function formatDate(iso: string): string {
  try {
    return new Date(iso).toLocaleDateString("en-GB", {
      day: "numeric",
      month: "short",
      year: "numeric",
    });
  } catch {
    return iso;
  }
}

// -----------------------------------------------------------------------
// Reusable download button — encapsulates the presigned URL mutation
// -----------------------------------------------------------------------
function DownloadDocButton({ doc }: { doc: PropertyDocument }) {
  const { mutate: download, isPending: signing } = useMutation({
    mutationFn: async () => {
      const res = await fetch("/api/sign-document-url", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ key: doc.s3FileKey, bucket: doc.s3FileBucket }),
      });
      if (!res.ok) throw new Error("Failed to get signed URL");
      const data = await res.json();
      return data.url as string;
    },
    onSuccess: (url) => {
      window.open(url, "_blank");
    },
  });

  return (
    <button
      onClick={() => download()}
      disabled={signing}
      className="shrink-0 inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg bg-brandblue text-white text-xs font-medium hover:bg-brandblue/90 transition-colors disabled:opacity-60 disabled:cursor-not-allowed"
    >
      {signing ? (
        <Loader2 className="h-3.5 w-3.5 animate-spin" />
      ) : (
        <FileDown className="h-3.5 w-3.5" />
      )}
      {signing ? "Preparing…" : "Download"}
    </button>
  );
}

// -----------------------------------------------------------------------
// Individual document row — used in retrofit section and install fallback
// -----------------------------------------------------------------------
function DocumentRow({ doc, showMeasure }: { doc: PropertyDocument; showMeasure?: boolean }) {
  const label = DOC_TYPE_LABELS[doc.docType] ?? doc.docType;

  return (
    <motion.div
      layout
      initial={{ opacity: 0, y: 4 }}
      animate={{ opacity: 1, y: 0 }}
      className="flex items-center justify-between gap-4 px-4 py-3 rounded-lg border border-gray-100 bg-white hover:border-brandblue/20 hover:shadow-sm transition-all duration-150"
    >
      {/* Left: icon + label + date stacked */}
      <div className="flex items-center gap-3 min-w-0">
        <div className="shrink-0 w-8 h-8 rounded-lg bg-sky-50 border border-sky-200 flex items-center justify-center">
          <FileText className="h-4 w-4 text-sky-600" />
        </div>
        <div className="min-w-0">
          <p className="text-sm font-medium text-gray-800 truncate">{label}</p>
          <p className="text-xs text-gray-400 mt-0.5">
            {showMeasure && doc.measureName
              ? <><span className="text-brandblue/70 font-medium">{doc.measureName}</span> · {formatDate(doc.s3UploadTimestamp)}</>
              : formatDate(doc.s3UploadTimestamp)
            }
          </p>
        </div>
      </div>

      <DownloadDocButton doc={doc} />
    </motion.div>
  );
}

// -----------------------------------------------------------------------
// PropertyDrawer — main component
// -----------------------------------------------------------------------
interface PropertyDrawerProps {
  open: boolean;
  dealId?: string | null;
  uprn: string | null;
  landlordPropertyId: string | null;
  dealname: string | null;
  docStatus?: DocStatus;
  onClose: () => void;
}

export default function PropertyDrawer({
  open,
  dealId,
  uprn,
  landlordPropertyId,
  dealname,
  docStatus,
  onClose,
}: PropertyDrawerProps) {
  const canQuery = !!(dealId || uprn || landlordPropertyId);
  const {
    data: fetchedDocuments = [],
    isFetching,
    isError,
  } = useQuery({
    queryKey: ["property-documents", dealId, uprn, landlordPropertyId],
    queryFn: async () => {
      const params = new URLSearchParams();
      if (dealId) params.set("dealId", dealId);
      else if (uprn) params.set("uprn", uprn);
      else if (landlordPropertyId)
        params.set("landlordPropertyId", landlordPropertyId);
      const res = await fetch(
        `/api/live-tracking/property-documents?${params}`,
      );
      if (!res.ok) throw new Error("Failed to load documents");
      return res.json() as Promise<PropertyDocument[]>;
    },
    enabled: open && canQuery,
    staleTime: 30_000,
  });

  // Keep the last successfully fetched result so the closing animation doesn't
  // flash the empty state (the parent nulls out uprn/landlordPropertyId on close,
  // which disables the query and resets fetchedDocuments to [] mid-animation).
  const lastDocumentsRef = useRef<PropertyDocument[]>([]);
  if (open && !isFetching && !isError) {
    lastDocumentsRef.current = fetchedDocuments as PropertyDocument[];
  }
  const documents = open ? (fetchedDocuments as PropertyDocument[]) : lastDocumentsRef.current;

  // Split documents into the two sections
  const retrofitDocs = documents.filter((d) => SURVEY_ALL_DOC_TYPES.has(d.docType));
  const installDocs = documents.filter((d) => !SURVEY_ALL_DOC_TYPES.has(d.docType));

  const hasDocuments = documents.length > 0;

  // Missing mandatory retrofit assessment docs (ecmk types are optional — not shown as missing)
  const presentRetrofitTypes = new Set(retrofitDocs.map((d) => d.docType));
  const missingRetrofitTypes = EXPECTED_RETROFIT_ASSESSMENT_DOC_TYPES.filter(
    (t) => !presentRetrofitTypes.has(t),
  );

  return (
    <Drawer open={open} onOpenChange={(v) => !v && onClose()} direction="right">
      <DrawerContent className="fixed right-0 top-0 bottom-0 h-full w-[40vw] min-w-80 rounded-l-2xl rounded-r-none mt-0 flex flex-col border-l border-t-0 border-b-0 border-r-0 border-brandblue/10 bg-white shadow-2xl overflow-hidden">
        {/* Remove the default drag handle */}
        <div className="hidden" />

        <DrawerHeader className="shrink-0 px-6 pt-6 pb-4 border-b border-gray-100">
          <div className="flex items-start justify-between gap-3">
            <div className="min-w-0 flex-1">
              <DrawerTitle className="text-lg font-semibold text-brandblue leading-tight line-clamp-2">
                {dealname ?? "Property Documents"}
              </DrawerTitle>
              {uprn ? (
                <DrawerDescription className="text-xs text-gray-500 mt-0.5 font-mono truncate">
                  UPRN: {uprn}
                </DrawerDescription>
              ) : landlordPropertyId ? (
                <DrawerDescription className="text-xs text-gray-500 mt-0.5 font-mono truncate">
                  Ref: {landlordPropertyId}
                </DrawerDescription>
              ) : null}
            </div>
            <DrawerClose asChild>
              <button
                onClick={onClose}
                className="shrink-0 p-1.5 rounded-lg text-gray-400 hover:text-gray-600 hover:bg-gray-100 transition-colors"
              >
                <X className="h-4 w-4" />
              </button>
            </DrawerClose>
          </div>

          {hasDocuments && !isFetching && (
            <div className="mt-3 inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-brandblue/10 border border-brandblue/20">
              <FileDown className="h-3.5 w-3.5 text-brandblue" />
              <span className="text-xs font-medium text-brandblue">
                {documents.length} document{documents.length !== 1 ? "s" : ""}
              </span>
            </div>
          )}
        </DrawerHeader>

        {/* Body */}
        <div className="flex-1 overflow-y-auto px-6 py-4 space-y-6">
          {/* Loading state */}
          {isFetching && (
            <div className="space-y-3 pt-2">
              {[1, 2, 3].map((i) => (
                <div
                  key={i}
                  className="h-14 rounded-lg bg-gray-100 animate-pulse"
                />
              ))}
            </div>
          )}

          {/* Error state */}
          {isError && !isFetching && (
            <div className="flex flex-col items-center justify-center py-12 text-center">
              <div className="w-10 h-10 rounded-full bg-red-50 flex items-center justify-center mb-3">
                <ExternalLink className="h-5 w-5 text-red-400" />
              </div>
              <p className="text-sm font-medium text-gray-700">
                Could not load documents
              </p>
              <p className="text-xs text-gray-500 mt-1">
                Please try again later.
              </p>
            </div>
          )}

          {/* Empty state */}
          {!isFetching && !isError && !hasDocuments && (
            <div className="space-y-4 pt-1">
              <div className="flex flex-col items-center py-6 text-center">
                <div className="w-12 h-12 rounded-full bg-amber-50 border border-amber-200 flex items-center justify-center mb-3">
                  <FolderOpen className="h-6 w-6 text-amber-400" />
                </div>
                <p className="text-sm font-medium text-gray-700">
                  No documents available
                </p>
                <p className="text-xs text-gray-400 mt-1">
                  All {EXPECTED_RETROFIT_ASSESSMENT_DOC_TYPES.length} retrofit assessment documents are outstanding.
                </p>
              </div>
              <div className="space-y-1.5">
                <h3 className="text-xs font-semibold uppercase tracking-wide text-amber-500 px-0.5">
                  Missing Documents ({missingRetrofitTypes.length})
                </h3>
                {missingRetrofitTypes.map((t) => (
                  <div
                    key={t}
                    className="flex items-center gap-2.5 p-3 rounded-lg border border-dashed border-amber-200 bg-amber-50/40"
                  >
                    <FileX className="h-3.5 w-3.5 text-amber-300 shrink-0" />
                    <span className="text-xs text-amber-600 font-medium">
                      {DOC_TYPE_LABELS[t] ?? t}
                    </span>
                  </div>
                ))}
              </div>
            </div>
          )}

          <AnimatePresence>
            {!isFetching && !isError && hasDocuments && (
              <>
                {/* ── Retrofit Assessment Documents ── */}
                <motion.div
                  key="retrofit"
                  initial={{ opacity: 0 }}
                  animate={{ opacity: 1 }}
                  className="space-y-2"
                >
                  <h3 className="text-xs font-semibold uppercase tracking-wide text-gray-400 px-0.5">
                    Retrofit Assessment Documents
                  </h3>
                  {retrofitDocs.length > 0 ? (
                    <div className="space-y-1.5">
                      {retrofitDocs.map((doc) => (
                        <DocumentRow key={doc.id} doc={doc} />
                      ))}
                    </div>
                  ) : (
                    <p className="text-xs text-gray-400 px-0.5">None uploaded yet.</p>
                  )}

                  {/* Missing mandatory retrofit assessment docs */}
                  {missingRetrofitTypes.length > 0 && (
                    <div className="space-y-1.5 pt-1">
                      <h4 className="text-xs font-semibold uppercase tracking-wide text-amber-500 px-0.5">
                        Missing ({missingRetrofitTypes.length})
                      </h4>
                      {missingRetrofitTypes.map((t) => (
                        <div
                          key={t}
                          className="flex items-center gap-2.5 p-3 rounded-lg border border-dashed border-amber-200 bg-amber-50/40"
                        >
                          <FileX className="h-3.5 w-3.5 text-amber-300 shrink-0" />
                          <span className="text-xs text-amber-600 font-medium">
                            {DOC_TYPE_LABELS[t] ?? t}
                          </span>
                        </div>
                      ))}
                    </div>
                  )}
                </motion.div>

                {/* ── Install Documents ── */}
                <motion.div
                  key="install"
                  initial={{ opacity: 0 }}
                  animate={{ opacity: 1 }}
                  className="space-y-3"
                >
                  <h3 className="text-xs font-semibold uppercase tracking-wide text-gray-400 px-0.5 flex items-center gap-1.5">
                    <HardHat className="h-3.5 w-3.5" />
                    Install Documents
                  </h3>

                  {docStatus?.measureProgress && docStatus.measureProgress.length > 0 ? (
                    // ── Per-measure checklist ──
                    <div className="space-y-4">
                      {docStatus.measureProgress.map((mp) => {
                        const measureDocs = installDocs.filter((d) => d.measureName === mp.measureName);
                        const uploadedTypeSet = new Set(measureDocs.map((d) => d.docType));
                        const missingTypes = mp.required.filter((t) => !uploadedTypeSet.has(t));

                        return (
                          <div key={mp.measureName} className="rounded-xl border border-gray-100 bg-gray-50/40 overflow-hidden">
                            {/* Measure header */}
                            <div className="flex items-center justify-between px-3 py-2.5 border-b border-gray-100 bg-white">
                              <span className="text-xs font-semibold text-gray-800">{mp.measureName}</span>
                              <span className={`inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-[10px] font-medium border ${
                                mp.isComplete
                                  ? "bg-emerald-50 text-emerald-700 border-emerald-200"
                                  : mp.uploadedCount > 0
                                    ? "bg-amber-50 text-amber-700 border-amber-200"
                                    : "bg-gray-100 text-gray-500 border-gray-200"
                              }`}>
                                {mp.uploadedCount} / {mp.requiredCount} docs
                              </span>
                            </div>

                            <div className="px-3 py-2.5 space-y-1.5">
                              {/* Uploaded required docs */}
                              {mp.uploaded.map((docType) => {
                                const doc = measureDocs.find((d) => d.docType === docType);
                                if (!doc) return null;
                                return (
                                  <div key={docType} className="flex items-center justify-between gap-3 px-3 py-2 rounded-lg border border-emerald-100 bg-emerald-50/50">
                                    <div className="flex items-center gap-2 min-w-0">
                                      <div className="shrink-0 w-5 h-5 rounded-full bg-emerald-100 border border-emerald-200 flex items-center justify-center">
                                        <svg className="h-3 w-3 text-emerald-600" viewBox="0 0 12 12" fill="none">
                                          <path d="M2 6l3 3 5-5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
                                        </svg>
                                      </div>
                                      <div className="min-w-0">
                                        <p className="text-xs font-medium text-gray-800 truncate">{DOC_TYPE_LABELS[docType] ?? docType}</p>
                                        <p className="text-[10px] text-gray-400">{formatDate(doc.s3UploadTimestamp)}</p>
                                      </div>
                                    </div>
                                    <DownloadDocButton doc={doc} />
                                  </div>
                                );
                              })}

                              {/* Missing required docs */}
                              {missingTypes.map((docType) => (
                                <div key={docType} className="flex items-center gap-2.5 px-3 py-2 rounded-lg border border-dashed border-amber-200 bg-amber-50/30">
                                  <div className="shrink-0 w-5 h-5 rounded-full border-2 border-dashed border-amber-300 flex items-center justify-center">
                                    <FileX className="h-2.5 w-2.5 text-amber-400" />
                                  </div>
                                  <p className="text-xs text-amber-700 font-medium">{DOC_TYPE_LABELS[docType] ?? docType}</p>
                                </div>
                              ))}

                              {/* Extra docs uploaded for this measure (not in required list) */}
                              {measureDocs
                                .filter((d) => !mp.required.includes(d.docType))
                                .map((doc) => (
                                  <div key={doc.id} className="flex items-center justify-between gap-3 px-3 py-2 rounded-lg border border-gray-100 bg-white">
                                    <div className="flex items-center gap-2 min-w-0">
                                      <div className="shrink-0 w-5 h-5 rounded-full bg-sky-50 border border-sky-200 flex items-center justify-center">
                                        <FileText className="h-3 w-3 text-sky-500" />
                                      </div>
                                      <div className="min-w-0">
                                        <p className="text-xs font-medium text-gray-800 truncate">{DOC_TYPE_LABELS[doc.docType] ?? doc.docType}</p>
                                        <p className="text-[10px] text-gray-400">{formatDate(doc.s3UploadTimestamp)}</p>
                                      </div>
                                    </div>
                                    <DownloadDocButton doc={doc} />
                                  </div>
                                ))
                              }
                            </div>
                          </div>
                        );
                      })}

                      {/* Unassigned / no-measure install docs */}
                      {(() => {
                        const knownMeasures = new Set(docStatus.measureProgress.map((m) => m.measureName));
                        const unassigned = installDocs.filter(
                          (d) => !d.measureName || !knownMeasures.has(d.measureName),
                        );
                        if (unassigned.length === 0) return null;
                        return (
                          <div className="space-y-1.5">
                            <h4 className="text-[10px] font-semibold uppercase tracking-wide text-gray-400 px-0.5">Other</h4>
                            {unassigned.map((doc) => (
                              <DocumentRow key={doc.id} doc={doc} showMeasure />
                            ))}
                          </div>
                        );
                      })()}
                    </div>
                  ) : installDocs.length > 0 ? (
                    // ── Fallback: flat list (no measure progress data) ──
                    <div className="space-y-1.5">
                      {installDocs.map((doc) => (
                        <DocumentRow key={doc.id} doc={doc} showMeasure />
                      ))}
                    </div>
                  ) : (
                    <p className="text-xs text-gray-400 px-0.5">No install documents uploaded yet.</p>
                  )}
                </motion.div>
              </>
            )}
          </AnimatePresence>
        </div>

        {/* Footer */}
        <div className="px-6 py-4 border-t border-gray-100 bg-gray-50/50">
          <p className="text-xs text-gray-400">
            Download links expire after 30 minutes. Refresh to generate a new
            link.
          </p>
        </div>
      </DrawerContent>
    </Drawer>
  );
}
