"use client";

import { Suspense, useCallback, useEffect, useState } from "react";
import { useParams, usePathname, useRouter, useSearchParams } from "next/navigation";
import { toast } from "sonner";
import { ArrowLeftIcon } from "@heroicons/react/24/outline";
import { Button } from "@/components/Button";
import {
  BrandCampaignForm,
  buildCampaignPayload,
  campaignToFormValues,
  type CampaignFormValues,
} from "@/components/dashboard/BrandCampaignForm";
import { BrandCampaignApplicationsTab } from "@/components/dashboard/BrandCampaignApplicationsTab";
import { BrandCampaignDeliverablesTab } from "@/components/dashboard/BrandCampaignDeliverablesTab";
import { BrandCampaignParticipantsTab } from "@/components/dashboard/BrandCampaignParticipantsTab";
import { BrandCampaignPaymentsTab } from "@/components/dashboard/BrandCampaignPaymentsTab";
import { CampaignActivityPreview } from "@/components/dashboard/campaign-detail/CampaignActivityPreview";
import { CampaignAudienceSection } from "@/components/dashboard/campaign-detail/CampaignAudienceSection";
import { CampaignBriefDeliverables } from "@/components/dashboard/campaign-detail/CampaignBriefDeliverables";
import { CampaignBudgetPanel } from "@/components/dashboard/campaign-detail/CampaignBudgetPanel";
import { CampaignDetailHeader } from "@/components/dashboard/campaign-detail/CampaignDetailHeader";
import { CampaignDetailSkeleton } from "@/components/dashboard/campaign-detail/CampaignDetailSkeleton";
import { CampaignDetailTabs } from "@/components/dashboard/campaign-detail/CampaignDetailTabs";
import { CampaignNextActionCard } from "@/components/dashboard/campaign-detail/CampaignNextActionCard";
import { CampaignScheduleCard } from "@/components/dashboard/campaign-detail/CampaignStatusSchedule";
import { DashboardPageContainer } from "@/components/dashboard/DashboardPageContainer";
import { DashboardShell } from "@/components/dashboard/DashboardShell";
import { EmptyState } from "@/components/ui/EmptyState";
import { ErrorState } from "@/components/ui/ErrorState";
import { ConfirmDialog } from "@/components/ui/ConfirmDialog";
import { ApiError, creatorSearchApi, type ValidationErrors } from "@/lib/api";
import { campaignApi } from "@/lib/api/campaigns";
import {
  applicationApi,
  invitationApi,
  participantApi,
} from "@/lib/api/campaign-participation";
import {
  buildCampaignAudienceView,
  buildCampaignRelatedCreatorFilters,
  campaignDeliverableUnitCount,
  campaignDiscoverHref,
  friendlyCampaignLoadError,
  resolveCampaignNextAction,
  participantNeedsPaymentAuthorization,
  type CampaignActivityCounts,
} from "@/lib/campaign-detail-ui";
import {
  campaignActionRequiresConfirmation,
  campaignConfirmCopy,
  isCampaignLifecycleAction,
  parseCampaignManagementTab,
  type CampaignLifecycleAction,
  type CampaignManagementTab,
  type CampaignPrimaryAction,
} from "@/lib/campaign-management";
import { campaignIsEditable } from "@/lib/campaigns";
import type { Campaign, CampaignStatus } from "@/types/campaign";
import type {
  CampaignApplication,
  CampaignInvitation,
  CampaignParticipant,
} from "@/types/campaign-participation";
import type { SearchCreator } from "@/types/profile";

const BRAND_ONLY = ["brand"] as const;

function BrandCampaignDetailContent() {
  const params = useParams<{ id: string }>();
  const router = useRouter();
  const pathname = usePathname();
  const searchParams = useSearchParams();
  const campaignId = Number.parseInt(params.id, 10);

  const activeTab = parseCampaignManagementTab(searchParams.get("tab"));
  const focusParticipantRaw = searchParams.get("participant");
  const focusParticipantId = focusParticipantRaw
    ? Number.parseInt(focusParticipantRaw, 10)
    : null;

  const [campaign, setCampaign] = useState<Campaign | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [isEditing, setIsEditing] = useState(false);
  const [fieldErrors, setFieldErrors] = useState<ValidationErrors>({});
  const [busyAction, setBusyAction] = useState<"draft" | "active" | "save" | null>(null);
  const [busyPrimary, setBusyPrimary] = useState<CampaignPrimaryAction | null>(null);
  const [pendingConfirm, setPendingConfirm] = useState<CampaignPrimaryAction | null>(null);

  const [activity, setActivity] = useState<CampaignActivityCounts | null>(null);
  const [previewParticipants, setPreviewParticipants] = useState<CampaignParticipant[]>([]);
  const [previewApplications, setPreviewApplications] = useState<CampaignApplication[]>([]);
  const [previewInvitations, setPreviewInvitations] = useState<CampaignInvitation[]>([]);
  const [relatedCreators, setRelatedCreators] = useState<SearchCreator[]>([]);

  const setTab = useCallback(
    (tab: CampaignManagementTab, participantId?: number | null) => {
      const next = new URLSearchParams(searchParams.toString());
      if (tab === "overview") {
        next.delete("tab");
      } else {
        next.set("tab", tab);
      }
      if (participantId != null && Number.isInteger(participantId) && participantId > 0) {
        next.set("participant", String(participantId));
      } else {
        next.delete("participant");
      }
      const query = next.toString();
      router.replace(query ? `${pathname}?${query}` : pathname, { scroll: false });
    },
    [pathname, router, searchParams],
  );

  const load = useCallback(async () => {
    if (!Number.isInteger(campaignId) || campaignId < 1) {
      setError("Campaign not found.");
      setIsLoading(false);
      return;
    }

    setIsLoading(true);
    setError(null);

    try {
      const result = await campaignApi.get(campaignId);
      setCampaign(result);
    } catch (err) {
      setCampaign(null);
      setError(
        err instanceof ApiError
          ? friendlyCampaignLoadError(err.message)
          : "Unable to load this campaign.",
      );
    } finally {
      setIsLoading(false);
    }
  }, [campaignId]);

  const loadActivity = useCallback(async () => {
    if (!campaign || !Number.isInteger(campaignId) || campaignId < 1) return;

    try {
      const [participantsPage, applicationsPage, pendingAppsPage, invitationsPage, relatedPage] =
        await Promise.all([
          participantApi.listForCampaign(campaignId, { per_page: 50 }),
          applicationApi.listForCampaign(campaignId, { per_page: 5 }),
          applicationApi.listForCampaign(campaignId, { per_page: 1, status: "pending" }),
          invitationApi.listForCampaign(campaignId, { per_page: 5 }),
          creatorSearchApi
            .search(buildCampaignRelatedCreatorFilters(campaign, { per_page: 4 }))
            .catch(() => ({ creators: [] as SearchCreator[] })),
        ]);

      const paymentsNeedingAuthorization = participantsPage.participants.filter(
        (participant) => participantNeedsPaymentAuthorization(participant),
      ).length;

      setActivity({
        creators: participantsPage.meta.total,
        applications: applicationsPage.meta.total,
        pendingApplications: pendingAppsPage.meta.total,
        invitations: invitationsPage.meta.total,
        paymentsNeedingAuthorization,
      });
      setPreviewParticipants(participantsPage.participants.slice(0, 5));
      setPreviewApplications(applicationsPage.applications);
      setPreviewInvitations(invitationsPage.invitations);
      setRelatedCreators(relatedPage.creators);
    } catch {
      setActivity(null);
      setPreviewParticipants([]);
      setPreviewApplications([]);
      setPreviewInvitations([]);
      setRelatedCreators([]);
    }
  }, [campaign, campaignId]);

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

  useEffect(() => {
    if (!campaign || isEditing) return;
    void loadActivity();
  }, [campaign, isEditing, loadActivity]);

  async function handleSave(values: CampaignFormValues, _status: CampaignStatus) {
    if (!campaign) return;

    // Content update only — preserve current lifecycle status.
    const built = buildCampaignPayload(values, campaign.status);
    if ("errors" in built) {
      setFieldErrors(built.errors);
      return;
    }

    setBusyAction("save");
    setFieldErrors({});

    try {
      const updated = await campaignApi.update(campaign.id, built.payload);
      setCampaign(updated);
      setIsEditing(false);
      toast.success("Campaign updated.");
    } catch (err) {
      if (err instanceof ApiError && err.isValidation) {
        setFieldErrors(err.errors);
        toast.error(err.message);
      } else {
        toast.error(err instanceof ApiError ? err.message : "Unable to update campaign.");
      }
    } finally {
      setBusyAction(null);
    }
  }

  async function runLifecycleAction(action: CampaignLifecycleAction) {
    if (!campaign) return;

    setBusyPrimary(action);
    try {
      const updated = await campaignApi[action](campaign.id);
      setCampaign(updated);
      setIsEditing(false);
      const messages: Record<CampaignLifecycleAction, string> = {
        activate: "Campaign activated.",
        pause: "Campaign paused.",
        resume: "Campaign resumed.",
        complete: "Campaign completed.",
        cancel: "Campaign cancelled.",
      };
      toast.success(messages[action]);
    } catch (err) {
      toast.error(err instanceof ApiError ? err.message : `Unable to ${action} campaign.`);
    } finally {
      setBusyPrimary(null);
      setPendingConfirm(null);
    }
  }

  async function runDeleteDraft() {
    if (!campaign) return;

    setBusyPrimary("delete");
    try {
      const result = await campaignApi.remove(campaign.id);
      if (result.deleted) {
        toast.success("Draft deleted.");
        router.push("/dashboard/campaigns");
        return;
      }
      toast.error("Unable to delete draft.");
    } catch (err) {
      toast.error(err instanceof ApiError ? err.message : "Unable to delete draft.");
    } finally {
      setBusyPrimary(null);
      setPendingConfirm(null);
    }
  }

  function handlePrimaryAction(action: CampaignPrimaryAction) {
    if (action === "edit") {
      setIsEditing(true);
      setFieldErrors({});
      return;
    }

    if (campaignActionRequiresConfirmation(action)) {
      setPendingConfirm(action);
      return;
    }

    if (isCampaignLifecycleAction(action)) {
      void runLifecycleAction(action);
    }
  }

  function handleConfirmPending() {
    if (!pendingConfirm) return;
    if (pendingConfirm === "delete") {
      void runDeleteDraft();
      return;
    }
    if (isCampaignLifecycleAction(pendingConfirm)) {
      void runLifecycleAction(pendingConfirm);
    }
  }

  if (isLoading) {
    return (
      <DashboardPageContainer>
        <CampaignDetailSkeleton />
      </DashboardPageContainer>
    );
  }

  if (error || !campaign) {
    return (
      <DashboardPageContainer>
        <ErrorState
          title="Couldn’t load campaign"
          message={error ?? "Campaign not found."}
          action={
            <Button href="/dashboard/campaigns" size="sm" variant="secondary">
              <ArrowLeftIcon className="size-4" aria-hidden="true" />
              <span>Back to Campaigns</span>
            </Button>
          }
        />
      </DashboardPageContainer>
    );
  }

  const editable = campaignIsEditable(campaign.status);
  const audience = buildCampaignAudienceView(campaign);
  const discoverHref = campaignDiscoverHref(campaign);
  const nextAction = resolveCampaignNextAction({
    status: campaign.status,
    deliverableCount: campaignDeliverableUnitCount(campaign.deliverables),
    activity,
    discoverHref,
  });

  return (
    <DashboardPageContainer>
      {pendingConfirm ? (
        (() => {
          const copy = campaignConfirmCopy(pendingConfirm);
          if (!copy) return null;
          return (
            <ConfirmDialog
              title={copy.title}
              description={copy.description}
              confirmLabel={copy.confirmLabel}
              busy={busyPrimary !== null}
              onCancel={() => {
                if (busyPrimary !== null) return;
                setPendingConfirm(null);
              }}
              onConfirm={handleConfirmPending}
            />
          );
        })()
      ) : null}

      {!isEditing ? (
        <CampaignDetailHeader
          campaign={campaign}
          busyPrimary={busyPrimary}
          onPrimaryAction={handlePrimaryAction}
        />
      ) : (
        <div className="space-y-1">
          <Button
            size="sm"
            variant="secondary"
            onClick={() => {
              setIsEditing(false);
              setFieldErrors({});
            }}
          >
            <ArrowLeftIcon className="size-4" aria-hidden="true" />
            <span>Back to campaign</span>
          </Button>
          <h1 className="text-[1.25rem] font-semibold tracking-[-0.02em] text-primary">
            Edit {campaign.name}
          </h1>
        </div>
      )}

      {isEditing && editable ? (
        <div className="mt-4 rounded-pv border border-line bg-surface px-4 py-4 sm:px-5">
          <BrandCampaignForm
            mode="edit"
            initialValues={campaignToFormValues(campaign)}
            fieldErrors={fieldErrors}
            busyAction={busyAction}
            onSubmit={handleSave}
            onCancel={() => {
              setIsEditing(false);
              setFieldErrors({});
            }}
          />
        </div>
      ) : (
        <div className="mt-5 space-y-5">
          {nextAction ? (
            <CampaignNextActionCard
              nextAction={nextAction}
              busyPrimary={busyPrimary}
              onPrimaryAction={handlePrimaryAction}
              onGoToTab={setTab}
            />
          ) : null}

          <CampaignDetailTabs
            activeTab={activeTab}
            counts={
              activity
                ? {
                    applications: activity.pendingApplications,
                    payments: activity.paymentsNeedingAuthorization,
                    participants: activity.creators,
                  }
                : undefined
            }
            onTabChange={setTab}
          />

          {activeTab === "overview" ? (
            <div className="grid gap-6 xl:grid-cols-[minmax(0,1fr)_16.5rem] xl:items-start">
              <div className="min-w-0 space-y-5">
                <div className="space-y-8 rounded-pv border border-line bg-surface px-4 py-4 sm:px-5">
                  <CampaignAudienceSection audience={audience} />
                  <CampaignBriefDeliverables deliverables={campaign.deliverables} />
                  {!editable ? (
                    <EmptyState
                      variant="dashed"
                      title="This campaign is finished"
                      description="Completed and cancelled campaigns can’t be edited."
                    />
                  ) : null}
                </div>

                <CampaignActivityPreview
                  participants={previewParticipants}
                  applications={previewApplications}
                  invitations={previewInvitations}
                  relatedCreators={relatedCreators}
                  onGoToCreators={() => setTab("participants")}
                  onGoToApplications={() => setTab("applications")}
                />
              </div>

              <aside className="space-y-5 xl:sticky xl:top-4">
                <CampaignScheduleCard campaign={campaign} />
                <CampaignBudgetPanel campaign={campaign} />
              </aside>
            </div>
          ) : null}

          {activeTab === "applications" ? (
            <BrandCampaignApplicationsTab
              campaign={campaign}
              discoverHref={discoverHref}
              onApplicationAccepted={() => {
                void loadActivity();
                setTab("payments");
              }}
            />
          ) : null}

          {activeTab === "payments" ? (
            <BrandCampaignPaymentsTab
              campaignId={campaign.id}
              focusParticipantId={
                focusParticipantId != null && Number.isInteger(focusParticipantId)
                  ? focusParticipantId
                  : null
              }
            />
          ) : null}

          {activeTab === "deliverables" ? (
            <BrandCampaignDeliverablesTab
              campaignId={campaign.id}
              focusParticipantId={
                focusParticipantId != null && Number.isInteger(focusParticipantId)
                  ? focusParticipantId
                  : null
              }
            />
          ) : null}

          {activeTab === "participants" ? (
            <BrandCampaignParticipantsTab
              campaignId={campaign.id}
              discoverHref={discoverHref}
              onGoToApplications={() => setTab("applications")}
              onViewDeliverables={(participantId) => setTab("deliverables", participantId)}
              onViewPayment={(participantId) => setTab("payments", participantId)}
            />
          ) : null}
        </div>
      )}
    </DashboardPageContainer>
  );
}

export function BrandCampaignDetailPage() {
  return (
    <DashboardShell title="Campaign" allowedAccountTypes={BRAND_ONLY}>
      {() => (
        <Suspense
          fallback={
            <DashboardPageContainer>
              <CampaignDetailSkeleton />
            </DashboardPageContainer>
          }
        >
          <BrandCampaignDetailContent />
        </Suspense>
      )}
    </DashboardShell>
  );
}
