"use client";

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

interface Props {
  initial: OrgBilling | null;
  /**
   * Personal-account (individual customer) flag from the session.
   * Individuals get a "Full name" field instead of "Company name",
   * and the VAT input is hidden entirely — they don't have one and
   * showing the field would only confuse. The underlying column is
   * still `company_name` in the DB and the invoice PDF; for an
   * individual that field carries their full name, which is
   * exactly what should print on the invoice.
   */
  isPersonal: boolean;
}

/**
 * Customer billing settings form. Drives PUT /api/settings/billing
 * which upserts org_billing for the caller's org.
 *
 * Validation is the same regex as the server-side zod schema for
 * the country field (ISO 3166-1 alpha-2). Other fields are checked
 * for required + max-length client-side; the server is the
 * authority and re-validates everything.
 *
 * On success we router.refresh() the page so the server component
 * re-fetches and any "create now" -> "edit" wording flips.
 */
export function BillingSettingsForm({ initial, isPersonal }: Props) {
  const t = useTranslations("settingsBilling");
  const router = useRouter();
  const [form, setForm] = useState({
    companyName: initial?.companyName ?? "",
    contactName: initial?.contactName ?? "",
    streetAddress: initial?.streetAddress ?? "",
    postalCode: initial?.postalCode ?? "",
    city: initial?.city ?? "",
    country: initial?.country ?? "CH",
    vatNumber: initial?.vatNumber ?? "",
    billingEmail: initial?.billingEmail ?? "",
    notes: initial?.notes ?? "",
  });
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [savedFlash, setSavedFlash] = useState(false);

  const set =
    (field: keyof typeof form) =>
    (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) =>
      setForm((f) => ({ ...f, [field]: e.target.value }));

  const submit = async () => {
    setError(null);
    setSavedFlash(false);
    // Client-side gate on required fields — the server re-validates.
    if (
      !form.companyName.trim() ||
      !form.streetAddress.trim() ||
      !form.postalCode.trim() ||
      !form.city.trim() ||
      !form.country.trim() ||
      !form.billingEmail.trim()
    ) {
      setError(t("missingRequired"));
      return;
    }
    if (!/^[A-Za-z]{2}$/.test(form.country.trim())) {
      setError(t("invalidCountry"));
      return;
    }
    if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(form.billingEmail.trim())) {
      setError(t("invalidEmail"));
      return;
    }
    setBusy(true);
    try {
      const res = await fetch("/api/settings/billing", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          companyName: form.companyName.trim(),
          // Personal accounts don't have a contact-name field
          // (companyName IS their name); force null so stale state
          // from a previously-org-flagged account can't carry over.
          contactName: isPersonal ? null : form.contactName.trim() || null,
          streetAddress: form.streetAddress.trim(),
          postalCode: form.postalCode.trim(),
          city: form.city.trim(),
          country: form.country.trim().toUpperCase(),
          // Personal accounts never have a VAT number — force null
          // regardless of stale state, in case a value was stored
          // before the account got flagged as personal.
          vatNumber: isPersonal ? null : form.vatNumber.trim() || null,
          billingEmail: form.billingEmail.trim(),
          notes: form.notes.trim() || null,
        }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        throw new Error(data.error ?? `HTTP ${res.status}`);
      }
      setSavedFlash(true);
      router.refresh();
    } catch (e: any) {
      setError(e?.message ?? String(e));
    } finally {
      setBusy(false);
    }
  };

  return (
    <Card>
      <div className="space-y-4">
        <Field
          label={isPersonal ? t("fullNameLabel") : t("companyNameLabel")}
          required
        >
          <input
            type="text"
            value={form.companyName}
            onChange={set("companyName")}
            maxLength={200}
            className="w-full px-3 py-2 rounded-md bg-surface-2 border border-border focus:border-accent focus:outline-none text-sm"
          />
        </Field>
        {!isPersonal && (
          <Field label={t("contactNameLabel")} hint={t("contactNameHint")}>
            <input
              type="text"
              value={form.contactName}
              onChange={set("contactName")}
              maxLength={200}
              className="w-full px-3 py-2 rounded-md bg-surface-2 border border-border focus:border-accent focus:outline-none text-sm"
            />
          </Field>
        )}
        <Field label={t("streetAddressLabel")} required>
          <input
            type="text"
            value={form.streetAddress}
            onChange={set("streetAddress")}
            maxLength={200}
            className="w-full px-3 py-2 rounded-md bg-surface-2 border border-border focus:border-accent focus:outline-none text-sm"
          />
        </Field>
        <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
          <Field label={t("postalCodeLabel")} required>
            <input
              type="text"
              value={form.postalCode}
              onChange={set("postalCode")}
              maxLength={20}
              className="w-full px-3 py-2 rounded-md bg-surface-2 border border-border focus:border-accent focus:outline-none text-sm"
            />
          </Field>
          <Field label={t("cityLabel")} required>
            <input
              type="text"
              value={form.city}
              onChange={set("city")}
              maxLength={100}
              className="w-full px-3 py-2 rounded-md bg-surface-2 border border-border focus:border-accent focus:outline-none text-sm"
            />
          </Field>
          <Field
            label={t("countryLabel")}
            required
            hint={t("countryHint")}
          >
            <input
              type="text"
              value={form.country}
              onChange={(e) =>
                setForm((f) => ({
                  ...f,
                  country: e.target.value.toUpperCase().slice(0, 2),
                }))
              }
              maxLength={2}
              className="w-full px-3 py-2 rounded-md bg-surface-2 border border-border focus:border-accent focus:outline-none text-sm uppercase font-mono"
            />
          </Field>
        </div>
        {!isPersonal && (
          <Field label={t("vatNumberLabel")} hint={t("vatNumberHint")}>
            <input
              type="text"
              value={form.vatNumber}
              onChange={set("vatNumber")}
              maxLength={40}
              placeholder="CHE-123.456.789 MWST"
              className="w-full px-3 py-2 rounded-md bg-surface-2 border border-border focus:border-accent focus:outline-none text-sm font-mono"
            />
          </Field>
        )}
        <Field label={t("billingEmailLabel")} required hint={t("billingEmailHint")}>
          <input
            type="email"
            value={form.billingEmail}
            onChange={set("billingEmail")}
            maxLength={200}
            className="w-full px-3 py-2 rounded-md bg-surface-2 border border-border focus:border-accent focus:outline-none text-sm"
          />
        </Field>
        <Field label={t("notesLabel")} hint={t("notesHint")}>
          <textarea
            value={form.notes}
            onChange={set("notes")}
            maxLength={2000}
            rows={3}
            className="w-full px-3 py-2 rounded-md bg-surface-2 border border-border focus:border-accent focus:outline-none text-sm"
          />
        </Field>
        {error && (
          <p className="text-sm text-error">{error}</p>
        )}
        {savedFlash && (
          <p className="text-sm text-success">{t("saved")}</p>
        )}
        <div className="flex justify-end">
          <button
            onClick={submit}
            disabled={busy}
            className="px-4 py-2 rounded-md bg-accent text-white text-sm font-medium hover:bg-accent-dim transition-colors disabled:opacity-50 cursor-pointer"
          >
            {busy ? t("saving") : initial ? t("saveChanges") : t("createBilling")}
          </button>
        </div>
      </div>
    </Card>
  );
}

function Field({
  label,
  required,
  hint,
  children,
}: {
  label: string;
  required?: boolean;
  hint?: string;
  children: React.ReactNode;
}) {
  return (
    <div>
      <label className="block text-xs uppercase tracking-wider text-text-muted mb-1">
        {label}
        {required && <span className="text-error ml-1">*</span>}
      </label>
      {children}
      {hint && (
        <p className="text-xs text-text-muted mt-1 italic">{hint}</p>
      )}
    </div>
  );
}
