"use client";

import { FormEvent, useCallback, useEffect, useState } from "react";
import { toast } from "sonner";
import { Button } from "@/components/Button";
import { ErrorState } from "@/components/ui/ErrorState";
import { PageHeader } from "@/components/ui/PageHeader";
import { Skeleton } from "@/components/ui/Skeleton";
import { ApiError } from "@/lib/api";
import { billingAddressApi } from "@/lib/api/billing-address";
import type { BrandBillingAddress } from "@/types/payments";
import { DashboardShell } from "./DashboardShell";

type FormState = {
  billing_name: string;
  billing_line1: string;
  billing_line2: string;
  billing_city: string;
  billing_state: string;
  billing_postal_code: string;
  billing_country: string;
};

function emptyForm(): FormState {
  return {
    billing_name: "",
    billing_line1: "",
    billing_line2: "",
    billing_city: "",
    billing_state: "",
    billing_postal_code: "",
    billing_country: "US",
  };
}

function formFromAddress(address: BrandBillingAddress): FormState {
  return {
    billing_name: address.billing_name ?? "",
    billing_line1: address.billing_line1 ?? "",
    billing_line2: address.billing_line2 ?? "",
    billing_city: address.billing_city ?? "",
    billing_state: address.billing_state ?? "",
    billing_postal_code: address.billing_postal_code ?? "",
    billing_country: (address.billing_country ?? "US").toUpperCase(),
  };
}

export function DashboardBillingSettingsPage() {
  return (
    <DashboardShell title="Billing">
      {() => <BillingSettingsContent />}
    </DashboardShell>
  );
}

function BillingSettingsContent() {
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [complete, setComplete] = useState(false);
  const [form, setForm] = useState<FormState>(emptyForm);

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const address = await billingAddressApi.get();
      setForm(formFromAddress(address));
      setComplete(address.complete);
    } catch (caught) {
      setError(
        caught instanceof ApiError ? caught.message : "Unable to load billing address.",
      );
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    void load();
  }, [load]);

  async function onSubmit(event: FormEvent) {
    event.preventDefault();
    setSaving(true);
    setError(null);
    try {
      const address = await billingAddressApi.update({
        billing_name: form.billing_name.trim() || null,
        billing_line1: form.billing_line1.trim(),
        billing_line2: form.billing_line2.trim() || null,
        billing_city: form.billing_city.trim(),
        billing_state: form.billing_state.trim() || null,
        billing_postal_code: form.billing_postal_code.trim(),
        billing_country: form.billing_country.trim().toUpperCase(),
      });
      setForm(formFromAddress(address));
      setComplete(address.complete);
      toast.success("Billing address saved");
    } catch (caught) {
      setError(
        caught instanceof ApiError ? caught.message : "Unable to save billing address.",
      );
    } finally {
      setSaving(false);
    }
  }

  if (loading) {
    return (
      <div className="mx-auto w-full max-w-2xl space-y-4 px-4 py-8 sm:px-6">
        <Skeleton className="h-8 w-48" />
        <Skeleton className="h-40 w-full" />
      </div>
    );
  }

  return (
    <div className="mx-auto w-full max-w-2xl space-y-8 px-4 py-8 sm:px-6">
      <PageHeader description="Billing address is used for tax calculation on campaign payments. It is not taken from campaign audience targeting." />

      <section
        aria-labelledby="billing-address-heading"
        className="rounded-pv border border-line bg-surface p-5"
      >
        <h2 id="billing-address-heading" className="text-sm font-semibold text-primary">
          Billing address
        </h2>
        <p className="mt-2 text-[0.8125rem] text-ink-60">
          {complete
            ? "Address on file. Taxes are calculated when the payment is charged after deliverable verification."
            : "Add a complete billing address so Postvertise can calculate applicable taxes at charge time."}
        </p>

        {error ? (
          <div className="mt-4">
            <ErrorState message={error} />
          </div>
        ) : null}

        <form className="mt-4 space-y-3" onSubmit={onSubmit}>
          <label className="block text-[0.8125rem] text-ink-60">
            Name / company
            <input
              className="mt-1 w-full rounded-pv border border-line bg-white px-3 py-2 text-sm text-primary"
              value={form.billing_name}
              onChange={(e) => setForm((current) => ({ ...current, billing_name: e.target.value }))}
              autoComplete="organization"
            />
          </label>
          <label className="block text-[0.8125rem] text-ink-60">
            Address line 1
            <input
              required
              className="mt-1 w-full rounded-pv border border-line bg-white px-3 py-2 text-sm text-primary"
              value={form.billing_line1}
              onChange={(e) => setForm((current) => ({ ...current, billing_line1: e.target.value }))}
              autoComplete="address-line1"
            />
          </label>
          <label className="block text-[0.8125rem] text-ink-60">
            Address line 2
            <input
              className="mt-1 w-full rounded-pv border border-line bg-white px-3 py-2 text-sm text-primary"
              value={form.billing_line2}
              onChange={(e) => setForm((current) => ({ ...current, billing_line2: e.target.value }))}
              autoComplete="address-line2"
            />
          </label>
          <div className="grid gap-3 sm:grid-cols-2">
            <label className="block text-[0.8125rem] text-ink-60">
              City
              <input
                required
                className="mt-1 w-full rounded-pv border border-line bg-white px-3 py-2 text-sm text-primary"
                value={form.billing_city}
                onChange={(e) => setForm((current) => ({ ...current, billing_city: e.target.value }))}
                autoComplete="address-level2"
              />
            </label>
            <label className="block text-[0.8125rem] text-ink-60">
              State / province
              <input
                className="mt-1 w-full rounded-pv border border-line bg-white px-3 py-2 text-sm text-primary"
                value={form.billing_state}
                onChange={(e) => setForm((current) => ({ ...current, billing_state: e.target.value }))}
                autoComplete="address-level1"
                required={form.billing_country.toUpperCase() === "US"}
              />
            </label>
          </div>
          <div className="grid gap-3 sm:grid-cols-2">
            <label className="block text-[0.8125rem] text-ink-60">
              Postal code
              <input
                required
                className="mt-1 w-full rounded-pv border border-line bg-white px-3 py-2 text-sm text-primary"
                value={form.billing_postal_code}
                onChange={(e) =>
                  setForm((current) => ({ ...current, billing_postal_code: e.target.value }))
                }
                autoComplete="postal-code"
              />
            </label>
            <label className="block text-[0.8125rem] text-ink-60">
              Country
              <input
                required
                maxLength={2}
                className="mt-1 w-full rounded-pv border border-line bg-white px-3 py-2 text-sm uppercase text-primary"
                value={form.billing_country}
                onChange={(e) =>
                  setForm((current) => ({
                    ...current,
                    billing_country: e.target.value.toUpperCase(),
                  }))
                }
                autoComplete="country"
              />
            </label>
          </div>
          <div className="pt-2">
            <Button type="submit" size="sm" disabled={saving}>
              {saving ? "Saving…" : "Save billing address"}
            </Button>
          </div>
        </form>
      </section>
    </div>
  );
}
