"use client";

import * as React from "react";
import { useDropzone } from "react-dropzone";
import { Download, Loader2, Upload } from "lucide-react";
import { toast } from "sonner";

import {
  useImportUsersMutation,
  useLazyGetUsersImportSampleQuery,
} from "@/api/endpoints/users-api";
import type { UserImportGeneratedCredential, UserImportResult } from "@/api/users/types";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { downloadBlob } from "@/lib/download-blob";
import { cn } from "@/lib/utils";

const IMPORT_ACCEPT = {
  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": [
    ".xlsx",
  ],
  "application/vnd.ms-excel": [".xls"],
} as const;

type UserImportDialogProps = {
  open: boolean;
  onOpenChange: (open: boolean) => void;
};

function downloadCredentialsCsv(
  credentials: UserImportGeneratedCredential[],
): void {
  const escapeCsv = (value: string) => `"${value.replace(/"/g, '""')}"`;
  const lines = [
    "Email,Password",
    ...credentials.map(
      (row) => `${escapeCsv(row.email)},${escapeCsv(row.password)}`,
    ),
  ];
  const blob = new Blob([lines.join("\n")], {
    type: "text/csv;charset=utf-8",
  });
  downloadBlob(blob, "imported-user-credentials.csv", "text/csv");
}

export function UserImportDialog({
  open,
  onOpenChange,
}: UserImportDialogProps) {
  const [selectedFile, setSelectedFile] = React.useState<File | null>(null);
  const [importResult, setImportResult] = React.useState<UserImportResult | null>(
    null,
  );

  const [fetchSample, { isFetching: isDownloadingSample }] =
    useLazyGetUsersImportSampleQuery();
  const [importUsers, { isLoading: isImporting }] = useImportUsersMutation();

  const resetState = React.useCallback(() => {
    setSelectedFile(null);
    setImportResult(null);
  }, []);

  const handleOpenChange = (nextOpen: boolean) => {
    if (!nextOpen) {
      resetState();
    }
    onOpenChange(nextOpen);
  };

  const { getRootProps, getInputProps, isDragActive } = useDropzone({
    onDrop: (acceptedFiles) => {
      const file = acceptedFiles[0];
      if (file) {
        setSelectedFile(file);
        setImportResult(null);
      }
    },
    accept: IMPORT_ACCEPT,
    multiple: false,
    disabled: isImporting,
  });

  const handleDownloadSample = async () => {
    try {
      const blob = await fetchSample().unwrap();
      downloadBlob(
        blob,
        "users-import-sample.xlsx",
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
      );
    } catch (error) {
      const message =
        error instanceof Error ? error.message : "Failed to download sample";
      toast.error(message);
    }
  };

  const handleImport = async () => {
    if (!selectedFile) {
      toast.error("Select an Excel file to import");
      return;
    }

    const formData = new FormData();
    formData.append("file", selectedFile);

    try {
      const result = await importUsers(formData).unwrap();
      setImportResult(result);

      if (result.success > 0 && result.failed === 0) {
        toast.success(`Imported ${result.success} user(s)`);
      } else if (result.success > 0) {
        toast.warning(
          `Imported ${result.success} user(s); ${result.failed} row(s) failed`,
        );
      } else {
        toast.error("Import failed — check row errors below");
      }
    } catch (error) {
      const message =
        error instanceof Error ? error.message : "User import failed";
      toast.error(message);
    }
  };

  const generatedCredentials = importResult?.generatedCredentials ?? [];

  return (
    <Dialog open={open} onOpenChange={handleOpenChange}>
      <DialogContent className="max-w-lg">
        <DialogHeader>
          <DialogTitle>Import users</DialogTitle>
        </DialogHeader>

        <div className="space-y-4 text-sm text-[#475467]">
          <p>
            Upload an Excel file with columns{" "}
            <strong className="text-[#101828]">
              Name, Email, Role, Division, Team
            </strong>
            . Password is optional — when omitted, each user gets an auto-generated
            password in the format <strong className="text-[#101828]">Name123+</strong>{" "}
            (e.g. John Doe → JohnDoe123+, no spaces).
          </p>
          <p>
            The workbook includes a <strong className="text-[#101828]">Reference</strong>{' '}
            sheet with your organization&apos;s current roles, divisions, and teams.
            Division and team names must match that catalog (case-insensitive).
          </p>

          <Button
            type="button"
            variant="outline"
            size="sm"
            className="gap-2"
            onClick={() => void handleDownloadSample()}
            disabled={isDownloadingSample || isImporting}
          >
            {isDownloadingSample ? (
              <Loader2 className="size-4 animate-spin" />
            ) : (
              <Download className="size-4" />
            )}
            Download sample template
          </Button>

          <div
            {...getRootProps()}
            className={cn(
              "flex min-h-[120px] cursor-pointer flex-col items-center justify-center gap-2 rounded-xl border border-dashed border-[#b9c7d0] bg-[#f8fafc] px-4 py-6 text-center transition-colors",
              isDragActive && "border-accent bg-accent/5",
              isImporting && "pointer-events-none opacity-60",
            )}
          >
            <input {...getInputProps()} />
            <Upload className="size-5 text-[#575a62]" />
            <p className="text-[13px] font-medium text-[#101828]">
              {selectedFile
                ? selectedFile.name
                : "Drop .xlsx here or click to browse"}
            </p>
            <p className="text-xs text-[#667085]">One worksheet, header row required</p>
          </div>

          {importResult ? (
            <div className="space-y-3 rounded-xl border border-[#e4e7ec] bg-white p-4">
              <div className="flex flex-wrap gap-4 text-[13px] font-medium text-[#101828]">
                <span>Total: {importResult.total}</span>
                <span className="text-emerald-700">Success: {importResult.success}</span>
                <span className="text-red-600">Failed: {importResult.failed}</span>
              </div>

              {importResult.errors.length > 0 ? (
                <div className="max-h-40 overflow-y-auto rounded-lg bg-[#f9fafb] p-3 text-xs text-red-700">
                  {importResult.errors.map((error) => (
                    <p key={error}>{error}</p>
                  ))}
                </div>
              ) : null}

              {generatedCredentials.length > 0 ? (
                <Button
                  type="button"
                  variant="outline"
                  size="sm"
                  className="gap-2"
                  onClick={() => downloadCredentialsCsv(generatedCredentials)}
                >
                  <Download className="size-4" />
                  Download generated credentials (CSV)
                </Button>
              ) : null}
            </div>
          ) : null}
        </div>

        <DialogFooter>
          <Button
            type="button"
            variant="outline"
            onClick={() => handleOpenChange(false)}
            disabled={isImporting}
          >
            {importResult ? "Close" : "Cancel"}
          </Button>
          {!importResult ? (
            <Button
              type="button"
              onClick={handleImport}
              disabled={!selectedFile || isImporting}
            >
              {isImporting ? (
                <>
                  <Loader2 className="size-4 animate-spin" />
                  Importing…
                </>
              ) : (
                "Import users"
              )}
            </Button>
          ) : null}
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
