"use client";

import { FormEvent, Suspense, useEffect, useState } from "react";
import Link from "next/link";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { AdminBooleanBadge } from "@/components/admin/AdminBooleanBadge";
import { AdminDataTable } from "@/components/admin/AdminDataTable";
import {
  AdminFilterBar,
  AdminFilterField,
  adminFilterInputClassName,
} from "@/components/admin/AdminFilterBar";
import { AdminPageIntro } from "@/components/admin/AdminPageIntro";
import { AdminPagination } from "@/components/admin/AdminPagination";
import { AdminShell } from "@/components/admin/AdminShell";
import { AdminStatusBadge } from "@/components/admin/AdminStatusBadge";
import { AdminTableSkeleton } from "@/components/admin/AdminTableSkeleton";
import { ErrorState } from "@/components/ui/ErrorState";
import { ApiError } from "@/lib/api";
import {
  buildAdminListQuery,
  parseAdminEnumParam,
  parseAdminPage,
  parseAdminSearchParam,
} from "@/lib/admin-list-query";
import { adminApi, formatAdminDate } from "@/lib/api/admin";
import type { AdminPaginationMeta, AdminStripeAccount } from "@/types/admin";

const READINESS_VALUES = [
  "not_connected",
  "setup_required",
  "verification_pending",
  "action_required",
  "ready",
  "restricted",
  "disabled",
] as const;

export function AdminStripeAccountsPage() {
  return (
    <AdminShell title="Stripe Accounts" subtitle="Connect readiness">
      {() => (
        <Suspense fallback={<AdminTableSkeleton columns={7} />}>
          <StripeContent />
        </Suspense>
      )}
    </AdminShell>
  );
}

function StripeContent() {
  const router = useRouter();
  const pathname = usePathname();
  const searchParams = useSearchParams();

  const urlSearch = parseAdminSearchParam(searchParams.get("search"));
  const urlReadiness = parseAdminEnumParam(searchParams.get("readiness"), READINESS_VALUES);
  const urlPage = parseAdminPage(searchParams.get("page"));

  const [search, setSearch] = useState(urlSearch);
  const [readiness, setReadiness] = useState(urlReadiness);
  const [accounts, setAccounts] = useState<AdminStripeAccount[]>([]);
  const [meta, setMeta] = useState<AdminPaginationMeta | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    setSearch(urlSearch);
    setReadiness(urlReadiness);
  }, [urlSearch, urlReadiness]);

  useEffect(() => {
    let cancelled = false;

    async function load() {
      setLoading(true);
      setError(null);
      try {
        const result = await adminApi.listStripeAccounts({
          page: urlPage,
          search: urlSearch || undefined,
          readiness: urlReadiness || undefined,
        });
        if (cancelled) return;
        setAccounts(result.stripe_accounts);
        setMeta(result.meta);
      } catch (err) {
        if (cancelled) return;
        setError(err instanceof ApiError ? err.message : "Unable to load Stripe accounts.");
      } finally {
        if (!cancelled) setLoading(false);
      }
    }

    void load();
    return () => {
      cancelled = true;
    };
  }, [urlSearch, urlReadiness, urlPage]);

  function replaceQuery(next: { search?: string; readiness?: string; page?: number }) {
    const query = buildAdminListQuery({
      search: next.search !== undefined ? next.search : urlSearch,
      readiness: next.readiness !== undefined ? next.readiness : urlReadiness,
      page: next.page !== undefined ? next.page : urlPage,
    });
    router.replace(`${pathname}${query}`, { scroll: false });
  }

  function handleSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    replaceQuery({ search: search.trim(), readiness, page: 1 });
  }

  function handleReset() {
    setSearch("");
    setReadiness("");
    router.replace(pathname, { scroll: false });
  }

  return (
    <div className="space-y-5">
      <AdminPageIntro description="Operational Connect status only. Bank details and secrets are never shown." />

      <AdminFilterBar onSubmit={handleSubmit} onReset={handleReset} disabled={loading}>
        <AdminFilterField label="Search" className="min-w-[14rem] lg:flex-[1.4]">
          <input
            className={adminFilterInputClassName}
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            placeholder="Creator, email, or account id"
            aria-label="Search creator, email, or account id"
          />
        </AdminFilterField>
        <AdminFilterField label="Readiness">
          <select
            className={adminFilterInputClassName}
            value={readiness}
            onChange={(e) => setReadiness(e.target.value)}
          >
            <option value="">All</option>
            <option value="setup_required">Setup required</option>
            <option value="verification_pending">Verification pending</option>
            <option value="action_required">Action required</option>
            <option value="ready">Ready</option>
            <option value="restricted">Restricted</option>
            <option value="disabled">Disabled</option>
            <option value="not_connected">Not connected</option>
          </select>
        </AdminFilterField>
      </AdminFilterBar>

      {error ? (
        <ErrorState
          title="Unable to load accounts"
          message={error}
          onRetry={() => replaceQuery({ page: urlPage })}
        />
      ) : loading ? (
        <AdminTableSkeleton columns={7} />
      ) : (
        <>
          <AdminDataTable
            rows={accounts}
            caption="Stripe Connect accounts"
            emptyTitle="No Stripe accounts found"
            emptyDescription="Connected creator Express accounts will appear here."
            columns={[
              {
                key: "creator",
                header: "Creator",
                cell: (row) => {
                  const label = row.creator?.display_name ?? row.creator?.username ?? "—";
                  const userId = row.creator?.user?.id;
                  return (
                    <div className="min-w-[11rem]">
                      {userId ? (
                        <Link
                          href={`/admin/users/${userId}`}
                          className="font-medium text-primary underline-offset-2 hover:underline"
                        >
                          {label}
                        </Link>
                      ) : (
                        <p className="font-medium text-primary">{label}</p>
                      )}
                      <p className="mt-0.5 text-[0.75rem] text-ink-60">
                        {row.creator?.user?.email ?? "—"}
                      </p>
                    </div>
                  );
                },
              },
              {
                key: "account",
                header: "Stripe account",
                cell: (row) => (
                  <span className="font-mono text-[0.75rem] text-ink-60">
                    {row.provider_account_id}
                  </span>
                ),
              },
              {
                key: "onboarding",
                header: "Onboarding",
                cell: (row) => (
                  <AdminBooleanBadge
                    enabled={row.details_submitted}
                    enabledLabel="Submitted"
                    disabledLabel="Incomplete"
                  />
                ),
              },
              {
                key: "charges",
                header: "Charges",
                cell: (row) => <AdminBooleanBadge enabled={row.charges_enabled} />,
              },
              {
                key: "payouts",
                header: "Payouts",
                cell: (row) => <AdminBooleanBadge enabled={row.payouts_enabled} />,
              },
              {
                key: "status",
                header: "Status",
                cell: (row) => (
                  <div className="space-y-1">
                    <AdminStatusBadge status={row.readiness} />
                    {(row.currently_due_count > 0 || row.past_due_count > 0) && (
                      <p className="text-[0.6875rem] text-ink-40">
                        Due {row.currently_due_count} · Past due {row.past_due_count}
                      </p>
                    )}
                    {row.disabled_reason ? (
                      <p className="max-w-[10rem] truncate text-[0.6875rem] text-red-700" title={row.disabled_reason}>
                        {row.disabled_reason}
                      </p>
                    ) : null}
                  </div>
                ),
              },
              {
                key: "updated",
                header: "Last updated",
                cell: (row) => (
                  <span className="whitespace-nowrap text-[0.75rem] text-ink-40">
                    {formatAdminDate(row.requirements_synced_at ?? row.updated_at)}
                  </span>
                ),
              },
            ]}
          />
          {meta ? (
            <AdminPagination
              meta={meta}
              onPageChange={(next) => replaceQuery({ page: next })}
            />
          ) : null}
        </>
      )}
    </div>
  );
}
