"use client";

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

type ConditionType = SegmentCondition["type"];

// One row's worth of form state, kept as strings for easy binding; converted
// to a typed SegmentCondition in toCondition() below.
interface ConditionDraft {
  type: ConditionType;
  eventId: string;
  ticketTypeIds: string[];
  spendKes: string;
}

function emptyCondition(): ConditionDraft {
  return { type: "bought_event", eventId: "", ticketTypeIds: [], spendKes: "" };
}

function toCondition(draft: ConditionDraft): SegmentCondition | null {
  if (draft.type === "bought_event") {
    return draft.eventId ? { type: "bought_event", event_id: draft.eventId } : null;
  }
  if (draft.type === "bought_ticket_type") {
    return draft.eventId && draft.ticketTypeIds.length > 0
      ? { type: "bought_ticket_type", event_id: draft.eventId, ticket_type_ids: draft.ticketTypeIds }
      : null;
  }
  const kes = Number(draft.spendKes);
  return kes > 0 ? { type: "min_spent", cents: Math.round(kes * 100) } : null;
}

export default function NewSegmentForm({
  events,
  audienceEvents,
}: {
  events: { id: string; title: string }[];
  audienceEvents: AudienceEvent[];
}) {
  const router = useRouter();
  const [name, setName] = useState("");
  const [match, setMatch] = useState<"all" | "any">("all");
  const [conditions, setConditions] = useState<ConditionDraft[]>([emptyCondition()]);
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);
  const [preview, setPreview] = useState<{ count: number; sample: string[] } | null>(null);
  const [previewing, setPreviewing] = useState(false);

  function updateCondition(index: number, patch: Partial<ConditionDraft>) {
    setConditions((prev) => prev.map((c, i) => (i === index ? { ...c, ...patch } : c)));
    setPreview(null);
  }

  function addCondition() {
    setConditions((prev) => [...prev, emptyCondition()]);
    setPreview(null);
  }

  function removeCondition(index: number) {
    setConditions((prev) => prev.filter((_, i) => i !== index));
    setPreview(null);
  }

  async function handlePreview() {
    setError(null);
    setPreviewing(true);
    const parsed = conditions.map(toCondition).filter((c): c is SegmentCondition => c !== null);
    if (parsed.length === 0) {
      setError("Add at least one complete rule first");
      setPreviewing(false);
      return;
    }
    const res = await fetch("/api/dashboard/segments/preview", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ match, conditions: parsed }),
    });
    const data = await res.json();
    setPreview(data);
    setPreviewing(false);
  }

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

    const parsed = conditions.map(toCondition).filter((c): c is SegmentCondition => c !== null);
    if (parsed.length === 0) {
      setError("Add at least one complete rule");
      setLoading(false);
      return;
    }

    const res = await fetch("/api/dashboard/segments", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ name: name.trim(), match, conditions: parsed }),
    });

    if (!res.ok) {
      const data = await res.json();
      setError(data.error ?? "Could not create segment");
      setLoading(false);
      return;
    }

    router.push("/dashboard/segments");
    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. Big spenders"
          className="input"
        />
      </Field>

      {conditions.length > 1 && (
        <Field label="Match">
          <select
            value={match}
            onChange={(e) => {
              setMatch(e.target.value as "all" | "any");
              setPreview(null);
            }}
            className="input"
          >
            <option value="all">All of these rules</option>
            <option value="any">Any of these rules</option>
          </select>
        </Field>
      )}

      <div className="space-y-3">
        {conditions.map((c, i) => (
          <div key={i} className="flex items-start gap-2 rounded-lg border border-be-border p-3">
            <div className="grid min-w-0 flex-1 gap-2 sm:grid-cols-2">
              <select
                value={c.type}
                onChange={(e) => updateCondition(i, { type: e.target.value as ConditionType, eventId: "", ticketTypeIds: [] })}
                className={`input ${c.type === "bought_ticket_type" ? "sm:col-span-2" : ""}`}
              >
                <option value="bought_event">Bought a ticket to</option>
                <option value="bought_ticket_type">Bought these ticket types</option>
                <option value="min_spent">Spent at least</option>
              </select>

              {c.type === "bought_ticket_type" ? (
                <div className="sm:col-span-2">
                  <TicketAudiencePicker
                    events={audienceEvents}
                    value={{ eventId: c.eventId, ticketTypeIds: c.ticketTypeIds }}
                    onChange={(v) => updateCondition(i, { eventId: v.eventId, ticketTypeIds: v.ticketTypeIds })}
                  />
                </div>
              ) : c.type === "bought_event" ? (
                <select
                  value={c.eventId}
                  onChange={(e) => updateCondition(i, { eventId: e.target.value })}
                  className="input"
                >
                  <option value="">Choose an event…</option>
                  {events.map((ev) => (
                    <option key={ev.id} value={ev.id}>
                      {ev.title}
                    </option>
                  ))}
                </select>
              ) : (
                <input
                  type="number"
                  min="0"
                  step="0.01"
                  value={c.spendKes}
                  onChange={(e) => updateCondition(i, { spendKes: e.target.value })}
                  placeholder="Amount in KES"
                  className="input"
                />
              )}
            </div>
            {conditions.length > 1 && (
              <button
                type="button"
                onClick={() => removeCondition(i)}
                className="mt-2 text-sm text-be-muted hover:text-be-text"
                aria-label="Remove rule"
              >
                ✕
              </button>
            )}
          </div>
        ))}
      </div>

      <button type="button" onClick={addCondition} className={buttonClass("secondary")}>
        Add rule
      </button>

      <div className="flex items-center gap-3">
        <button
          type="button"
          onClick={handlePreview}
          disabled={previewing}
          className={buttonClass("secondary")}
        >
          {previewing ? "Checking…" : "Preview matches"}
        </button>
        {preview && (
          <p className="text-sm text-be-muted">
            {preview.count} customer{preview.count === 1 ? "" : "s"} match
            {preview.sample.length > 0 ? ` — e.g. ${preview.sample.join(", ")}` : ""}
          </p>
        )}
      </div>

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

      <button type="submit" disabled={loading} className={buttonClass("primary")}>
        {loading ? "Creating…" : "Create segment"}
      </button>
    </form>
  );
}

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