"use client";

import { useCallback, useEffect, useState, type FormEvent } from "react";
import { toast } from "sonner";
import { Button } from "@/components/Button";
import { EmptyState } from "@/components/ui/EmptyState";
import { ErrorState } from "@/components/ui/ErrorState";
import { textareaClassName } from "@/components/ui/field-styles";
import { Skeleton } from "@/components/ui/Skeleton";
import { StatusBadge } from "@/components/ui/StatusBadge";
import { ApiError } from "@/lib/api";
import { deliverableApi, submissionApi } from "@/lib/api/campaign-deliverables";
import {
  canReviewSubmission,
  deliverableStatusBadgeVariant,
  deliverableStatusLabel,
  submissionStatusBadgeVariant,
  submissionStatusLabel,
} from "@/lib/campaign-deliverables";
import { sortSubmissionsChronologically } from "@/lib/campaign-management";
import { campaignDeliverableLabel } from "@/lib/campaigns";
import { formatDateShort, formatRelativeTime } from "@/lib/format";
import { socialProviderLabel } from "@/lib/social-providers";
import type {
  CampaignSubmission,
  ParticipantDeliverable,
} from "@/types/campaign-deliverables";

function ListSkeleton() {
  return (
    <div className="space-y-2">
      <Skeleton className="h-4 w-40" />
      <Skeleton className="h-20 w-full" />
    </div>
  );
}

function SubmissionDetails({ submission }: { submission: CampaignSubmission }) {
  return (
    <div className="space-y-1 text-[0.8125rem]">
      {submission.submitted_at ? (
        <p className="text-ink-40">Submitted {formatRelativeTime(submission.submitted_at)}</p>
      ) : null}
      {submission.content_url ? (
        <p className="break-all">
          <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="whitespace-pre-wrap text-ink-60">{submission.caption}</p>
      ) : null}
      {submission.notes ? (
        <p className="whitespace-pre-wrap text-ink-40">Notes: {submission.notes}</p>
      ) : null}
      {submission.reviewed_at ? (
        <p className="text-ink-40">Reviewed {formatRelativeTime(submission.reviewed_at)}</p>
      ) : null}
      {submission.review_notes ? (
        <p className="whitespace-pre-wrap text-amber-900">Review: {submission.review_notes}</p>
      ) : null}
    </div>
  );
}

export function BrandParticipantDeliverablesPanel({
  campaignId,
  participantId,
  creatorLabel,
}: {
  campaignId: number;
  participantId: number;
  creatorLabel: string;
}) {
  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 [expandedId, setExpandedId] = useState<number | null>(null);
  const [histories, setHistories] = useState<Record<number, CampaignSubmission[]>>({});
  const [revisionNotes, setRevisionNotes] = useState<Record<number, string>>({});

  const load = useCallback(async () => {
    setIsLoading(true);
    setError(null);
    try {
      const result = await deliverableApi.listForCampaignParticipant(campaignId, participantId);
      setDeliverables(result.deliverables);
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "Unable to load deliverables.");
    } finally {
      setIsLoading(false);
    }
  }, [campaignId, participantId]);

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

  async function ensureHistory(deliverableId: number) {
    if (histories[deliverableId]) return;
    try {
      const result = await deliverableApi.listSubmissions(deliverableId);
      setHistories((current) => ({
        ...current,
        [deliverableId]: sortSubmissionsChronologically(result.submissions),
      }));
    } catch (err) {
      toast.error(err instanceof ApiError ? err.message : "Unable to load submission history.");
    }
  }

  async function runAction(key: string, action: () => Promise<void>, success: string) {
    setBusyKey(key);
    try {
      await action();
      toast.success(success);
      setHistories({});
      await load();
    } catch (err) {
      toast.error(err instanceof ApiError ? err.message : "Something went wrong.");
    } finally {
      setBusyKey(null);
    }
  }

  async function handleRequestRevision(
    event: FormEvent,
    submissionId: number,
    deliverableId: number,
  ) {
    event.preventDefault();
    const notes = (revisionNotes[submissionId] ?? "").trim();
    if (!notes) {
      toast.error("Add review notes for the revision request.");
      return;
    }
    await runAction(
      `revision-${submissionId}`,
      async () => {
        await submissionApi.requestRevision(submissionId, notes);
        setRevisionNotes((current) => ({ ...current, [submissionId]: "" }));
        await ensureHistory(deliverableId);
      },
      "Revision requested.",
    );
  }

  if (isLoading) return <ListSkeleton />;
  if (error) {
    return <ErrorState title="Unable to load deliverables" message={error} />;
  }
  if (deliverables.length === 0) {
    return (
      <EmptyState
        title="No deliverables assigned yet"
        description={`Assigned work for ${creatorLabel} will appear here.`}
      />
    );
  }

  return (
    <ul className="space-y-3">
      {deliverables.map((deliverable) => {
        const latest = deliverable.latest_submission;
        const expanded = expandedId === deliverable.id;
        const title =
          deliverable.title?.trim() || campaignDeliverableLabel(deliverable.type);
        const isApproved = deliverable.status === "approved";
        const needsCreatorAction = deliverable.status === "revision_requested";

        return (
          <li
            key={deliverable.id}
            className={`space-y-3 rounded-pv border px-3 py-3 ${
              isApproved
                ? "border-emerald-200 bg-emerald-50/40"
                : needsCreatorAction
                  ? "border-amber-200 bg-amber-50/40"
                  : "border-line bg-surface"
            }`}
          >
            <div className="flex flex-wrap items-start justify-between gap-2">
              <div>
                <p className="font-medium text-primary">{title}</p>
                <p className="text-[0.75rem] text-ink-40">
                  {socialProviderLabel(deliverable.platform)}
                  {` · ${campaignDeliverableLabel(deliverable.type)}`}
                  {` · Qty ${deliverable.quantity}`}
                  {deliverable.due_at ? ` · Due ${formatDateShort(deliverable.due_at)}` : ""}
                </p>
              </div>
              <StatusBadge variant={deliverableStatusBadgeVariant(deliverable.status)}>
                {deliverableStatusLabel(deliverable.status)}
              </StatusBadge>
            </div>

            {needsCreatorAction ? (
              <p className="text-[0.8125rem] font-medium text-amber-900">
                Creator action required — waiting for a revised submission.
              </p>
            ) : null}
            {isApproved ? (
              <p className="text-[0.8125rem] font-medium text-emerald-800">
                Deliverable completed.
              </p>
            ) : null}

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

            {(deliverable.creator_instructions || deliverable.reference_url) && (
              <dl className="space-y-1.5 rounded-pv border border-line bg-bg px-3 py-2 text-[0.8125rem]">
                {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}
              </dl>
            )}

            {latest ? (
              <div className="rounded-pv border border-line bg-bg px-3 py-2">
                <div className="mb-2 flex flex-wrap items-center justify-between gap-2">
                  <p className="text-[0.8125rem] font-medium text-primary">
                    Latest submission · Version {latest.version}
                  </p>
                  <StatusBadge variant={submissionStatusBadgeVariant(latest.status)}>
                    {submissionStatusLabel(latest.status)}
                  </StatusBadge>
                </div>
                <SubmissionDetails submission={latest} />

                {canReviewSubmission(latest.status) ? (
                  <div className="mt-3 space-y-2">
                    <div className="flex flex-wrap gap-2">
                      <Button
                        size="sm"
                        disabled={busyKey === `approve-${latest.id}`}
                        onClick={() =>
                          void runAction(
                            `approve-${latest.id}`,
                            async () => {
                              await submissionApi.approve(latest.id);
                            },
                            "Submission approved.",
                          )
                        }
                      >
                        Approve
                      </Button>
                    </div>
                    <form
                      className="space-y-2"
                      onSubmit={(event) =>
                        void handleRequestRevision(event, latest.id, deliverable.id)
                      }
                    >
                      <label
                        className="text-[0.75rem] font-medium text-ink-60"
                        htmlFor={`revision-${latest.id}`}
                      >
                        Revision notes
                      </label>
                      <textarea
                        id={`revision-${latest.id}`}
                        className={textareaClassName}
                        rows={2}
                        value={revisionNotes[latest.id] ?? ""}
                        onChange={(event) =>
                          setRevisionNotes((current) => ({
                            ...current,
                            [latest.id]: event.target.value,
                          }))
                        }
                        placeholder="What should the creator change?"
                      />
                      <Button
                        size="sm"
                        variant="secondary"
                        type="submit"
                        disabled={busyKey === `revision-${latest.id}`}
                      >
                        Request revision
                      </Button>
                    </form>
                  </div>
                ) : null}
              </div>
            ) : (
              <EmptyState
                variant="dashed"
                title="No submissions yet"
                description="Submitted content will appear here for review."
              />
            )}

            <Button
              size="sm"
              variant="secondary"
              onClick={() => {
                const next = expanded ? null : deliverable.id;
                setExpandedId(next);
                if (next !== null) void ensureHistory(deliverable.id);
              }}
            >
              {expanded ? "Hide submission history" : "View submission history"}
            </Button>

            {expanded ? (
              <div className="space-y-2">
                {(histories[deliverable.id] ?? []).length === 0 ? (
                  <EmptyState
                    variant="dashed"
                    title="No submissions yet"
                    description="Submission versions will appear here chronologically."
                  />
                ) : (
                  (histories[deliverable.id] ?? []).map((submission) => (
                    <div
                      key={submission.id}
                      className="rounded-pv border border-line bg-bg px-3 py-2"
                    >
                      <div className="mb-2 flex flex-wrap items-center justify-between gap-2">
                        <p className="text-[0.8125rem] font-medium text-primary">
                          Version {submission.version}
                        </p>
                        <StatusBadge variant={submissionStatusBadgeVariant(submission.status)}>
                          {submissionStatusLabel(submission.status)}
                        </StatusBadge>
                      </div>
                      <SubmissionDetails submission={submission} />
                    </div>
                  ))
                )}
              </div>
            ) : null}
          </li>
        );
      })}
    </ul>
  );
}
