"use client";

import { FormEvent, Suspense, useEffect, useState } from "react";
import Link from "next/link";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
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 {
  adminListHref,
  buildAdminListQuery,
  parseAdminEnumParam,
  parseAdminIdParam,
  parseAdminPage,
} from "@/lib/admin-list-query";
import { adminApi, formatAdminDate, formatAdminMoney } from "@/lib/api/admin";
import type { AdminEarning, AdminPaginationMeta } from "@/types/admin";

const EARNING_STATUSES = [
  "unfunded",
  "funded",
  "in_progress",
  "payable",
  "transfer_pending",
  "transferred",
] as const;

const TRANSFER_STATUSES = ["pending", "processing", "succeeded", "failed"] as const;

export function AdminEarningsPage() {
  return (
    <AdminShell title="Earnings" subtitle="Creator payouts">
      {() => (
        <Suspense fallback={<AdminTableSkeleton columns={9} />}>
          <EarningsContent />
        </Suspense>
      )}
    </AdminShell>
  );
}

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

  const urlStatus = parseAdminEnumParam(searchParams.get("status"), EARNING_STATUSES);
  const urlTransferStatus = parseAdminEnumParam(
    searchParams.get("transfer_status"),
    TRANSFER_STATUSES,
  );
  const urlCreatorProfileId = parseAdminIdParam(searchParams.get("creator_profile_id"));
  const urlCampaignId = parseAdminIdParam(searchParams.get("campaign_id"));
  const urlPaymentId = parseAdminIdParam(searchParams.get("marketplace_payment_id"));
  const urlPage = parseAdminPage(searchParams.get("page"));

  const [status, setStatus] = useState(urlStatus);
  const [transferStatus, setTransferStatus] = useState(urlTransferStatus);
  const [earnings, setEarnings] = useState<AdminEarning[]>([]);
  const [meta, setMeta] = useState<AdminPaginationMeta | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    setStatus(urlStatus);
    setTransferStatus(urlTransferStatus);
  }, [urlStatus, urlTransferStatus]);

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

    async function load() {
      setLoading(true);
      setError(null);
      try {
        const result = await adminApi.listEarnings({
          page: urlPage,
          status: urlStatus || undefined,
          transfer_status: urlTransferStatus || undefined,
          creator_profile_id: urlCreatorProfileId,
          campaign_id: urlCampaignId,
          marketplace_payment_id: urlPaymentId,
        });
        if (cancelled) return;
        setEarnings(result.earnings);
        setMeta(result.meta);
      } catch (err) {
        if (cancelled) return;
        setError(err instanceof ApiError ? err.message : "Unable to load earnings.");
      } finally {
        if (!cancelled) setLoading(false);
      }
    }

    void load();
    return () => {
      cancelled = true;
    };
  }, [
    urlStatus,
    urlTransferStatus,
    urlCreatorProfileId,
    urlCampaignId,
    urlPaymentId,
    urlPage,
  ]);

  function replaceQuery(next: {
    status?: string;
    transfer_status?: string;
    creator_profile_id?: number | null;
    campaign_id?: number | null;
    marketplace_payment_id?: number | null;
    page?: number;
  }) {
    const creatorId =
      next.creator_profile_id !== undefined ? next.creator_profile_id : urlCreatorProfileId;
    const campaignId = next.campaign_id !== undefined ? next.campaign_id : urlCampaignId;
    const paymentId =
      next.marketplace_payment_id !== undefined ? next.marketplace_payment_id : urlPaymentId;

    const query = buildAdminListQuery({
      status: next.status !== undefined ? next.status : urlStatus,
      transfer_status:
        next.transfer_status !== undefined ? next.transfer_status : urlTransferStatus,
      creator_profile_id: creatorId ?? undefined,
      campaign_id: campaignId ?? undefined,
      marketplace_payment_id: paymentId ?? undefined,
      page: next.page !== undefined ? next.page : urlPage,
    });
    router.replace(`${pathname}${query}`, { scroll: false });
  }

  function handleSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    replaceQuery({ status, transfer_status: transferStatus, page: 1 });
  }

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

  const filterNote = [
    urlCreatorProfileId ? `creator profile #${urlCreatorProfileId}` : null,
    urlCampaignId ? `campaign #${urlCampaignId}` : null,
    urlPaymentId ? `payment #${urlPaymentId}` : null,
    urlTransferStatus ? `transfer ${urlTransferStatus}` : null,
  ]
    .filter(Boolean)
    .join(", ");

  return (
    <div className="space-y-5">
      <AdminPageIntro description="Read-only funded charge → earning → Connect transfer flow. Earning status is accounting state; transfer status is the Stripe Connect transfer attempt." />

      {filterNote ? (
        <p className="text-[0.8125rem] text-ink-60">
          Filtered by {filterNote}.{" "}
          <button
            type="button"
            className="font-medium text-primary underline-offset-2 hover:underline"
            onClick={() =>
              replaceQuery({
                creator_profile_id: null,
                campaign_id: null,
                marketplace_payment_id: null,
                page: 1,
              })
            }
          >
            Clear record filters
          </button>
        </p>
      ) : null}

      <AdminFilterBar onSubmit={handleSubmit} onReset={handleReset} disabled={loading}>
        <AdminFilterField label="Earning status">
          <select
            className={adminFilterInputClassName}
            value={status}
            onChange={(e) => setStatus(e.target.value)}
          >
            <option value="">All</option>
            <option value="unfunded">Unfunded</option>
            <option value="funded">Funded</option>
            <option value="in_progress">In progress</option>
            <option value="payable">Payable</option>
            <option value="transfer_pending">Transfer pending</option>
            <option value="transferred">Transferred</option>
          </select>
        </AdminFilterField>
        <AdminFilterField label="Transfer status">
          <select
            className={adminFilterInputClassName}
            value={transferStatus}
            onChange={(e) => setTransferStatus(e.target.value)}
            aria-label="Filter by transfer status"
          >
            <option value="">All</option>
            <option value="pending">Pending</option>
            <option value="processing">Processing</option>
            <option value="succeeded">Succeeded</option>
            <option value="failed">Failed</option>
          </select>
        </AdminFilterField>
      </AdminFilterBar>

      {error ? (
        <ErrorState
          title="Unable to load earnings"
          message={error}
          onRetry={() => replaceQuery({ page: urlPage })}
        />
      ) : loading ? (
        <AdminTableSkeleton columns={9} />
      ) : (
        <>
          <AdminDataTable
            rows={earnings}
            caption="Creator earnings"
            emptyTitle="No earnings found"
            emptyDescription="Creator earnings appear after a brand charge succeeds."
            columns={[
              {
                key: "creator",
                header: "Creator",
                cell: (row) => {
                  const label = row.creator?.display_name ?? row.creator?.username ?? "—";
                  const userId = row.creator?.user?.id;
                  if (!userId) {
                    return <span className="font-medium text-primary">{label}</span>;
                  }
                  return (
                    <Link
                      href={`/admin/users/${userId}`}
                      className="font-medium text-primary underline-offset-2 hover:underline"
                    >
                      {label}
                    </Link>
                  );
                },
              },
              {
                key: "campaign",
                header: "Campaign",
                cell: (row) => {
                  if (!row.campaign) {
                    return <span className="text-ink-60">—</span>;
                  }
                  return (
                    <Link
                      href={`/admin/campaigns/${row.campaign.id}`}
                      className="text-ink-60 underline-offset-2 hover:text-primary hover:underline"
                    >
                      {row.campaign.name}
                    </Link>
                  );
                },
              },
              {
                key: "creator_amount",
                header: "Creator amount",
                cell: (row) => (
                  <span className="tabular-nums font-semibold text-primary">
                    {formatAdminMoney(row.creator_amount, row.currency)}
                  </span>
                ),
              },
              {
                key: "earning_status",
                header: "Earning",
                cell: (row) => <AdminStatusBadge status={row.status} />,
              },
              {
                key: "transfer",
                header: "Transfer",
                cell: (row) => {
                  if (!row.transfer) {
                    return <span className="text-[0.75rem] text-ink-40">No transfer</span>;
                  }
                  return (
                    <div className="min-w-[8rem] space-y-1">
                      <AdminStatusBadge status={row.transfer.status} />
                      <p className="tabular-nums text-[0.75rem] text-ink-60">
                        {formatAdminMoney(row.transfer.amount, row.currency)}
                      </p>
                      {row.transfer.failure_code ? (
                        <p className="font-mono text-[0.6875rem] text-red-700">
                          {row.transfer.failure_code}
                        </p>
                      ) : null}
                    </div>
                  );
                },
              },
              {
                key: "transfer_dates",
                header: "Transfer dates",
                cell: (row) => {
                  if (!row.transfer) {
                    return <span className="text-ink-40">—</span>;
                  }
                  return (
                    <div className="space-y-0.5 text-[0.75rem] text-ink-40">
                      <p>Init {formatAdminDate(row.transfer.initiated_at)}</p>
                      <p>Done {formatAdminDate(row.transfer.transferred_at)}</p>
                      <p>Fail {formatAdminDate(row.transfer.failed_at)}</p>
                    </div>
                  );
                },
              },
              {
                key: "payable",
                header: "Payable",
                cell: (row) => (
                  <span className="whitespace-nowrap text-[0.75rem] text-ink-40">
                    {formatAdminDate(row.payable_at)}
                  </span>
                ),
              },
              {
                key: "payment",
                header: "Payment",
                cell: (row) => {
                  if (!row.payment) {
                    return <span className="text-ink-40">—</span>;
                  }
                  const label = (
                    <span className="tabular-nums">
                      #{row.payment.id}
                      <span className="mt-0.5 block text-[0.6875rem] text-ink-40">
                        {row.payment.status}
                        {row.payment.paid_at ? ` · ${formatAdminDate(row.payment.paid_at)}` : ""}
                      </span>
                    </span>
                  );
                  if (!row.campaign) {
                    return <span className="text-ink-60">{label}</span>;
                  }
                  return (
                    <Link
                      href={adminListHref("/admin/finance/payments", {
                        campaign_id: row.campaign.id,
                      })}
                      className="text-ink-60 underline-offset-2 hover:text-primary hover:underline"
                      title={`Payment #${row.payment.id}`}
                    >
                      {label}
                    </Link>
                  );
                },
              },
            ]}
          />
          {meta ? (
            <AdminPagination
              meta={meta}
              onPageChange={(next) => replaceQuery({ page: next })}
            />
          ) : null}
        </>
      )}
    </div>
  );
}
