"use client";

import { FormEvent, Suspense, useEffect, useState } from "react";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { AdminActionLink } from "@/components/admin/AdminActionLink";
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,
  parseAdminFlagParam,
  parseAdminIdParam,
  parseAdminPage,
  parseAdminSearchParam,
} from "@/lib/admin-list-query";
import { adminApi, formatAdminDate, formatAdminMoney } from "@/lib/api/admin";
import type { AdminCampaignListItem, AdminPaginationMeta } from "@/types/admin";

const CAMPAIGN_STATUSES = ["draft", "active", "paused", "completed", "cancelled"] as const;

export function AdminCampaignsPage() {
  return (
    <AdminShell title="Campaigns" subtitle="Marketplace directory">
      {() => (
        <Suspense fallback={<AdminTableSkeleton columns={7} />}>
          <CampaignsContent />
        </Suspense>
      )}
    </AdminShell>
  );
}

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

  const urlSearch = parseAdminSearchParam(searchParams.get("search"));
  const urlStatus = parseAdminEnumParam(searchParams.get("status"), CAMPAIGN_STATUSES);
  const urlBrandProfileId = parseAdminIdParam(searchParams.get("brand_profile_id"));
  const urlCreatorProfileId = parseAdminIdParam(searchParams.get("creator_profile_id"));
  const urlHasPendingApplications = parseAdminFlagParam(
    searchParams.get("has_pending_applications"),
  );
  const urlPage = parseAdminPage(searchParams.get("page"));

  const [search, setSearch] = useState(urlSearch);
  const [status, setStatus] = useState(urlStatus);
  const [hasPendingApplications, setHasPendingApplications] = useState(urlHasPendingApplications);
  const [campaigns, setCampaigns] = useState<AdminCampaignListItem[]>([]);
  const [meta, setMeta] = useState<AdminPaginationMeta | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    setSearch(urlSearch);
    setStatus(urlStatus);
    setHasPendingApplications(urlHasPendingApplications);
  }, [urlSearch, urlStatus, urlHasPendingApplications]);

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

    async function load() {
      setLoading(true);
      setError(null);
      try {
        const result = await adminApi.listCampaigns({
          page: urlPage,
          search: urlSearch || undefined,
          status: urlStatus || undefined,
          brand_profile_id: urlBrandProfileId,
          creator_profile_id: urlCreatorProfileId,
          has_pending_applications: urlHasPendingApplications ? 1 : undefined,
        });
        if (cancelled) return;
        setCampaigns(result.campaigns);
        setMeta(result.meta);
      } catch (err) {
        if (cancelled) return;
        setError(err instanceof ApiError ? err.message : "Unable to load campaigns.");
      } finally {
        if (!cancelled) setLoading(false);
      }
    }

    void load();
    return () => {
      cancelled = true;
    };
  }, [
    urlSearch,
    urlStatus,
    urlBrandProfileId,
    urlCreatorProfileId,
    urlHasPendingApplications,
    urlPage,
  ]);

  function replaceQuery(next: {
    search?: string;
    status?: string;
    brand_profile_id?: number | null;
    creator_profile_id?: number | null;
    has_pending_applications?: boolean;
    page?: number;
  }) {
    const brandId =
      next.brand_profile_id !== undefined ? next.brand_profile_id : urlBrandProfileId;
    const creatorId =
      next.creator_profile_id !== undefined ? next.creator_profile_id : urlCreatorProfileId;
    const pending =
      next.has_pending_applications !== undefined
        ? next.has_pending_applications
        : urlHasPendingApplications;

    const query = buildAdminListQuery({
      search: next.search !== undefined ? next.search : urlSearch,
      status: next.status !== undefined ? next.status : urlStatus,
      brand_profile_id: brandId ?? undefined,
      creator_profile_id: creatorId ?? undefined,
      has_pending_applications: pending ? 1 : undefined,
      page: next.page !== undefined ? next.page : urlPage,
    });
    router.replace(`${pathname}${query}`, { scroll: false });
  }

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

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

  const filterNote = [
    urlBrandProfileId ? `brand #${urlBrandProfileId}` : null,
    urlCreatorProfileId ? `creator profile #${urlCreatorProfileId}` : null,
    urlHasPendingApplications ? "pending applications" : null,
  ]
    .filter(Boolean)
    .join(", ");

  return (
    <div className="space-y-5">
      <AdminPageIntro description="Global read-only campaign directory." />

      {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({
                brand_profile_id: null,
                creator_profile_id: null,
                has_pending_applications: false,
                page: 1,
              })
            }
          >
            Clear list filters
          </button>
        </p>
      ) : null}

      <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="Search campaign or brand"
            aria-label="Search campaign or brand"
          />
        </AdminFilterField>
        <AdminFilterField label="Status">
          <select
            className={adminFilterInputClassName}
            value={status}
            onChange={(e) => setStatus(e.target.value)}
          >
            <option value="">All</option>
            <option value="draft">Draft</option>
            <option value="active">Active</option>
            <option value="paused">Paused</option>
            <option value="completed">Completed</option>
            <option value="cancelled">Cancelled</option>
          </select>
        </AdminFilterField>
        <AdminFilterField label="Applications">
          <select
            className={adminFilterInputClassName}
            value={hasPendingApplications ? "1" : ""}
            onChange={(e) => setHasPendingApplications(e.target.value === "1")}
            aria-label="Filter by pending applications"
          >
            <option value="">All</option>
            <option value="1">Has pending</option>
          </select>
        </AdminFilterField>
      </AdminFilterBar>

      {error ? (
        <ErrorState
          title="Unable to load campaigns"
          message={error}
          onRetry={() => replaceQuery({ page: urlPage })}
        />
      ) : loading ? (
        <AdminTableSkeleton columns={7} />
      ) : (
        <>
          <AdminDataTable
            rows={campaigns}
            caption="Campaigns"
            emptyTitle="No campaigns found"
            emptyDescription="Try adjusting search or status filters."
            columns={[
              {
                key: "name",
                header: "Campaign",
                cell: (row) => (
                  <div className="min-w-[12rem]">
                    <p className="font-medium text-primary">{row.name}</p>
                    <p className="mt-0.5 text-[0.75rem] text-ink-40">
                      {formatAdminDate(row.start_date)} → {formatAdminDate(row.end_date)}
                    </p>
                  </div>
                ),
              },
              {
                key: "brand",
                header: "Brand",
                cell: (row) => (
                  <span className="text-ink-60">{row.brand?.company_name ?? "—"}</span>
                ),
              },
              {
                key: "status",
                header: "Status",
                cell: (row) => <AdminStatusBadge status={row.status} />,
              },
              {
                key: "budget",
                header: "Budget",
                cell: (row) => (
                  <span className="tabular-nums font-medium text-primary">
                    {formatAdminMoney(row.budget_amount, row.currency)}
                  </span>
                ),
              },
              {
                key: "participants",
                header: "Participants",
                cell: (row) => (
                  <span className="tabular-nums text-ink-60">{row.participants_count}</span>
                ),
              },
              {
                key: "applications",
                header: "Applications",
                cell: (row) => (
                  <span className="tabular-nums text-ink-60">{row.applications_count}</span>
                ),
              },
              {
                key: "created",
                header: "Created",
                cell: (row) => (
                  <span className="whitespace-nowrap text-[0.75rem] text-ink-40">
                    {formatAdminDate(row.created_at)}
                  </span>
                ),
              },
              {
                key: "actions",
                header: "Action",
                className: "text-right",
                headerClassName: "text-right",
                cell: (row) => <AdminActionLink href={`/admin/campaigns/${row.id}`} />,
              },
            ]}
          />
          {meta ? (
            <AdminPagination
              meta={meta}
              onPageChange={(next) => replaceQuery({ page: next })}
            />
          ) : null}
        </>
      )}
    </div>
  );
}
