"use client";

import { useCallback, useEffect, useId, useState, type FormEvent } from "react";
import { toast } from "sonner";
import { Button } from "@/components/Button";
import { fieldClassName } from "@/components/ui/field-styles";
import { ApiError } from "@/lib/api";
import { invitationApi } from "@/lib/api/campaign-participation";
import { campaignApi } from "@/lib/api/campaigns";
import { defaultInvitationMessage } from "@/lib/campaign-participation";
import type { CampaignListItem } from "@/types/campaign";

/**
 * Compact invite flow used from Discover: pick an active campaign + invite by username.
 */
export function InviteCreatorDialog({
  username,
  open,
  onClose,
  preferredCampaignId = null,
  onSent,
}: {
  username: string;
  open: boolean;
  onClose: () => void;
  preferredCampaignId?: number | null;
  /** Called after a successful invite (before close). */
  onSent?: () => void;
}) {
  const titleId = useId();
  const [campaigns, setCampaigns] = useState<CampaignListItem[]>([]);
  const [campaignId, setCampaignId] = useState<number | "">("");
  const [message, setMessage] = useState("");
  const [messageTouched, setMessageTouched] = useState(false);
  const [isLoading, setIsLoading] = useState(false);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [loadError, setLoadError] = useState<string | null>(null);

  const loadCampaigns = useCallback(async () => {
    setIsLoading(true);
    setLoadError(null);
    try {
      const result = await campaignApi.list({ per_page: 50 });
      const active = result.campaigns.filter((item) => item.status === "active");
      setCampaigns(active);
      const preferred =
        preferredCampaignId != null && active.some((item) => item.id === preferredCampaignId)
          ? preferredCampaignId
          : (active[0]?.id ?? "");
      setCampaignId(preferred);
    } catch (err) {
      setLoadError(err instanceof ApiError ? err.message : "Unable to load campaigns.");
      setCampaigns([]);
      setCampaignId("");
    } finally {
      setIsLoading(false);
    }
  }, [preferredCampaignId]);

  useEffect(() => {
    if (!open) return;
    setMessageTouched(false);
    setMessage(defaultInvitationMessage({ username }));
    void loadCampaigns();
  }, [open, username, loadCampaigns]);

  useEffect(() => {
    if (!open || messageTouched || isLoading) return;
    const selected = campaigns.find((item) => item.id === campaignId);
    setMessage(
      defaultInvitationMessage({
        username,
        campaignName: selected?.name,
      }),
    );
  }, [open, messageTouched, isLoading, campaigns, campaignId, username]);

  if (!open) {
    return null;
  }

  async function handleSubmit(event: FormEvent) {
    event.preventDefault();
    if (typeof campaignId !== "number") {
      toast.error("Select an active campaign.");
      return;
    }

    setIsSubmitting(true);
    try {
      await invitationApi.create(campaignId, {
        username,
        message: message.trim() || null,
      });
      toast.success(`Invitation sent to @${username}.`);
      onSent?.();
      onClose();
    } catch (err) {
      toast.error(err instanceof ApiError ? err.message : "Unable to send invitation.");
    } finally {
      setIsSubmitting(false);
    }
  }

  return (
    <div className="fixed inset-0 z-50 flex items-end justify-center bg-black/40 p-4 sm:items-center">
      <button
        type="button"
        className="absolute inset-0 cursor-default"
        aria-label="Close invite dialog"
        onClick={onClose}
      />
      <div
        role="dialog"
        aria-modal="true"
        aria-labelledby={titleId}
        className="relative z-10 w-full max-w-md rounded-pv border border-line bg-surface p-4 shadow-lg"
      >
        <h2 id={titleId} className="text-[1rem] font-semibold text-primary">
          Invite @{username}
        </h2>
        <p className="mt-1 text-[0.8125rem] text-ink-60">
          Choose an active campaign to send an invitation.
        </p>

        {isLoading ? (
          <p className="mt-4 text-[0.8125rem] text-ink-60">Loading campaigns…</p>
        ) : loadError ? (
          <p className="mt-4 text-[0.8125rem] text-red-700">{loadError}</p>
        ) : campaigns.length === 0 ? (
          <p className="mt-4 text-[0.8125rem] text-ink-60">
            You need an active campaign before inviting creators.
          </p>
        ) : (
          <form className="mt-4 space-y-3" onSubmit={(event) => void handleSubmit(event)}>
            <label className="block">
              <span className="mb-1 block text-[0.6875rem] font-medium uppercase tracking-[0.06em] text-ink-40">
                Campaign
              </span>
              <select
                className={fieldClassName}
                value={campaignId === "" ? "" : String(campaignId)}
                onChange={(event) => {
                  const value = event.target.value;
                  setCampaignId(value ? Number.parseInt(value, 10) : "");
                }}
              >
                {campaigns.map((campaign) => (
                  <option key={campaign.id} value={campaign.id}>
                    {campaign.name}
                  </option>
                ))}
              </select>
            </label>
            <label className="block">
              <span className="mb-1 block text-[0.6875rem] font-medium uppercase tracking-[0.06em] text-ink-40">
                Message (optional)
              </span>
              <textarea
                className={fieldClassName}
                rows={4}
                maxLength={2000}
                value={message}
                onChange={(event) => {
                  setMessageTouched(true);
                  setMessage(event.target.value);
                }}
              />
              <span className="mt-1 block text-[0.75rem] text-ink-40">
                Suggested message — edit or clear before sending.
              </span>
            </label>
            <div className="flex flex-wrap gap-2">
              <Button type="submit" size="sm" disabled={isSubmitting}>
                {isSubmitting ? "Sending…" : "Send invitation"}
              </Button>
              <Button type="button" size="sm" variant="secondary" onClick={onClose}>
                Cancel
              </Button>
            </div>
          </form>
        )}

        {campaigns.length === 0 && !isLoading ? (
          <div className="mt-4">
            <Button type="button" size="sm" variant="secondary" onClick={onClose}>
              Close
            </Button>
          </div>
        ) : null}
      </div>
    </div>
  );
}
