"use client";

import { Download, FileUp, Play, Upload } from "lucide-react";
import Link from "next/link";
import { useState } from "react";

import ImportPreviewTable from "@/components/customers/ImportPreviewTable";
import ImportSummaryCard from "@/components/customers/ImportSummaryCard";
import { Button, buttonVariants } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Label } from "@/components/ui/label";
import { api } from "@/lib/api";
import type {
  CustomerImportCommitResponse,
  CustomerImportMode,
  CustomerImportPreviewResponse,
} from "@/types/customer";

type Props = {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onCommitted: (result: CustomerImportCommitResponse) => void;
  onError: (message: string) => void;
};

function errorMessage(error: unknown) {
  if (typeof error === "object" && error !== null && "response" in error) {
    const response = (error as { response?: { data?: { detail?: string } } }).response;
    return response?.data?.detail ?? "Import konnte nicht ausgeführt werden";
  }
  return "Import konnte nicht ausgeführt werden";
}

function buildFormData(file: File, mode: CustomerImportMode) {
  const formData = new FormData();
  formData.append("mode", mode);
  formData.append("file", file);
  return formData;
}

export default function CustomerImportDialog({ open, onOpenChange, onCommitted, onError }: Props) {
  const [file, setFile] = useState<File | null>(null);
  const [mode, setMode] = useState<CustomerImportMode>("upsert");
  const [preview, setPreview] = useState<CustomerImportPreviewResponse | null>(null);
  const [pending, setPending] = useState(false);
  const [serverError, setServerError] = useState("");

  async function runPreview() {
    if (!file) {
      setServerError("Bitte CSV-Datei auswählen");
      return;
    }

    setPending(true);
    setServerError("");
    try {
      const response = await api.post<CustomerImportPreviewResponse>(
        "/customers/import/preview",
        buildFormData(file, mode),
      );
      setPreview(response.data);
    } catch (error) {
      const message = errorMessage(error);
      setServerError(message);
      onError(message);
    } finally {
      setPending(false);
    }
  }

  async function commitImport() {
    if (!file || !preview || preview.summary.valid_rows === 0) {
      return;
    }

    setPending(true);
    setServerError("");
    try {
      const response = await api.post<CustomerImportCommitResponse>(
        "/customers/import/commit",
        buildFormData(file, mode),
      );
      onCommitted(response.data);
      setPreview(null);
      setFile(null);
      onOpenChange(false);
    } catch (error) {
      const message = errorMessage(error);
      setServerError(message);
      onError(message);
    } finally {
      setPending(false);
    }
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-5xl">
        <DialogHeader>
          <DialogTitle>Kunden importieren</DialogTitle>
          <DialogDescription>CSV-Datei prüfen und anschließend gültige Zeilen übernehmen.</DialogDescription>
        </DialogHeader>

        <div className="grid gap-4">
          <div className="grid gap-4 lg:grid-cols-[1fr_14rem_auto] lg:items-end">
            <div className="grid gap-2">
              <Label htmlFor="customer-import-file">CSV-Datei</Label>
              <input
                id="customer-import-file"
                type="file"
                accept=".csv,text/csv"
                className="h-10 rounded-lg border border-input bg-white px-3 py-2 text-sm"
                onChange={(event) => {
                  setFile(event.target.files?.[0] ?? null);
                  setPreview(null);
                  setServerError("");
                }}
              />
            </div>

            <div className="grid gap-2">
              <Label htmlFor="customer-import-mode">Importmodus</Label>
              <select
                id="customer-import-mode"
                value={mode}
                className="h-10 rounded-lg border border-input bg-white px-3 text-sm"
                onChange={(event) => {
                  setMode(event.target.value as CustomerImportMode);
                  setPreview(null);
                }}
              >
                <option value="upsert">Upsert</option>
                <option value="create_only">Nur erstellen</option>
                <option value="update_existing">Bestehende aktualisieren</option>
              </select>
            </div>

            <Link href="/api/customers/import/template" className={buttonVariants({ variant: "outline", size: "default" })}>
                <Download size={16} />
                Vorlage
            </Link>
          </div>

          {serverError && <p className="rounded-lg bg-red-50 p-3 text-sm text-red-700">{serverError}</p>}

          {preview && (
            <div className="grid gap-4">
              <ImportSummaryCard summary={preview.summary} />
              <ImportPreviewTable rows={preview.rows} />
            </div>
          )}
        </div>

        <DialogFooter>
          <Button type="button" variant="outline" onClick={() => onOpenChange(false)} disabled={pending}>
            Schließen
          </Button>
          <Button type="button" variant="outline" onClick={runPreview} disabled={pending || !file}>
            <Play size={16} />
            Preview starten
          </Button>
          <Button type="button" onClick={commitImport} disabled={pending || !preview || preview.summary.valid_rows === 0}>
            {pending ? <FileUp size={16} /> : <Upload size={16} />}
            Import übernehmen
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
