"use client";

import * as React from "react";
import dynamic from "next/dynamic";
import Link from "next/link";
import { useSearchParams } from "next/navigation";
import { useSession } from "next-auth/react";
import { ChevronLeft } from "lucide-react";
import { toast } from "sonner";

import { useGetProfileQuery } from "@/api/endpoints/auth-api";
import { useAuthToken } from "@/hooks/use-auth-token";
import { useExcelEditorFileIo } from "@/hooks/use-excel-editor-file-io";
import {
  clearExcelEditorDraft,
  writeExcelEditorDraft,
} from "@/lib/excel-editor-draft-storage";
import { hasPermission } from "@/lib/permissions";
import { Button } from "@/components/ui/button";
import { Loading } from "@/components/ui/loading";
import { ExcelEditorForbidden } from "@/components/excel-editor/excel-editor-forbidden";
import { ExcelEditorToolbar } from "@/components/excel-editor/excel-editor-toolbar";
import {
  createDefaultWorkbookPayloads,
  ensureRevenuePayload,
  parsedRowsToGridData,
  replaceRevenueWithFreshTemplate,
} from "@/components/excel-editor/excel-grid-adapters";
import type { ImportSampleSheetPayload } from "@/workers/import-sample-export.worker";
import type { ExcelSpreadsheetHandle } from "@/components/excel-editor/excel-spreadsheet";

const ExcelSpreadsheet = dynamic(
  () =>
    import("@/components/excel-editor/excel-spreadsheet").then(
      (mod) => mod.ExcelSpreadsheet,
    ),
  {
    ssr: false,
    loading: () => (
      <div className="flex-1 min-h-[320px] animate-pulse rounded-xl border border-gray-200 bg-gray-50" />
    ),
  },
);

const BLANK_WORKBOOK: ImportSampleSheetPayload[] = createDefaultWorkbookPayloads();

const DRAFT_AUTOSAVE_MS = 1200;

export function ExcelEditorPage() {
  const searchParams = useSearchParams();
  const { data: session } = useSession();
  const { token } = useAuthToken();
  const { data: profile } = useGetProfileQuery(undefined, { skip: !token });
  const spreadsheetRef = React.useRef<ExcelSpreadsheetHandle>(null);
  const exportFilenameRef = React.useRef("spreadsheet.xlsx");
  const [workbookInstanceKey, setWorkbookInstanceKey] = React.useState(0);
  const [workbookSheets, setWorkbookSheets] =
    React.useState<ImportSampleSheetPayload[] | null>(null);
  const [isDirty, setIsDirty] = React.useState(false);
  const [exportFilename, setExportFilename] = React.useState("spreadsheet.xlsx");
  const { parseFile, downloadSheets, isParsing, isExporting } =
    useExcelEditorFileIo();

  const permissionSource = React.useMemo(
    () =>
      (session as { backendUser?: unknown } | null)?.backendUser ?? profile,
    [session, profile],
  );

  const canUseExcelEditor = React.useMemo(
    () => hasPermission(permissionSource, "CREATE", "EXCEL_IMPORT"),
    [permissionSource],
  );

  const backHref = searchParams.get("from") === "leads" ? "/leads" : "/leads";

  React.useEffect(() => {
    exportFilenameRef.current = exportFilename;
  }, [exportFilename]);

  React.useEffect(() => {
    if (!canUseExcelEditor) return;

    let cancelled = false;

    void (async () => {
      await clearExcelEditorDraft();

      if (cancelled) return;

      setWorkbookSheets(BLANK_WORKBOOK);
      setWorkbookInstanceKey((key) => key + 1);
    })();

    return () => {
      cancelled = true;
    };
  }, [canUseExcelEditor]);

  const persistDraft = React.useCallback(async () => {
    const sheets = spreadsheetRef.current?.getExportSheets();
    if (!sheets?.length) return;

    try {
      await writeExcelEditorDraft({
        sheets: replaceRevenueWithFreshTemplate(sheets),
        exportFilename: exportFilenameRef.current,
      });
    } catch {
      /* quota / private mode */
    }
  }, []);

  React.useEffect(() => {
    if (!canUseExcelEditor || workbookSheets == null) return;

    const saveDraft = () => {
      void persistDraft();
    };

    window.addEventListener("beforeunload", saveDraft);
    return () => {
      saveDraft();
      window.removeEventListener("beforeunload", saveDraft);
    };
  }, [canUseExcelEditor, persistDraft, workbookSheets]);

  React.useEffect(() => {
    if (!canUseExcelEditor || !isDirty || workbookSheets == null) return;

    const timer = window.setTimeout(() => {
      void persistDraft();
    }, DRAFT_AUTOSAVE_MS);

    return () => window.clearTimeout(timer);
  }, [canUseExcelEditor, isDirty, persistDraft, workbookSheets]);

  const handleNew = () => {
    setWorkbookSheets(createDefaultWorkbookPayloads());
    setWorkbookInstanceKey((key) => key + 1);
    setExportFilename("spreadsheet.xlsx");
    setIsDirty(false);
    void clearExcelEditorDraft();
    toast.success("Started a new spreadsheet");
  };

  const handleOpenFile = async (file: File) => {
    try {
      const parsed = await parseFile(file);
      const gridData = parsedRowsToGridData(parsed);
      setWorkbookSheets(
        ensureRevenuePayload([
          { name: "Sheet1", rows: gridData },
        ]),
      );
      setWorkbookInstanceKey((key) => key + 1);
      const nextFilename =
        file.name.replace(/\.(xlsx|xls|csv)$/i, "") + ".xlsx";
      setExportFilename(nextFilename);
      setIsDirty(true);
      toast.success(`Opened ${file.name}`);
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Failed to open file");
    }
  };

  const handleAddSheet = () => {
    spreadsheetRef.current?.addSheet();
    setIsDirty(true);
    toast.success("Added a new worksheet");
  };

  const handleExport = async () => {
    try {
      const sheets =
        spreadsheetRef.current?.getExportSheets() ?? BLANK_WORKBOOK;
      await downloadSheets(sheets, exportFilename);
      toast.success("Spreadsheet exported");
    } catch {
      /* toast handled in hook */
    }
  };

  if (!canUseExcelEditor) {
    return <ExcelEditorForbidden />;
  }

  if (workbookSheets == null) {
    return (
      <div className="flex h-full min-h-[320px] items-center justify-center">
        <Loading layout="section" message="Loading Excel Editor..." />
      </div>
    );
  }

  return (
    <div className="flex h-full min-h-0 min-w-0 flex-col gap-3">
      <div className="flex flex-wrap items-center justify-between gap-3">
        <div className="flex min-w-0 items-center gap-3">
          <Link href={backHref}>
            <Button size="sm" variant="outline" className="h-10 gap-1.5">
              <ChevronLeft size={14} />
              Back to Leads
            </Button>
          </Link>
          <div className="min-w-0">
            <h1 className="text-[20px] font-extrabold font-['Lexend'] text-text leading-tight">
              Excel Editor
            </h1>
            <p className="text-[12px] text-gray-500 font-['Lexend_Deca']">
              Excel-style editor with formulas and formatting. The Revenue sheet
              loads fresh from sales targets on each visit (no cached demo data).
            </p>
          </div>
        </div>
        {isDirty ? (
          <span className="inline-flex items-center gap-1.5 text-[12px] font-medium text-amber-600">
            <span className="size-2 rounded-full bg-amber-500" />
            Unsaved changes
          </span>
        ) : null}
      </div>

      <ExcelEditorToolbar
        onNew={handleNew}
        onAddSheet={handleAddSheet}
        onOpenFile={handleOpenFile}
        onExport={handleExport}
        isParsing={isParsing}
        isExporting={isExporting}
      />

      <div className="flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden rounded-xl border border-gray-200 bg-white shadow-sm">
        <ExcelSpreadsheet
          key={workbookInstanceKey}
          ref={spreadsheetRef}
          initialSheets={workbookSheets}
          onDirty={() => setIsDirty(true)}
        />
      </div>
    </div>
  );
}
