"use client";

import { useRef, useState, useTransition } from "react";
import { useRouter } from "next/navigation";
import type { ChangeEvent } from "react";

type ImportSummary = {
  created: number;
  updated: number;
  skipped: number;
  errors: Array<{
    row: number;
    message: string;
    identifier?: string;
  }>;
};

type BulkImportPanelProps = {
  title: string;
  description: string;
  endpoint: string;
  sampleCsv: string;
  sampleJson: string;
  defaultPayload?: Record<string, unknown>;
};

export function BulkImportPanel({
  title,
  description,
  endpoint,
  sampleCsv,
  sampleJson,
  defaultPayload,
}: BulkImportPanelProps) {
  const router = useRouter();
  const fileInputRef = useRef<HTMLInputElement | null>(null);
  const [format, setFormat] = useState<"csv" | "json">("csv");
  const [content, setContent] = useState("");
  const [filename, setFilename] = useState("");
  const [message, setMessage] = useState<string | null>(null);
  const [summary, setSummary] = useState<ImportSummary | null>(null);
  const [isPending, startTransition] = useTransition();

  function fillTemplate(nextFormat: "csv" | "json") {
    setFormat(nextFormat);
    setContent(nextFormat === "csv" ? sampleCsv : sampleJson);
    setFilename("");
    setSummary(null);
    setMessage(null);
  }

  async function handleFileChange(event: ChangeEvent<HTMLInputElement>) {
    const file = event.target.files?.[0];

    if (!file) {
      return;
    }

    const nextContent = await file.text();
    setContent(nextContent);
    setFilename(file.name);
    setSummary(null);
    setMessage(null);

    if (file.name.toLowerCase().endsWith(".json")) {
      setFormat("json");
    } else {
      setFormat("csv");
    }
  }

  function handleImport() {
    startTransition(async () => {
      try {
        const response = await fetch(endpoint, {
          method: "POST",
          headers: {
            "content-type": "application/json",
          },
          body: JSON.stringify({
            content,
            format,
            filename,
            ...defaultPayload,
          }),
        });

        const payload = (await response.json()) as {
          summary?: ImportSummary;
          message?: string;
        };

        if (!response.ok) {
          throw new Error(payload.message || "Import nije uspeo.");
        }

        setSummary(payload.summary ?? null);
        setMessage(
          payload.summary
            ? `Import je završen: kreirano ${payload.summary.created}, ažurirano ${payload.summary.updated}, preskočeno ${payload.summary.skipped}.`
            : "Import je završen.",
        );
        router.refresh();
      } catch (error) {
        setSummary(null);
        setMessage(error instanceof Error ? error.message : "Import nije uspeo.");
      }
    });
  }

  return (
    <div className="admin-toolbar rounded-[1.75rem] p-5">
      <div className="flex flex-col gap-3 xl:flex-row xl:items-start xl:justify-between">
        <div className="max-w-3xl">
          <div className="flex flex-wrap items-baseline gap-x-3 gap-y-1">
            <h3 className="text-lg font-semibold text-foreground">{title}</h3>
            <span className="text-[0.62rem] font-bold uppercase tracking-[0.18em] text-muted-foreground">
              Bulk import
            </span>
          </div>
          <p className="mt-1.5 text-sm leading-6 text-muted-foreground">{description}</p>
        </div>
        <div className="flex flex-wrap gap-2">
          <button
            type="button"
            onClick={() => fillTemplate("csv")}
            className="ghost-button !min-h-0 px-4 py-2.5 text-sm"
          >
            CSV template
          </button>
          <button
            type="button"
            onClick={() => fillTemplate("json")}
            className="ghost-button !min-h-0 px-4 py-2.5 text-sm"
          >
            JSON template
          </button>
          <button
            type="button"
            onClick={() => fileInputRef.current?.click()}
            className="ghost-button !min-h-0 px-4 py-2.5 text-sm"
          >
            Ucitaj fajl
          </button>
        </div>
      </div>

      <div className="mt-5 flex flex-wrap gap-3">
        <button
          type="button"
          onClick={() => setFormat("csv")}
          className="inline-toggle"
          data-active={format === "csv"}
          data-tone="neutral"
        >
          CSV
        </button>
        <button
          type="button"
          onClick={() => setFormat("json")}
          className="inline-toggle"
          data-active={format === "json"}
          data-tone="neutral"
        >
          JSON
        </button>
        {filename ? <span className="admin-chip">Fajl: {filename}</span> : null}
        <span className="admin-chip">Upsert po slug-u</span>
      </div>

      <input
        ref={fileInputRef}
        type="file"
        accept=".csv,.tsv,.json,text/csv,application/json"
        className="hidden"
        onChange={handleFileChange}
      />

      <label className="field-shell mt-5">
        <span className="field-label">Sadrzaj importa</span>
        <textarea
          value={content}
          onChange={(event) => {
            setContent(event.target.value);
            setSummary(null);
            setMessage(null);
          }}
          aria-label={`Sadržaj importa za ${title}`}
          className="input-premium min-h-56 resize-y font-mono text-sm"
          placeholder={
            format === "csv"
              ? "Paste CSV sa header kolonama ili ucitaj .csv fajl."
              : "Paste JSON niz objekata ili ucitaj .json fajl."
          }
        />
        <span className="field-hint">
          Sistem cita CSV/TSV/JSON, normalizuje kolone i radi create/update bez ulaska u pojedinacne detalje.
        </span>
      </label>

      {message ? (
        <div className="mt-4 rounded-[1.25rem] border border-border bg-white/80 px-4 py-4 text-sm text-muted-foreground">
          {message}
        </div>
      ) : null}

      {summary ? (
        <div className="mt-4 grid gap-3 lg:grid-cols-[repeat(3,minmax(0,1fr))]">
          <div className="rounded-[1.35rem] border border-border bg-white/85 px-4 py-4">
            <div className="text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground">
              Kreirano
            </div>
            <div className="mt-2 text-3xl font-semibold text-foreground">{summary.created}</div>
          </div>
          <div className="rounded-[1.35rem] border border-border bg-white/85 px-4 py-4">
            <div className="text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground">
              Azurirano
            </div>
            <div className="mt-2 text-3xl font-semibold text-foreground">{summary.updated}</div>
          </div>
          <div className="rounded-[1.35rem] border border-border bg-white/85 px-4 py-4">
            <div className="text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground">
              Preskoceno
            </div>
            <div className="mt-2 text-3xl font-semibold text-foreground">{summary.skipped}</div>
          </div>
        </div>
      ) : null}

      {summary?.errors.length ? (
        <div className="mt-4 rounded-[1.5rem] border border-danger/15 bg-danger/5 px-4 py-4">
          <div className="text-sm font-semibold text-danger">Redovi sa greskom</div>
          <div className="mt-3 space-y-2 text-sm text-muted-foreground">
            {summary.errors.slice(0, 8).map((error) => (
              <div key={`${error.row}-${error.identifier ?? error.message}`}>
                Red {error.row}
                {error.identifier ? ` (${error.identifier})` : ""}: {error.message}
              </div>
            ))}
            {summary.errors.length > 8 ? (
              <div>Prikazano je prvih 8 gresaka od ukupno {summary.errors.length}.</div>
            ) : null}
          </div>
        </div>
      ) : null}

      <div className="mt-5 flex flex-wrap items-center justify-between gap-3">
        <div className="text-sm text-muted-foreground">
          Preporuka: prvo popuni template, pa zatim ubaci stvarni CSV/JSON sa istim kolonama.
        </div>
        <button
          type="button"
          onClick={handleImport}
          disabled={isPending || content.trim().length === 0}
          className="primary-button"
        >
          {isPending ? "Obrada importa..." : "Pokreni import"}
        </button>
      </div>
    </div>
  );
}
