"use client";

import { useState } from "react";
import { useMutation } from "@tanstack/react-query";
import { motion, AnimatePresence } from "framer-motion";
import {
  ChevronRight,
  FileDown,
  FileText,
  FileX,
  Loader2,
  FolderOpen,
  ExternalLink,
  HardHat,
  Upload,
} from "lucide-react";
import type { PropertyDocument, DocStatus } from "./types";
import { EXPECTED_RETROFIT_ASSESSMENT_DOC_TYPES } from "./types";
import { splitDocumentsByType, getMissingSurveyDocTypes, getUnassignedInstallDocs } from "./propertyDocuments";
import ContractorUploadModal from "./ContractorUploadModal";
import type { ClassifiedDeal, PortfolioCapabilityType } from "./types";

export const DOC_TYPE_LABELS: Record<string, string> = {
  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",
  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",
  pre_installation_building_inspection: "PIBI / Tech Survey",
  point_of_work_risk_assessment: "Point of Work Risk Assessment",
  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",
  ventilation_assessment_checklist: "Ventilation Assessment Checklist",
  anemometer_readings: "Anemometer Readings",
  commissioning_records: "Commissioning Records",
  part_f_ventilation_document: "Approved Document Part F",
  handover_pack: "Handover Pack",
  insurance_guarantee: "Insurance Backed Guarantee (IBG)",
  workmanship_warranty: "Workmanship Warranty",
  g98_notification: "G98 / G99 Notification",
  installer_qualifications: "Installer Qualifications",
  installer_feedback: "Installer Feedback",
  contractor_other: "Other",
  improvement_option_evaluation: "Improvement Option Evaluation",
  medium_term_improvement_plan: "Medium Term Improvement Plan",
  retrofit_design_doc: "Retrofit Design Document"
};

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

export 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>
  );
}

export 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"
    >
      <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>{" "}
                · {formatDocDate(doc.s3UploadTimestamp)}
              </>
            ) : (
              formatDocDate(doc.s3UploadTimestamp)
            )}
          </p>
        </div>
      </div>
      <DownloadDocButton doc={doc} />
    </motion.div>
  );
}

interface PropertyDocumentsContentProps {
  documents: PropertyDocument[];
  isFetching: boolean;
  isError: boolean;
  docStatus: DocStatus;
  // Upload (contractor-only, all required to show button)
  deal?: ClassifiedDeal;
  portfolioId?: string;
  userCapability?: PortfolioCapabilityType;
  approvedMeasures?: string[];
}

export default function PropertyDocumentsContent({
  documents,
  isFetching,
  isError,
  docStatus,
  deal,
  portfolioId,
  userCapability,
  approvedMeasures,
}: PropertyDocumentsContentProps) {
  const [uploadOpen, setUploadOpen] = useState(false);
  const [openMeasures, setOpenMeasures] = useState<Set<string>>(new Set());
  const [otherOpen, setOtherOpen] = useState(false);

  const toggleMeasure = (measureName: string) =>
    setOpenMeasures((prev) => {
      const next = new Set(prev);
      next.has(measureName) ? next.delete(measureName) : next.add(measureName);
      return next;
    });

  const { docs: surveyDocs, coordinationDocs, designDocs, installDocs } = splitDocumentsByType(documents);
  const missingSurveyDocTypes = getMissingSurveyDocTypes(surveyDocs);
  const hasDocuments = documents.length > 0;

  const isContractor = userCapability?.includes("contractor") ?? false;
  const canUpload = isContractor && !!deal && !!portfolioId;

  const docStatusMap = deal
    ? { [deal.dealId]: docStatus }
    : undefined;

  return (
    <div className="space-y-4">
      {/* Upload button */}
      {canUpload && (
        <div className="flex justify-end">
          <button
            onClick={() => setUploadOpen(true)}
            className="inline-flex items-center gap-2 px-4 py-2 rounded-lg bg-brandblue text-white text-sm font-semibold hover:bg-brandmidblue transition-colors"
          >
            <Upload className="h-4 w-4" />
            Upload Docs
          </button>
        </div>
      )}

      {/* Loading */}
      {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 */}
      {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 */}
      {!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 ({missingSurveyDocTypes.length})
            </h3>
            {missingSurveyDocTypes.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>
      )}

      {/* Documents */}
      <AnimatePresence>
        {!isFetching && !isError && hasDocuments && (
          <>
            {/* Retrofit Assessment */}
            <motion.div key="survey" 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>
              {surveyDocs.length > 0 ? (
                <div className="space-y-1.5">
                  {surveyDocs.map((doc) => (
                    <DocumentRow key={doc.id} doc={doc} />
                  ))}
                </div>
              ) : (
                <p className="text-xs text-gray-400 px-0.5">None uploaded yet.</p>
              )}
              {missingSurveyDocTypes.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 ({missingSurveyDocTypes.length})
                  </h4>
                  {missingSurveyDocTypes.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>

            {/* Coordination Documents */}
            <motion.div key="coordination" 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">
                Coordination Documents
              </h3>
              {coordinationDocs.length > 0 ? (
                <div className="space-y-1.5">
                  {coordinationDocs.map((doc) => (
                    <DocumentRow key={doc.id} doc={doc} />
                  ))}
                </div>
              ) : (
                <p className="text-xs text-gray-400 px-0.5">None uploaded yet.</p>
              )}
            </motion.div>

            {/* Design Documents */}
            <motion.div key="design" 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">
                Design Documents
              </h3>
              {designDocs.length > 0 ? (
                <div className="space-y-1.5">
                  {designDocs.map((doc) => (
                    <DocumentRow key={doc.id} doc={doc} />
                  ))}
                </div>
              ) : (
                <p className="text-xs text-gray-400 px-0.5">None uploaded yet.</p>
              )}
            </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.length > 0 ? (
                <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));

                    const isOpen = openMeasures.has(mp.measureName);
                    return (
                      <div key={mp.measureName} className="rounded-xl border border-gray-100 bg-gray-50/40 overflow-hidden">
                        <button
                          onClick={() => toggleMeasure(mp.measureName)}
                          className="w-full flex items-center justify-between px-3 py-2.5 bg-white hover:bg-gray-50 transition-colors text-left"
                        >
                          <span className="flex items-center gap-2">
                            <ChevronRight className={`h-3.5 w-3.5 text-gray-400 transition-transform duration-150 ${isOpen ? "rotate-90" : ""}`} />
                            <span className="text-xs font-semibold text-gray-800">{mp.measureName}</span>
                          </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>
                        </button>
                        {isOpen && <div className="px-3 py-2.5 space-y-1.5 border-t border-gray-100">
                          {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">{formatDocDate(doc.s3UploadTimestamp)}</p>
                                  </div>
                                </div>
                                <DownloadDocButton doc={doc} />
                              </div>
                            );
                          })}
                          {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>
                          ))}
                          {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">{formatDocDate(doc.s3UploadTimestamp)}</p>
                                  </div>
                                </div>
                                <DownloadDocButton doc={doc} />
                              </div>
                            ))}
                        </div>}
                      </div>
                    );
                  })}

                  {/* Unassigned install docs */}
                  {(() => {
                    const unassigned = getUnassignedInstallDocs(installDocs, docStatus.measureProgress);
                    if (unassigned.length === 0) return null;
                    return (
                      <div className="rounded-xl border border-gray-100 bg-gray-50/40 overflow-hidden">
                        <button
                          onClick={() => setOtherOpen((v) => !v)}
                          className="w-full flex items-center justify-between px-3 py-2.5 bg-white hover:bg-gray-50 transition-colors text-left"
                        >
                          <span className="flex items-center gap-2">
                            <ChevronRight className={`h-3.5 w-3.5 text-gray-400 transition-transform duration-150 ${otherOpen ? "rotate-90" : ""}`} />
                            <span className="text-[10px] font-semibold uppercase tracking-wide text-gray-500">Other</span>
                          </span>
                          <span className="text-[10px] text-gray-400">{unassigned.length} doc{unassigned.length !== 1 ? "s" : ""}</span>
                        </button>
                        {otherOpen && (
                          <div className="px-3 py-2.5 space-y-1.5 border-t border-gray-100">
                            {unassigned.map((doc) => (
                              <DocumentRow key={doc.id} doc={doc} showMeasure />
                            ))}
                          </div>
                        )}
                      </div>
                    );
                  })()}
                </div>
              ) : installDocs.length > 0 ? (
                <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>

      {/* Upload modal */}
      {canUpload && uploadOpen && deal && portfolioId && (
        <ContractorUploadModal
          deal={deal}
          portfolioId={portfolioId}
          onClose={() => setUploadOpen(false)}
          docStatusMap={docStatusMap}
          approvedMeasures={approvedMeasures}
        />
      )}
    </div>
  );
}
