"use client";

import { useState } from "react";
import { useRouter } from "next/navigation";
import { buttonClass } from "@/components/ui";
import { formatPrice } from "@/lib/format";
import type { CampaignChannel } from "@/lib/types";
import type { AudienceEvent } from "@db/queries/campaign-audience";
import TicketAudiencePicker, { type TicketAudienceValue } from "../ticket-audience-picker";

// Audience select value for "buyers of an event, by ticket type".
const TICKETS = "__tickets";

export default function NewCampaignForm({
  segments,
  events,
  smsCostPerMessageCents,
}: {
  segments: { id: string; name: string }[];
  events: AudienceEvent[];
  smsCostPerMessageCents: number;
}) {
  const router = useRouter();

  const [name, setName] = useState("");
  const [channel, setChannel] = useState<CampaignChannel>("sms");
  const [segmentId, setSegmentId] = useState("");
  const [ticketAudience, setTicketAudience] = useState<TicketAudienceValue>({ eventId: "", ticketTypeIds: [] });
  const byTickets = segmentId === TICKETS;

  // Payload for both the estimate and the save.
  function audiencePayload(): { segmentId: string | null; ticketAudience: TicketAudienceValue | null } | string {
    if (!byTickets) return { segmentId: segmentId || null, ticketAudience: null };
    if (!ticketAudience.eventId) return "Choose the event whose buyers should get this";
    if (ticketAudience.ticketTypeIds.length === 0) return "Tick at least one ticket type";
    return { segmentId: null, ticketAudience };
  }
  const [subject, setSubject] = useState("");
  const [body, setBody] = useState("");
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);
  const [estimate, setEstimate] = useState<{ eligible: number; costCents: number } | null>(null);
  const [estimating, setEstimating] = useState(false);

  async function handleEstimate() {
    setError(null);
    const aud = audiencePayload();
    if (typeof aud === "string") {
      setError(aud);
      return;
    }
    setEstimating(true);
    const res = await fetch("/api/dashboard/campaigns/estimate", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ channel, ...aud }),
    });
    const data = await res.json();
    if (!res.ok) {
      setError(data.error ?? "Could not estimate");
      setEstimating(false);
      return;
    }
    setEstimate({ eligible: data.eligible, costCents: data.costCents });
    setEstimating(false);
  }

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    setLoading(true);
    setError(null);

    if (!body.trim()) {
      setError("Write a message first");
      setLoading(false);
      return;
    }
    if (channel === "email" && !subject.trim()) {
      setError("Email campaigns need a subject line");
      setLoading(false);
      return;
    }

    const aud = audiencePayload();
    if (typeof aud === "string") {
      setError(aud);
      setLoading(false);
      return;
    }

    const res = await fetch("/api/dashboard/campaigns", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        name: name.trim(),
        channel,
        ...aud,
        subject: channel === "email" ? subject.trim() : null,
        body: body.trim(),
      }),
    });
    const data = await res.json();

    if (!res.ok) {
      setError(data.error ?? "Could not create campaign");
      setLoading(false);
      return;
    }

    router.push(`/dashboard/campaigns/${data.id}`);
    router.refresh();
  }

  return (
    <form onSubmit={handleSubmit} className="space-y-4">
      <Field label="Name">
        <input
          required
          value={name}
          onChange={(e) => setName(e.target.value)}
          placeholder="e.g. July early-bird push"
          className="input"
        />
      </Field>

      <Field label="Channel">
        <select
          value={channel}
          onChange={(e) => {
            setChannel(e.target.value as CampaignChannel);
            setEstimate(null);
          }}
          className="input"
        >
          <option value="sms">SMS</option>
          <option value="email">Email</option>
        </select>
      </Field>

      <Field label="Audience">
        <select
          value={segmentId}
          onChange={(e) => {
            setSegmentId(e.target.value);
            setEstimate(null);
          }}
          className="input"
        >
          <option value="">All customers</option>
          <option value={TICKETS}>Buyers by ticket type (e.g. VIP)…</option>
          {segments.length > 0 && (
            <optgroup label="Saved segments">
              {segments.map((s) => (
                <option key={s.id} value={s.id}>
                  {s.name}
                </option>
              ))}
            </optgroup>
          )}
        </select>
      </Field>

      {byTickets && (
        <TicketAudiencePicker
          events={events}
          value={ticketAudience}
          onChange={(v) => {
            setTicketAudience(v);
            setEstimate(null);
          }}
        />
      )}

      {channel === "email" && (
        <Field label="Subject">
          <input
            required
            value={subject}
            onChange={(e) => setSubject(e.target.value)}
            placeholder="e.g. Tickets for our next show are live"
            className="input"
          />
        </Field>
      )}

      <Field
        label="Message"
        hint={
          channel === "sms"
            ? `Plain text — ${formatPrice(smsCostPerMessageCents, "kes")} per message, more for longer texts`
            : "Plain text; a footer with an unsubscribe link is added automatically"
        }
      >
        <textarea
          required
          rows={6}
          value={body}
          onChange={(e) => setBody(e.target.value)}
          placeholder={channel === "sms" ? "Grab your tickets before they're gone…" : "Write your update here…"}
          className="input"
        />
      </Field>

      <div className="flex flex-wrap items-center gap-3">
        <button
          type="button"
          onClick={handleEstimate}
          disabled={estimating}
          className={buttonClass("secondary")}
        >
          {estimating ? "Checking…" : "Preview audience & cost"}
        </button>
        {estimate && (
          <p className="text-sm text-be-muted">
            {estimate.eligible} opted-in recipient{estimate.eligible === 1 ? "" : "s"}
            {channel === "sms" ? ` — est. ${formatPrice(estimate.costCents, "kes")}` : ""}
          </p>
        )}
      </div>

      {error && <p className="text-sm text-red-600">{error}</p>}

      <button type="submit" disabled={loading} className={buttonClass("primary")}>
        {loading ? "Saving…" : "Save draft"}
      </button>
    </form>
  );
}

function Field({
  label,
  hint,
  children,
}: {
  label: string;
  hint?: string;
  children: React.ReactNode;
}) {
  return (
    <div>
      <label className="block text-sm font-medium mb-1 text-be-text">
        {label} {hint && <span className="font-normal text-be-muted">— {hint}</span>}
      </label>
      {children}
    </div>
  );
}
