"use client";

import { useCallback, useEffect, useState, type FormEvent } from "react";
import Link from "next/link";
import { toast } from "sonner";
import { Button } from "@/components/Button";
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 { fieldClassName, textareaClassName } from "@/components/ui/field-styles";
import { PageHeader, SectionHeader } from "@/components/ui/PageHeader";
import { Skeleton } from "@/components/ui/Skeleton";
import { StatusBadge } from "@/components/ui/StatusBadge";
import { ApiError } from "@/lib/api";
import { deliverableApi } from "@/lib/api/campaign-deliverables";
import { participantApi } from "@/lib/api/campaign-participation";
import {
  canSubmitDeliverable,
  deliverableStatusBadgeVariant,
  deliverableStatusLabel,
  submissionStatusBadgeVariant,
  submissionStatusLabel,
} from "@/lib/campaign-deliverables";
import { campaignDeliverableLabel } from "@/lib/campaigns";
import {
  creatorEarningBadgeVariant,
  creatorEarningUiLabel,
  creatorEarningUiStatus,
  creatorTransferFailedGuidance,
  creatorTransferFailedShowsPayoutLink,
} from "@/lib/earnings";
import { formatDateShort, formatMoneyMinor } from "@/lib/format";
import { socialProviderLabel } from "@/lib/social-providers";
import type {
  CampaignSubmission,
  ParticipantDeliverable,
} from "@/types/campaign-deliverables";
import type { CampaignParticipant } from "@/types/campaign-participation";

const CREATOR_ONLY = ["creator"] as const;

function ListSkeleton() {
  return (
    <div className="space-y-3">
      {Array.from({ length: 3 }).map((_, index) => (
        <div key={index} className="rounded-pv border border-line bg-surface px-3 py-3">
          <Skeleton className="h-4 w-48" />
          <Skeleton className="mt-2 h-3 w-full" />
          <Skeleton className="mt-2 h-3 w-2/3" />
        </div>
      ))}
    </div>
  );
}

function SubmissionHistory({ submissions }: { submissions: CampaignSubmission[] }) {
  if (submissions.length === 0) {
    return <p className="text-[0.8125rem] text-ink-40">No submissions yet.</p>;
  }

  return (
    <ul className="space-y-2">
      {submissions.map((submission) => (
        <li
          key={submission.id}
          className="rounded-pv border border-line bg-bg px-3 py-2 text-[0.8125rem]"
        >
          <div className="flex flex-wrap items-center justify-between gap-2">
            <p className="font-medium text-primary">Version {submission.version}</p>
            <StatusBadge variant={submissionStatusBadgeVariant(submission.status)}>
              {submissionStatusLabel(submission.status)}
            </StatusBadge>
          </div>
          {submission.content_url ? (
            <p className="mt-1 break-all text-ink-60">
              <a
                href={submission.content_url}
                target="_blank"
                rel="noopener noreferrer"
                className="underline decoration-line underline-offset-2 hover:text-primary"
              >
                {submission.content_url}
              </a>
            </p>
          ) : null}
          {submission.caption ? (
            <p className="mt-1 whitespace-pre-wrap text-ink-60">{submission.caption}</p>
          ) : null}
          {submission.notes ? (
            <p className="mt-1 whitespace-pre-wrap text-ink-40">Notes: {submission.notes}</p>
          ) : null}
          {submission.review_notes ? (
            <p className="mt-1 whitespace-pre-wrap text-amber-900">
              Review: {submission.review_notes}
            </p>
          ) : null}
          <p className="mt-1 text-[0.75rem] text-ink-40">
            Submitted {formatDateShort(submission.submitted_at)}
            {submission.reviewed_at
              ? ` · Reviewed ${formatDateShort(submission.reviewed_at)}`
              : ""}
          </p>
        </li>
      ))}
    </ul>
  );
}

function DeliverableCard({
  deliverable,
  campaignAcceptsSubmissions,
  participantActive,
  paymentMethodAuthorized,
  busyKey,
  onSubmitted,
}: {
  deliverable: ParticipantDeliverable;
  campaignAcceptsSubmissions: boolean;
  participantActive: boolean;
  paymentMethodAuthorized: boolean;
  busyKey: string | null;
  onSubmitted: () => Promise<void>;
}) {
  const [showHistory, setShowHistory] = useState(false);
  const [history, setHistory] = useState<CampaignSubmission[] | null>(null);
  const [historyError, setHistoryError] = useState<string | null>(null);
  const [showForm, setShowForm] = useState(false);
  const [contentUrl, setContentUrl] = useState("");
  const [caption, setCaption] = useState("");
  const [notes, setNotes] = useState("");
  const [submitting, setSubmitting] = useState(false);

  const canSubmit =
    participantActive &&
    campaignAcceptsSubmissions &&
    paymentMethodAuthorized &&
    canSubmitDeliverable(deliverable.status);

  async function loadHistory() {
    setHistoryError(null);
    try {
      const result = await deliverableApi.listSubmissions(deliverable.id);
      setHistory(result.submissions);
    } catch (err) {
      setHistoryError(err instanceof ApiError ? err.message : "Unable to load history.");
    }
  }

  async function toggleHistory() {
    const next = !showHistory;
    setShowHistory(next);
    if (next && history === null) {
      await loadHistory();
    }
  }

  async function handleSubmit(event: FormEvent) {
    event.preventDefault();
    const trimmedUrl = contentUrl.trim();
    const trimmedCaption = caption.trim();
    if (!trimmedUrl && !trimmedCaption) {
      toast.error("Provide at least a content URL or caption.");
      return;
    }
    setSubmitting(true);
    try {
      await deliverableApi.createSubmission(deliverable.id, {
        content_url: trimmedUrl || null,
        caption: trimmedCaption || null,
        notes: notes.trim() || null,
      });
      toast.success("Content submitted for review.");
      setShowForm(false);
      setContentUrl("");
      setCaption("");
      setNotes("");
      setHistory(null);
      await onSubmitted();
    } catch (err) {
      toast.error(err instanceof ApiError ? err.message : "Unable to submit content.");
    } finally {
      setSubmitting(false);
    }
  }

  const latest = deliverable.latest_submission;
  const title =
    deliverable.title?.trim() || campaignDeliverableLabel(deliverable.type);

  return (
    <article className="space-y-3 rounded-pv border border-line bg-surface px-3 py-3 sm:px-4">
      <div className="flex flex-wrap items-start justify-between gap-2">
        <div className="min-w-0">
          <h3 className="text-[0.9375rem] font-semibold text-primary">{title}</h3>
          <p className="mt-0.5 text-[0.8125rem] text-ink-60">
            {socialProviderLabel(deliverable.platform)}
            {` · Qty ${deliverable.quantity}`}
            {deliverable.due_at ? ` · Due ${formatDateShort(deliverable.due_at)}` : ""}
          </p>
        </div>
        <StatusBadge variant={deliverableStatusBadgeVariant(deliverable.status)}>
          {deliverableStatusLabel(deliverable.status)}
        </StatusBadge>
      </div>

      <p className="whitespace-pre-wrap text-[0.8125rem] text-ink-60">
        {deliverable.description?.trim() || "No description provided."}
      </p>

      {(deliverable.requirements ||
        deliverable.creator_instructions ||
        deliverable.reference_url ||
        deliverable.call_to_action) && (
        <dl className="space-y-1.5 rounded-pv border border-line bg-bg px-3 py-2 text-[0.8125rem]">
          {deliverable.requirements ? (
            <div>
              <dt className="text-[0.6875rem] uppercase tracking-[0.06em] text-ink-40">
                Requirements
              </dt>
              <dd className="mt-0.5 whitespace-pre-wrap text-ink-60">{deliverable.requirements}</dd>
            </div>
          ) : null}
          {deliverable.creator_instructions ? (
            <div>
              <dt className="text-[0.6875rem] uppercase tracking-[0.06em] text-ink-40">
                Creator instructions
              </dt>
              <dd className="mt-0.5 whitespace-pre-wrap text-ink-60">
                {deliverable.creator_instructions}
              </dd>
            </div>
          ) : null}
          {deliverable.reference_url ? (
            <div>
              <dt className="text-[0.6875rem] uppercase tracking-[0.06em] text-ink-40">Reference</dt>
              <dd className="mt-0.5 break-all">
                <a
                  href={deliverable.reference_url}
                  target="_blank"
                  rel="noopener noreferrer"
                  className="underline decoration-line underline-offset-2 hover:text-primary"
                >
                  {deliverable.reference_url}
                </a>
              </dd>
            </div>
          ) : null}
          {deliverable.call_to_action ? (
            <div>
              <dt className="text-[0.6875rem] uppercase tracking-[0.06em] text-ink-40">
                Call to action
              </dt>
              <dd className="mt-0.5 text-ink-60">{deliverable.call_to_action}</dd>
            </div>
          ) : null}
        </dl>
      )}

      {latest ? (
        <div className="rounded-pv border border-line bg-bg px-3 py-2 text-[0.8125rem]">
          <div className="flex flex-wrap items-center justify-between gap-2">
            <p className="font-medium text-primary">Latest · v{latest.version}</p>
            <StatusBadge variant={submissionStatusBadgeVariant(latest.status)}>
              {submissionStatusLabel(latest.status)}
            </StatusBadge>
          </div>
          {latest.review_notes ? (
            <p className="mt-1 whitespace-pre-wrap text-amber-900">
              Review note: {latest.review_notes}
            </p>
          ) : null}
        </div>
      ) : null}

      <div className="flex flex-wrap gap-2">
        {canSubmit ? (
          <Button size="sm" onClick={() => setShowForm((value) => !value)}>
            {deliverable.status === "revision_requested" ? "Resubmit" : "Submit content"}
          </Button>
        ) : null}
        <Button size="sm" variant="secondary" onClick={() => void toggleHistory()}>
          {showHistory ? "Hide history" : "View history"}
        </Button>
      </div>

      {!campaignAcceptsSubmissions && canSubmitDeliverable(deliverable.status) ? (
        <p className="text-[0.8125rem] text-ink-40">
          This campaign is not accepting new submissions right now.
        </p>
      ) : null}

      {participantActive &&
      campaignAcceptsSubmissions &&
      !paymentMethodAuthorized &&
      canSubmitDeliverable(deliverable.status) ? (
        <p className="text-[0.8125rem] text-ink-40">
          Waiting for the brand to authorize a payment method. You can submit once booking is authorized.
        </p>
      ) : null}

      {showForm ? (
        <form
          className="space-y-3 rounded-pv border border-line bg-bg px-3 py-3"
          onSubmit={handleSubmit}
        >
          <div>
            <label
              className="text-[0.75rem] font-medium text-ink-60"
              htmlFor={`url-${deliverable.id}`}
            >
              Content URL
            </label>
            <input
              id={`url-${deliverable.id}`}
              className={fieldClassName}
              type="url"
              value={contentUrl}
              onChange={(event) => setContentUrl(event.target.value)}
              placeholder="https://"
            />
          </div>
          <div>
            <label
              className="text-[0.75rem] font-medium text-ink-60"
              htmlFor={`caption-${deliverable.id}`}
            >
              Caption
            </label>
            <textarea
              id={`caption-${deliverable.id}`}
              className={textareaClassName}
              rows={3}
              value={caption}
              onChange={(event) => setCaption(event.target.value)}
            />
          </div>
          <div>
            <label
              className="text-[0.75rem] font-medium text-ink-60"
              htmlFor={`notes-${deliverable.id}`}
            >
              Notes for brand
            </label>
            <textarea
              id={`notes-${deliverable.id}`}
              className={textareaClassName}
              rows={2}
              value={notes}
              onChange={(event) => setNotes(event.target.value)}
            />
          </div>
          <p className="text-[0.75rem] text-ink-40">
            Provide a content URL and/or caption for brand review. Submitting does not publish
            to social platforms.
          </p>
          <div className="flex flex-wrap gap-2">
            <Button size="sm" type="submit" disabled={submitting || busyKey !== null}>
              {submitting ? "Submitting…" : "Submit for review"}
            </Button>
            <Button
              size="sm"
              type="button"
              variant="secondary"
              disabled={submitting}
              onClick={() => setShowForm(false)}
            >
              Cancel
            </Button>
          </div>
        </form>
      ) : null}

      {showHistory ? (
        <div className="space-y-2">
          <SectionHeader title="Submission history" />
          {historyError ? (
            <ErrorState title="Unable to load history" message={historyError} />
          ) : null}
          {history === null && !historyError ? <Skeleton className="h-16 w-full" /> : null}
          {history ? <SubmissionHistory submissions={history} /> : null}
        </div>
      ) : null}
    </article>
  );
}

function CreatorEarningStatusCard({ participant }: { participant: CampaignParticipant }) {
  const earning = participant.earning;
  if (!earning) {
    return null;
  }

  const uiStatus = creatorEarningUiStatus(earning);
  if (!uiStatus) {
    return null;
  }

  return (
    <div className="mt-3 rounded-pv border border-line bg-surface px-3 py-3">
      <div className="flex flex-wrap items-center justify-between gap-2">
        <StatusBadge variant={creatorEarningBadgeVariant(uiStatus)}>
          {creatorEarningUiLabel(uiStatus)}
        </StatusBadge>
        <p className="text-[0.8125rem] text-ink-60">
          Your earnings {formatMoneyMinor(earning.amount, earning.currency)}
        </p>
      </div>
      {earning.gross_amount > 0 ? (
        <p className="mt-2 text-[0.75rem] text-ink-60">
          Creator compensation {formatMoneyMinor(earning.gross_amount, earning.currency)}
          {earning.platform_fee_amount > 0 && earning.financial_model === "legacy_creator_commission"
            ? ` · Postvertise commission −${formatMoneyMinor(earning.platform_fee_amount, earning.currency)}`
            : null}
          {earning.platform_fee_amount > 0 && earning.financial_model === "additive_platform_fee"
            ? ` · Platform fee not deducted from earnings`
            : null}
        </p>
      ) : null}
      {uiStatus === "payout_setup_required" ? (
        <p className="mt-2 text-[0.8125rem] text-ink-60">
          <Link
            href="/dashboard/settings/payouts"
            className="underline decoration-line underline-offset-2 hover:text-primary"
          >
            Set up payouts
          </Link>{" "}
          so this earning can be transferred.
        </p>
      ) : null}
      {uiStatus === "transfer_failed" ? (
        <p className="mt-2 text-[0.8125rem] text-ink-60">
          {creatorTransferFailedGuidance(earning)}
          {creatorTransferFailedShowsPayoutLink(earning) ? (
            <>
              {" "}
              <Link
                href="/dashboard/settings/payouts"
                className="underline decoration-line underline-offset-2 hover:text-primary"
              >
                Check payout setup
              </Link>
              .
            </>
          ) : null}
        </p>
      ) : null}
      {uiStatus === "transfer_complete" ? (
        <p className="mt-2 text-[0.8125rem] text-ink-60">
          Funds were transferred to your connected Stripe account. This is not a bank
          payout confirmation.
        </p>
      ) : null}
    </div>
  );
}

function CreatorParticipantDeliverablesContent({ participantId }: { participantId: number }) {
  const [participant, setParticipant] = useState<CampaignParticipant | null>(null);
  const [deliverables, setDeliverables] = useState<ParticipantDeliverable[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [busyKey, setBusyKey] = useState<string | null>(null);

  const load = useCallback(async () => {
    setIsLoading(true);
    setError(null);
    try {
      const [participantResult, deliverableResult] = await Promise.all([
        participantApi.get(participantId),
        deliverableApi.listForParticipant(participantId),
      ]);
      setParticipant(participantResult);
      setDeliverables(deliverableResult.deliverables);
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "Unable to load deliverables.");
    } finally {
      setIsLoading(false);
    }
  }, [participantId]);

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

  const campaignStatus = participant?.campaign.status ?? null;
  const campaignAcceptsSubmissions = campaignStatus === "active";
  const participantActive = participant?.status === "active";
  const paymentMethodAuthorized =
    participant?.payment_method_authorized === true || participant?.payment_confirmed === true;

  return (
    <DashboardPageContainer>
      <div className="mb-4">
        <Link
          href="/dashboard/opportunities"
          className="text-[0.8125rem] text-ink-60 underline decoration-line underline-offset-2 hover:text-primary"
        >
          ← Back to opportunities
        </Link>
      </div>

      <PageHeader description="Submit content for your assigned deliverables. Submissions are for brand review only and are not published automatically." />

      {participant ? (
        <SectionHeader
          className="mt-4"
          title={participant.campaign.name}
          description={
            participant.campaign.brand?.company_name ||
            participant.campaign.brand?.username ||
            undefined
          }
        />
      ) : null}

      {participant ? <CreatorEarningStatusCard participant={participant} /> : null}

      {isLoading ? <ListSkeleton /> : null}
      {!isLoading && error ? (
        <ErrorState title="Unable to load deliverables" message={error} />
      ) : null}
      {!isLoading && !error && deliverables.length === 0 ? (
        <EmptyState
          title="No deliverables assigned"
          description="Assigned work for this campaign will appear here."
        />
      ) : null}
      {!isLoading && !error ? (
        <div className="space-y-3">
          {deliverables.map((deliverable) => (
            <DeliverableCard
              key={deliverable.id}
              deliverable={deliverable}
              campaignAcceptsSubmissions={campaignAcceptsSubmissions}
              participantActive={participantActive}
              paymentMethodAuthorized={paymentMethodAuthorized}
              busyKey={busyKey}
              onSubmitted={async () => {
                setBusyKey(`reload-${deliverable.id}`);
                try {
                  await load();
                } finally {
                  setBusyKey(null);
                }
              }}
            />
          ))}
        </div>
      ) : null}
    </DashboardPageContainer>
  );
}

export function CreatorParticipantDeliverablesPage({ participantId }: { participantId: number }) {
  return (
    <DashboardShell title="Deliverables" allowedAccountTypes={CREATOR_ONLY}>
      {() => <CreatorParticipantDeliverablesContent participantId={participantId} />}
    </DashboardShell>
  );
}
