"use client";

import { useMemo, useState } from "react";
import {
  useReactTable,
  getCoreRowModel,
  getFilteredRowModel,
  getSortedRowModel,
  getPaginationRowModel,
  flexRender,
  type SortingState,
  type PaginationState,
} from "@tanstack/react-table";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/app/shadcn_components/ui/table";
import { Input } from "@/app/shadcn_components/ui/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
} from "@/app/shadcn_components/ui/select";
import { Search, ChevronLeft, ChevronRight, Download } from "lucide-react";
import { createDocumentTableColumns } from "./DocumentTableColumns";
import ContractorUploadModal from "./ContractorUploadModal";
import type { ClassifiedDeal, DocStatusMap, PortfolioCapabilityType, ApprovalsByDeal } from "./types";

type RetroAssessmentFilter = "all" | "none" | "partial" | "complete";
type InstallStatusFilter = "all" | "none" | "hasDocs" | "partial" | "complete";

interface DocumentTableProps {
  data: ClassifiedDeal[];
  onOpenDrawer: (dealId: string, uprn: string | null, landlordPropertyId: string | null, dealname: string | null) => void;
  docStatusMap: DocStatusMap;
  portfolioId: string;
  userCapability: PortfolioCapabilityType;
  approvalsByDeal?: ApprovalsByDeal;
}

function escapeCell(value: unknown): string {
  if (value === null || value === undefined) return "";
  const str =
    value instanceof Date
      ? value.toLocaleDateString("en-GB")
      : String(value);
  return str.includes(",") || str.includes('"') || str.includes("\n")
    ? `"${str.replace(/"/g, '""')}"`
    : str;
}

export default function DocumentTable({ data, onOpenDrawer, docStatusMap, portfolioId, userCapability, approvalsByDeal }: DocumentTableProps) {
  const [globalFilter, setGlobalFilter] = useState("");
  const [retroAssessmentFilter, setRetroAssessmentFilter] = useState<RetroAssessmentFilter>("all");
  const [installStatusFilter, setInstallStatusFilter] = useState<InstallStatusFilter>("all");
  const [sorting, setSorting] = useState<SortingState>([]);
  const [pagination, setPagination] = useState<PaginationState>({
    pageIndex: 0,
    pageSize: 25,
  });
  const [uploadDeal, setUploadDeal] = useState<ClassifiedDeal | null>(null);

  const filteredData = useMemo(() => {
    return data.filter((d) => {
      const status = docStatusMap[d.dealId];

      if (retroAssessmentFilter !== "all") {
        if (retroAssessmentFilter === "none" && !(!status || !status.hasSurveyDocs)) return false;
        if (retroAssessmentFilter === "partial" && !(status?.hasSurveyDocs && !status.isSurveyComplete)) return false;
        if (retroAssessmentFilter === "complete" && !status?.isSurveyComplete) return false;
      }

      if (installStatusFilter !== "all") {
        const s = status?.installStatus ?? "none";
        if (installStatusFilter === "none" && s !== "none") return false;
        if (installStatusFilter === "hasDocs" && s !== "hasDocs") return false;
        if (installStatusFilter === "partial" && s !== "partial") return false;
        if (installStatusFilter === "complete" && s !== "all") return false;
      }

      return true;
    });
  }, [data, retroAssessmentFilter, installStatusFilter, docStatusMap]);

  const columns = useMemo(
    () => createDocumentTableColumns(
      onOpenDrawer,
      docStatusMap,
      userCapability.includes("contractor") ? setUploadDeal : undefined,
    ),
    [onOpenDrawer, docStatusMap, userCapability],
  );

  const table = useReactTable({
    data: filteredData,
    columns,
    state: { globalFilter, sorting, pagination },
    onGlobalFilterChange: setGlobalFilter,
    onSortingChange: setSorting,
    onPaginationChange: setPagination,
    getCoreRowModel: getCoreRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    globalFilterFn: "includesString",
  });

  const downloadCsv = () => {
    const rows = table.getFilteredRowModel().rows;
    const header = "Address,Landlord ID,Retrofit Assessment Status,Install Docs Status";
    const body = rows
      .map((row) => {
        const status = docStatusMap[row.original.dealId];
        const retroStatus = status?.isSurveyComplete
          ? "Complete"
          : status?.hasSurveyDocs
            ? "Partial"
            : "No Docs";
        const installStatusMap: Record<string, string> = {
          all: "All Measures",
          partial: "Some Measures",
          hasDocs: "Has Docs",
          none: "No Docs",
        };
        const installStatus = installStatusMap[status?.installStatus ?? "none"];
        return [
          escapeCell(row.original.dealname),
          escapeCell(row.original.landlordPropertyId),
          retroStatus,
          installStatus,
        ].join(",");
      })
      .join("\n");
    const blob = new Blob([header + "\n" + body], { type: "text/csv;charset=utf-8;" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = "document-management.csv";
    a.click();
    URL.revokeObjectURL(url);
  };

  const pageCount = table.getPageCount();
  const currentPage = table.getState().pagination.pageIndex + 1;
  const totalFiltered = table.getFilteredRowModel().rows.length;

  const retroAssessmentLabel: Record<RetroAssessmentFilter, string> = {
    all: "All retrofit statuses",
    none: "No Retrofit Docs",
    partial: "Partial Retrofit Docs",
    complete: "Complete Retrofit Docs",
  };

  const installStatusLabel: Record<InstallStatusFilter, string> = {
    all: "All install statuses",
    none: "No Install Docs",
    hasDocs: "Has Install Docs",
    partial: "Some Measures",
    complete: "All Measures",
  };

  return (
    <div className="space-y-3">
      {/* Toolbar */}
      <div className="flex flex-col sm:flex-row gap-3 items-start sm:items-center">
        {/* Search */}
        <div className="relative flex-1 min-w-0">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400 pointer-events-none" />
          <Input
            value={globalFilter}
            onChange={(e) => {
              setGlobalFilter(e.target.value);
              setPagination((p) => ({ ...p, pageIndex: 0 }));
            }}
            placeholder="Search address, landlord ID…"
            className="pl-9 h-9 text-sm border-gray-200 focus:border-brandblue/40 focus:ring-brandblue/20"
          />
        </div>

        {/* Retrofit assessment filter */}
        <Select
          value={retroAssessmentFilter}
          onValueChange={(v) => {
            setRetroAssessmentFilter(v as RetroAssessmentFilter);
            setPagination((p) => ({ ...p, pageIndex: 0 }));
          }}
        >
          <SelectTrigger className="h-9 w-[210px] text-sm border-gray-200 shrink-0">
            {retroAssessmentLabel[retroAssessmentFilter]}
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="all">All retrofit statuses</SelectItem>
            <SelectItem value="none">No Retrofit Docs</SelectItem>
            <SelectItem value="partial">Partial Retrofit Docs</SelectItem>
            <SelectItem value="complete">Complete Retrofit Docs</SelectItem>
          </SelectContent>
        </Select>

        {/* Install docs filter */}
        <Select
          value={installStatusFilter}
          onValueChange={(v) => {
            setInstallStatusFilter(v as InstallStatusFilter);
            setPagination((p) => ({ ...p, pageIndex: 0 }));
          }}
        >
          <SelectTrigger className="h-9 w-[190px] text-sm border-gray-200 shrink-0">
            {installStatusLabel[installStatusFilter]}
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="all">All install statuses</SelectItem>
            <SelectItem value="none">No Install Docs</SelectItem>
            <SelectItem value="hasDocs">Has Install Docs</SelectItem>
            <SelectItem value="partial">Some Measures</SelectItem>
            <SelectItem value="complete">All Measures</SelectItem>
          </SelectContent>
        </Select>

        {/* Download CSV */}
        <button
          onClick={downloadCsv}
          className="inline-flex items-center gap-2 h-9 px-3 rounded-lg border border-gray-200 bg-white text-sm font-medium text-gray-600 hover:border-brandblue/30 hover:text-brandblue transition-colors shrink-0"
        >
          <Download className="h-3.5 w-3.5" />
          CSV
        </button>
      </div>

      {/* Result count */}
      <p className="text-xs text-gray-400">
        Showing{" "}
        <span className="font-semibold text-gray-600">
          {Math.min(
            table.getState().pagination.pageSize,
            totalFiltered - table.getState().pagination.pageIndex * table.getState().pagination.pageSize,
          )}
        </span>{" "}
        of{" "}
        <span className="font-semibold text-gray-600">{totalFiltered}</span>{" "}
        {(retroAssessmentFilter !== "all" || installStatusFilter !== "all") ? "(filtered) " : ""}
        propert{totalFiltered === 1 ? "y" : "ies"}
      </p>

      {/* Table */}
      <div className="rounded-xl border border-gray-200 overflow-hidden shadow-sm">
        <div className="overflow-x-auto">
          <Table>
            <TableHeader>
              {table.getHeaderGroups().map((headerGroup) => (
                <TableRow
                  key={headerGroup.id}
                  className="bg-gray-50/80 hover:bg-gray-50/80 border-b border-gray-200"
                >
                  {headerGroup.headers.map((header) => (
                    <TableHead key={header.id} className="h-10 px-4 first:pl-5 last:pr-5">
                      {header.isPlaceholder
                        ? null
                        : flexRender(header.column.columnDef.header, header.getContext())}
                    </TableHead>
                  ))}
                </TableRow>
              ))}
            </TableHeader>
            <TableBody>
              {table.getRowModel().rows.length ? (
                table.getRowModel().rows.map((row, i) => (
                  <TableRow
                    key={row.id}
                    className={`border-b border-gray-100 transition-colors hover:bg-brandlightblue/10 ${
                      i % 2 === 0 ? "bg-white" : "bg-gray-50/30"
                    }`}
                  >
                    {row.getVisibleCells().map((cell) => (
                      <TableCell key={cell.id} className="py-3 px-4 first:pl-5 last:pr-5">
                        {flexRender(cell.column.columnDef.cell, cell.getContext())}
                      </TableCell>
                    ))}
                  </TableRow>
                ))
              ) : (
                <TableRow>
                  <TableCell
                    colSpan={columns.length}
                    className="h-32 text-center text-sm text-gray-400"
                  >
                    No properties match the current filters.
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
        </div>
      </div>

      {/* Contractor upload modal */}
      {uploadDeal && (
        <ContractorUploadModal
          deal={uploadDeal}
          portfolioId={portfolioId}
          onClose={() => setUploadDeal(null)}
          docStatusMap={docStatusMap}
          approvedMeasures={approvalsByDeal?.[uploadDeal.dealId] ?? []}
        />
      )}

      {/* Pagination */}
      {pageCount > 1 && (
        <div className="flex items-center justify-between pt-1">
          <div className="flex items-center gap-2">
            <span className="text-xs text-gray-500">Rows per page:</span>
            <Select
              value={String(table.getState().pagination.pageSize)}
              onValueChange={(v) => table.setPageSize(Number(v))}
            >
              <SelectTrigger className="h-7 w-16 text-xs border-gray-200">
                {table.getState().pagination.pageSize}
              </SelectTrigger>
              <SelectContent>
                {[10, 25, 50, 100].map((n) => (
                  <SelectItem key={n} value={String(n)} className="text-xs">
                    {n}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          <div className="flex items-center gap-3">
            <span className="text-xs text-gray-500">
              Page {currentPage} of {pageCount}
            </span>
            <div className="flex gap-1">
              <button
                onClick={() => table.previousPage()}
                disabled={!table.getCanPreviousPage()}
                className="h-7 w-7 flex items-center justify-center rounded-lg border border-gray-200 text-gray-500 hover:border-brandblue/30 hover:text-brandblue disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
              >
                <ChevronLeft className="h-3.5 w-3.5" />
              </button>
              <button
                onClick={() => table.nextPage()}
                disabled={!table.getCanNextPage()}
                className="h-7 w-7 flex items-center justify-center rounded-lg border border-gray-200 text-gray-500 hover:border-brandblue/30 hover:text-brandblue disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
              >
                <ChevronRight className="h-3.5 w-3.5" />
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
