"use client";

import { useState, Fragment } from "react";
import { useRouter } from "next/navigation";
import { useTranslations } from "next-intl";
import { Card, CardHeader } from "@/components/ui/card";
import type { InvoiceDraft } from "@/types";

interface OrgEntry {
  zitadelOrgId: string;
  tenantNames: string[];
  companyName: string | null;
  country: string | null;
  hasBillingAddress: boolean;
}

interface Props {
  orgs: OrgEntry[];
}

const LOCALE_OPTIONS = [
  { value: "de", label: "Deutsch" },
  { value: "en", label: "English" },
  { value: "fr", label: "Français" },
  { value: "it", label: "Italiano" },
];

/**
 * Two-step flow: preview (dryRun) → commit.
 *
 * Preview displays the InvoiceDraft (lines, subtotal, VAT, total)
 * plus any warnings. Admin reviews and either commits or aborts.
 * Commit re-runs the generator without dryRun and redirects to the
 * persisted invoice's detail page.
 */
export function GenerateForm({ orgs }: Props) {
  const t = useTranslations("adminBilling");
  const router = useRouter();

  // Default to previous calendar month — that's the typical "bill
  // for last month" use case.
  const now = new Date();
  const prevMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1);
  const [orgId, setOrgId] = useState(orgs[0]?.zitadelOrgId ?? "");
  const [year, setYear] = useState(String(prevMonth.getFullYear()));
  const [month, setMonth] = useState(String(prevMonth.getMonth() + 1));
  const [locale, setLocale] = useState<string>("");
  const [draft, setDraft] = useState<InvoiceDraft | null>(null);
  const [error, setError] = useState("");
  const [busy, setBusy] = useState(false);

  const selectedOrg = orgs.find((o) => o.zitadelOrgId === orgId);
  // Auto-detect default locale from country if admin hasn't picked
  // one. Same logic as billing.ts's defaultLocaleForCountry.
  const effectiveLocale =
    locale ||
    (() => {
      const c = (selectedOrg?.country || "").toUpperCase();
      if (["CH", "LI", "AT", "DE"].includes(c)) return "de";
      if (["FR", "BE", "LU"].includes(c)) return "fr";
      if (c === "IT") return "it";
      return "en";
    })();

  const preview = async () => {
    setError("");
    setDraft(null);
    setBusy(true);
    try {
      const res = await fetch("/api/admin/billing/generate", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          zitadelOrgId: orgId,
          year: Number(year),
          month: Number(month),
          locale: effectiveLocale,
          dryRun: true,
        }),
      });
      const j = await res.json();
      if (!res.ok) throw new Error(j.error || `HTTP ${res.status}`);
      setDraft(j.draft);
    } catch (e: any) {
      setError(e.message);
    } finally {
      setBusy(false);
    }
  };

  const commit = async () => {
    if (!draft) return;
    if (!confirm(t("confirmGenerate"))) return;
    setError("");
    setBusy(true);
    try {
      const res = await fetch("/api/admin/billing/generate", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          zitadelOrgId: orgId,
          year: Number(year),
          month: Number(month),
          locale: effectiveLocale,
          dryRun: false,
        }),
      });
      const j = await res.json();
      if (!res.ok) throw new Error(j.error || `HTTP ${res.status}`);
      // Navigate to the new invoice's detail page.
      if (j.invoice?.id) {
        router.push(`/admin/billing/invoices/${j.invoice.id}`);
      }
    } catch (e: any) {
      setError(e.message);
      setBusy(false);
    }
  };

  return (
    <div className="space-y-6">
      <Card>
        <CardHeader>{t("generateFormTitle")}</CardHeader>
        {orgs.length === 0 ? (
          <p className="text-sm text-text-muted italic">{t("noOrgsToGenerate")}</p>
        ) : (
          <div className="space-y-4">
            <label className="block">
              <span className="text-sm text-text-secondary">{t("orgLabel")}</span>
              <select
                value={orgId}
                onChange={(e) => {
                  setOrgId(e.target.value);
                  setDraft(null);
                }}
                className="mt-1 w-full px-3 py-2 rounded-md border border-border bg-surface-2 text-sm"
              >
                {orgs.map((o) => (
                  <option key={o.zitadelOrgId} value={o.zitadelOrgId}>
                    {o.companyName ?? o.zitadelOrgId}
                    {!o.hasBillingAddress ? ` — ${t("noBillingAddrTag")}` : ""}
                    {` (${o.tenantNames.length} ${t("tenantsLabel")})`}
                  </option>
                ))}
              </select>
              {selectedOrg && !selectedOrg.hasBillingAddress && (
                <p className="text-xs text-error mt-1">
                  {t("noBillingAddrWarning")}
                </p>
              )}
            </label>
            <div className="grid grid-cols-3 gap-3">
              <label className="block">
                <span className="text-sm text-text-secondary">{t("yearLabel")}</span>
                <input
                  type="number"
                  min="2020"
                  max="2100"
                  value={year}
                  onChange={(e) => {
                    setYear(e.target.value);
                    setDraft(null);
                  }}
                  className="mt-1 w-full px-3 py-2 rounded-md border border-border bg-surface-2 text-sm"
                />
              </label>
              <label className="block">
                <span className="text-sm text-text-secondary">{t("monthLabel")}</span>
                <select
                  value={month}
                  onChange={(e) => {
                    setMonth(e.target.value);
                    setDraft(null);
                  }}
                  className="mt-1 w-full px-3 py-2 rounded-md border border-border bg-surface-2 text-sm"
                >
                  {Array.from({ length: 12 }, (_, i) => i + 1).map((m) => (
                    <option key={m} value={m}>
                      {String(m).padStart(2, "0")}
                    </option>
                  ))}
                </select>
              </label>
              <label className="block">
                <span className="text-sm text-text-secondary">
                  {t("localeLabel")}
                </span>
                <select
                  value={locale}
                  onChange={(e) => {
                    setLocale(e.target.value);
                    setDraft(null);
                  }}
                  className="mt-1 w-full px-3 py-2 rounded-md border border-border bg-surface-2 text-sm"
                >
                  <option value="">
                    {t("localeAuto")} ({effectiveLocale})
                  </option>
                  {LOCALE_OPTIONS.map((o) => (
                    <option key={o.value} value={o.value}>
                      {o.label}
                    </option>
                  ))}
                </select>
              </label>
            </div>
            <div className="flex items-center gap-3 pt-2">
              <button
                onClick={preview}
                disabled={busy || !selectedOrg?.hasBillingAddress}
                className="px-4 py-2 rounded-md border border-border text-sm disabled:opacity-50"
              >
                {busy && !draft ? t("computing") : t("previewBtn")}
              </button>
              {draft && (
                <button
                  onClick={commit}
                  disabled={busy}
                  className="px-4 py-2 rounded-md bg-accent text-surface-0 text-sm disabled:opacity-50"
                >
                  {busy ? t("saving") : t("commitBtn")}
                </button>
              )}
              {error && (
                <span className="text-sm text-error">{error}</span>
              )}
            </div>
          </div>
        )}
      </Card>

      {draft && <DraftPreview draft={draft} />}
    </div>
  );
}

function DraftPreview({ draft }: { draft: InvoiceDraft }) {
  const t = useTranslations("adminBilling");

  // Group lines by tenant for the preview (matches PDF layout).
  const linesByTenant = new Map<string | null, typeof draft.lines>();
  for (const ln of draft.lines) {
    const key = ln.tenantName;
    if (!linesByTenant.has(key)) linesByTenant.set(key, []);
    linesByTenant.get(key)!.push(ln);
  }
  const tenantOrder = [...linesByTenant.keys()].sort((a, b) => {
    if (a === null) return 1;
    if (b === null) return -1;
    return a.localeCompare(b);
  });

  return (
    <Card>
      <CardHeader>
        {t("previewTitle")} — {draft.periodStart} → {draft.periodEnd}
      </CardHeader>

      {draft.warnings.length > 0 && (
        <div className="mb-4 p-3 rounded-md border border-warning bg-warning/10 text-sm space-y-1">
          <div className="font-semibold text-warning">{t("warningsTitle")}</div>
          {draft.warnings.map((w, i) => (
            <div key={i} className="text-text-secondary">• {w}</div>
          ))}
        </div>
      )}

      <div className="overflow-x-auto">
      <table className="w-full text-sm">
        <thead className="text-xs text-text-muted text-left">
          <tr>
            <th className="pb-2">{t("descCol")}</th>
            <th className="pb-2 text-right">{t("qtyCol")}</th>
            <th className="pb-2 text-right">{t("unitPriceCol")}</th>
            <th className="pb-2 text-right">{t("amountCol")}</th>
          </tr>
        </thead>
        <tbody>
          {tenantOrder.map((tenantKey) => {
            const lines = linesByTenant.get(tenantKey)!;
            return (
              <Fragment key={tenantKey ?? "_org"}>
                {tenantKey && (
                  <tr className="border-t border-border">
                    <td colSpan={4} className="py-1.5 pt-3">
                      <span className="text-xs font-semibold text-accent">
                        {tenantKey}
                      </span>
                    </td>
                  </tr>
                )}
                {lines.map((ln, i) => (
                  <tr
                    key={`${tenantKey}-${i}`}
                    className="border-t border-border"
                  >
                    <td className="py-1.5">
                      <div>{ln.description}</div>
                      <div className="text-xs text-text-muted font-mono">
                        {ln.kind}
                      </div>
                    </td>
                    <td className="py-1.5 text-right">
                      {ln.quantity}
                      {ln.unitLabel ? ` ${ln.unitLabel}` : ""}
                    </td>
                    <td className="py-1.5 text-right font-mono text-xs">
                      {ln.unitPriceChf.toFixed(4)}
                    </td>
                    <td className="py-1.5 text-right">
                      {ln.amountChf.toFixed(2)}
                    </td>
                  </tr>
                ))}
              </Fragment>
            );
          })}
          {draft.lines.length === 0 && (
            <tr>
              <td colSpan={4} className="py-4 text-center text-text-muted italic">
                {t("noLinesGenerated")}
              </td>
            </tr>
          )}
        </tbody>
      </table>
      </div>

      <div className="mt-4 pt-3 border-t border-border space-y-1 text-sm">
        <div className="flex justify-between">
          <span className="text-text-muted">{t("subtotal")}</span>
          <span>CHF {draft.subtotalChf.toFixed(2)}</span>
        </div>
        <div className="flex justify-between">
          <span className="text-text-muted">
            {t("vat")} ({draft.vatRate.toFixed(2)}%)
          </span>
          <span>CHF {draft.vatAmountChf.toFixed(2)}</span>
        </div>
        <div className="flex justify-between pt-1 border-t border-border font-semibold">
          <span>{t("total")}</span>
          <span>CHF {draft.totalChf.toFixed(2)}</span>
        </div>
      </div>
    </Card>
  );
}
