"use client";

import { useMemo, useState } from "react";
import { useRouter } from "next/navigation";
import { RichTextEditor } from "@/components/admin/common/RichTextEditor";
import { UnsavedChangesWatcher } from "@/components/admin/common/UnsavedChangesWatcher";
import type { BulletinAudience, BulletinCampaignStatus, Tier, PublishStatus } from "@prisma/client";
import { ModalPortal } from "@/components/admin/common/ModalPortal";

type AudienceFilter = {
  tiers?: Tier[];
  statuses?: PublishStatus[];
  categoryIds?: string[];
};

export type BulletinFormInitial = {
  id?: string;
  name?: string;
  subject?: string;
  subjectVariantB?: string | null;
  bodyHtml?: string;
  audience?: BulletinAudience;
  audienceFilter?: AudienceFilter | null;
  customEmails?: string[];
  abEnabled?: boolean;
  abSplitPercent?: number;
  scheduledAt?: string | null;
  recurrenceCron?: string | null;
  utmCampaign?: string | null;
  status?: BulletinCampaignStatus;
};

type Props = {
  initial?: BulletinFormInitial;
  categories?: Array<{ id: string; name: string }>;
};

const TIERS: Tier[] = ["STANDARD", "BRONZE", "SILVER", "GOLD", "PLATINUM"] as Tier[];
const STATUSES: PublishStatus[] = ["DRAFT", "PUBLISHED", "ARCHIVED"] as PublishStatus[];

const CRON_PRESETS = [
  { label: "Svakog 1. u mesecu (09:00)", value: "0 9 1 * *" },
  { label: "Svakog ponedeljka (09:00)", value: "0 9 * * 1" },
  { label: "Svakog dana (08:00)", value: "0 8 * * *" },
];

function slugifyForUtm(s: string): string {
  return s
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-+|-+$/g, "")
    .slice(0, 60);
}

export function BulletinCampaignForm({ initial, categories }: Props) {
  const router = useRouter();
  const [name, setName] = useState(initial?.name ?? "");
  const [subject, setSubject] = useState(initial?.subject ?? "");
  const [subjectVariantB, setSubjectVariantB] = useState(initial?.subjectVariantB ?? "");
  const [abEnabled, setAbEnabled] = useState(initial?.abEnabled ?? false);
  const [abSplitPercent, setAbSplitPercent] = useState(initial?.abSplitPercent ?? 50);
  const [bodyHtml, setBodyHtml] = useState(initial?.bodyHtml ?? "");
  const [audience, setAudience] = useState<BulletinAudience>(
    (initial?.audience ?? "COMPANIES_ALL") as BulletinAudience,
  );
  const [filter, setFilter] = useState<AudienceFilter>(initial?.audienceFilter ?? {});
  const [customEmails, setCustomEmails] = useState((initial?.customEmails ?? []).join("\n"));
  const [scheduleMode, setScheduleMode] = useState<"now" | "later" | "recurring">(
    initial?.recurrenceCron ? "recurring" : initial?.scheduledAt ? "later" : "now",
  );
  const [scheduledAt, setScheduledAt] = useState(initial?.scheduledAt ?? "");
  const [recurrenceCron, setRecurrenceCron] = useState(initial?.recurrenceCron ?? "");
  const [utmCampaign, setUtmCampaign] = useState(initial?.utmCampaign ?? "");
  const [previewOpen, setPreviewOpen] = useState(false);
  const [busy, setBusy] = useState(false);
  const [message, setMessage] = useState<string | null>(null);

  const utmAuto = useMemo(() => utmCampaign || slugifyForUtm(name), [utmCampaign, name]);

  function markDirty() {
    // form-level UnsavedChangesWatcher detects input/change events on the form
  }

  function buildPayload() {
    return {
      name,
      subject,
      subjectVariantB: subjectVariantB || null,
      bodyHtml,
      audience,
      audienceFilter: filter,
      customEmails: customEmails
        .split(/[\n,;]+/)
        .map((s) => s.trim())
        .filter((s) => s.includes("@")),
      abEnabled,
      abSplitPercent,
      utmCampaign: utmAuto || null,
    };
  }

  async function persist(): Promise<string | null> {
    const payload = buildPayload();
    if (initial?.id) {
      const res = await fetch(`/api/admin/bulletin/${initial.id}`, {
        method: "PATCH",
        headers: { "content-type": "application/json" },
        body: JSON.stringify(payload),
      });
      if (!res.ok) {
        const data = await res.json().catch(() => ({}));
        throw new Error(data.error || "Greška pri čuvanju");
      }
      return initial.id;
    }
    const res = await fetch(`/api/admin/bulletin`, {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify(payload),
    });
    if (!res.ok) {
      const data = await res.json().catch(() => ({}));
      throw new Error(data.error || "Greška pri čuvanju");
    }
    const data = (await res.json()) as { item: { id: string } };
    return data.item.id;
  }

  async function handleSaveDraft() {
    setBusy(true);
    setMessage(null);
    try {
      const id = await persist();

      setMessage("Sačuvano kao draft.");
      if (id && !initial?.id) router.push(`/admin/bilten/${id}`);
      else router.refresh();
    } catch (error) {
      setMessage(error instanceof Error ? error.message : "Greška");
    } finally {
      setBusy(false);
    }
  }

  async function handleSchedule() {
    setBusy(true);
    setMessage(null);
    try {
      const id = await persist();
      if (!id) throw new Error("ID nije pronađen");
      const when =
        scheduleMode === "recurring" || scheduleMode === "later"
          ? scheduledAt
            ? new Date(scheduledAt).toISOString()
            : new Date().toISOString()
          : new Date().toISOString();
      const res = await fetch(`/api/admin/bulletin/${id}`, {
        method: "PATCH",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({
          action: "schedule",
          scheduledAt: when,
          recurrenceCron: scheduleMode === "recurring" ? recurrenceCron : null,
        }),
      });
      if (!res.ok) throw new Error("Zakazivanje neuspešno");

      setMessage("Kampanja zakazana.");
      router.refresh();
    } catch (error) {
      setMessage(error instanceof Error ? error.message : "Greška");
    } finally {
      setBusy(false);
    }
  }

  async function handleSendNow() {
    if (!confirm("Pošaljite kampanju odmah?")) return;
    setBusy(true);
    setMessage(null);
    try {
      const id = await persist();
      if (!id) throw new Error("ID nije pronađen");
      const res = await fetch(`/api/admin/bulletin/${id}`, {
        method: "PATCH",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ action: "send" }),
      });
      if (!res.ok) throw new Error("Slanje neuspešno");
      const data = (await res.json()) as { sent?: number };

      setMessage(`Poslato ${data.sent ?? 0} primalaca.`);
      router.refresh();
    } catch (error) {
      setMessage(error instanceof Error ? error.message : "Greška");
    } finally {
      setBusy(false);
    }
  }

  return (
    <form
      className="space-y-6"
      onSubmit={(e) => {
        e.preventDefault();
        handleSaveDraft();
      }}
    >
      <UnsavedChangesWatcher />

      {message ? (
        <div className="rounded-lg border border-neutral-200 bg-neutral-50 px-4 py-2 text-sm text-neutral-700">
          {message}
        </div>
      ) : null}

      <section className="space-y-4 rounded-2xl border border-neutral-200 bg-white p-6">
        <h2 className="text-lg font-semibold">Osnovno</h2>
        <label className="block">
          <span className="text-sm font-medium text-neutral-700">Naziv (interni)</span>
          <input
            className="mt-1 w-full rounded-lg border border-neutral-300 px-3 py-2 text-sm"
            value={name}
            onChange={(e) => {
              setName(e.target.value);
              markDirty();
            }}
            placeholder="npr. Mesečni bilten — april"
          />
        </label>
        <label className="block">
          <span className="text-sm font-medium text-neutral-700">Subject A</span>
          <input
            className="mt-1 w-full rounded-lg border border-neutral-300 px-3 py-2 text-sm"
            value={subject}
            onChange={(e) => {
              setSubject(e.target.value);
              markDirty();
            }}
            required
          />
        </label>
        <label className="block">
          <span className="text-sm font-medium text-neutral-700">Subject B (opciono, A/B test)</span>
          <input
            className="mt-1 w-full rounded-lg border border-neutral-300 px-3 py-2 text-sm"
            value={subjectVariantB}
            onChange={(e) => {
              setSubjectVariantB(e.target.value);
              markDirty();
            }}
          />
        </label>
        {subjectVariantB ? (
          <div className="flex items-center gap-3">
            <label className="flex items-center gap-2 text-sm">
              <input
                type="checkbox"
                checked={abEnabled}
                onChange={(e) => {
                  setAbEnabled(e.target.checked);
                  markDirty();
                }}
              />
              Uključi A/B test
            </label>
            {abEnabled ? (
              <label className="flex items-center gap-2 text-sm">
                Split A %:
                <input
                  type="number"
                  min={10}
                  max={90}
                  value={abSplitPercent}
                  onChange={(e) => {
                    setAbSplitPercent(Number(e.target.value));
                    markDirty();
                  }}
                  className="w-20 rounded-md border border-neutral-300 px-2 py-1 text-sm"
                />
              </label>
            ) : null}
          </div>
        ) : null}
      </section>

      <section className="space-y-4 rounded-2xl border border-neutral-200 bg-white p-6">
        <h2 className="text-lg font-semibold">Sadržaj</h2>
        <RichTextEditor
          value={bodyHtml}
          onChange={(html) => {
            setBodyHtml(html);
            markDirty();
          }}
          placeholder="Napišite sadržaj biltena..."
        />
        <button
          type="button"
          className="rounded-lg border border-neutral-300 bg-white px-3 py-1.5 text-sm font-medium hover:bg-neutral-50"
          onClick={() => setPreviewOpen(true)}
        >
          Pregled
        </button>
      </section>

      <section className="space-y-4 rounded-2xl border border-neutral-200 bg-white p-6">
        <h2 className="text-lg font-semibold">Publika</h2>
        <select
          className="w-full rounded-lg border border-neutral-300 px-3 py-2 text-sm"
          value={audience}
          onChange={(e) => {
            setAudience(e.target.value as BulletinAudience);
            setFilter({});
            markDirty();
          }}
        >
          <option value="COMPANIES_ALL">Sve kompanije</option>
          <option value="COMPANIES_BY_TIER">Kompanije po tier-u</option>
          <option value="COMPANIES_BY_STATUS">Kompanije po statusu</option>
          <option value="COMPANIES_BY_CATEGORY">Kompanije po kategoriji</option>
          <option value="CLIENT_ACCOUNTS">Klijent nalozi</option>
          <option value="CUSTOM_EMAILS">Custom email lista</option>
        </select>

        {audience === "COMPANIES_BY_TIER" ? (
          <div className="flex flex-wrap gap-2">
            {TIERS.map((tier) => {
              const active = filter.tiers?.includes(tier) ?? false;
              return (
                <button
                  type="button"
                  key={tier}
                  className={`rounded-full border px-3 py-1 text-sm ${
                    active ? "bg-neutral-900 text-white" : "border-neutral-300 bg-white"
                  }`}
                  onClick={() => {
                    const set = new Set(filter.tiers ?? []);
                    if (set.has(tier)) set.delete(tier);
                    else set.add(tier);
                    setFilter({ ...filter, tiers: Array.from(set) });
                    markDirty();
                  }}
                >
                  {tier}
                </button>
              );
            })}
          </div>
        ) : null}

        {audience === "COMPANIES_BY_STATUS" ? (
          <div className="flex flex-wrap gap-2">
            {STATUSES.map((status) => {
              const active = filter.statuses?.includes(status) ?? false;
              return (
                <button
                  type="button"
                  key={status}
                  className={`rounded-full border px-3 py-1 text-sm ${
                    active ? "bg-neutral-900 text-white" : "border-neutral-300 bg-white"
                  }`}
                  onClick={() => {
                    const set = new Set(filter.statuses ?? []);
                    if (set.has(status)) set.delete(status);
                    else set.add(status);
                    setFilter({ ...filter, statuses: Array.from(set) });
                    markDirty();
                  }}
                >
                  {status}
                </button>
              );
            })}
          </div>
        ) : null}

        {audience === "COMPANIES_BY_CATEGORY" ? (
          <div className="max-h-56 overflow-auto rounded-lg border border-neutral-200 p-3">
            {(categories ?? []).map((cat) => {
              const active = filter.categoryIds?.includes(cat.id) ?? false;
              return (
                <label key={cat.id} className="flex items-center gap-2 py-1 text-sm">
                  <input
                    type="checkbox"
                    checked={active}
                    onChange={() => {
                      const set = new Set(filter.categoryIds ?? []);
                      if (set.has(cat.id)) set.delete(cat.id);
                      else set.add(cat.id);
                      setFilter({ ...filter, categoryIds: Array.from(set) });
                      markDirty();
                    }}
                  />
                  {cat.name}
                </label>
              );
            })}
            {(categories ?? []).length === 0 ? (
              <p className="text-sm text-neutral-500">Nema dostupnih kategorija.</p>
            ) : null}
          </div>
        ) : null}

        {audience === "CUSTOM_EMAILS" ? (
          <textarea
            className="h-32 w-full rounded-lg border border-neutral-300 p-2 text-sm font-mono"
            placeholder="jedan email po liniji"
            value={customEmails}
            onChange={(e) => {
              setCustomEmails(e.target.value);
              markDirty();
            }}
          />
        ) : null}
      </section>

      <section className="space-y-4 rounded-2xl border border-neutral-200 bg-white p-6">
        <h2 className="text-lg font-semibold">Slanje</h2>
        <div className="flex flex-wrap gap-4">
          <label className="flex items-center gap-2 text-sm">
            <input
              type="radio"
              checked={scheduleMode === "now"}
              onChange={() => {
                setScheduleMode("now");
                markDirty();
              }}
            />
            Pošalji sada
          </label>
          <label className="flex items-center gap-2 text-sm">
            <input
              type="radio"
              checked={scheduleMode === "later"}
              onChange={() => {
                setScheduleMode("later");
                markDirty();
              }}
            />
            Zakaži za...
          </label>
          <label className="flex items-center gap-2 text-sm">
            <input
              type="radio"
              checked={scheduleMode === "recurring"}
              onChange={() => {
                setScheduleMode("recurring");
                markDirty();
              }}
            />
            Ponavljajuće
          </label>
        </div>

        {scheduleMode !== "now" ? (
          <label className="block">
            <span className="text-sm font-medium text-neutral-700">Datum/vreme</span>
            <input
              type="datetime-local"
              className="mt-1 w-full rounded-lg border border-neutral-300 px-3 py-2 text-sm"
              value={scheduledAt ?? ""}
              onChange={(e) => {
                setScheduledAt(e.target.value);
                markDirty();
              }}
            />
          </label>
        ) : null}

        {scheduleMode === "recurring" ? (
          <div className="space-y-2">
            <label className="block">
              <span className="text-sm font-medium text-neutral-700">Cron izraz</span>
              <input
                className="mt-1 w-full rounded-lg border border-neutral-300 px-3 py-2 font-mono text-sm"
                placeholder="0 9 1 * *"
                value={recurrenceCron ?? ""}
                onChange={(e) => {
                  setRecurrenceCron(e.target.value);
                  markDirty();
                }}
              />
            </label>
            <div className="flex flex-wrap gap-2">
              {CRON_PRESETS.map((p) => (
                <button
                  type="button"
                  key={p.value}
                  className="rounded-full border border-neutral-300 bg-white px-3 py-1 text-xs hover:bg-neutral-50"
                  onClick={() => {
                    setRecurrenceCron(p.value);
                    markDirty();
                  }}
                >
                  {p.label}
                </button>
              ))}
            </div>
            <p className="text-xs text-neutral-500">
              Format: minuta sat dan mesec dan_u_nedelji. Primer: &quot;0 9 1 * *&quot; =
              svakog 1. u mesecu u 09:00.
            </p>
          </div>
        ) : null}

        <label className="block">
          <span className="text-sm font-medium text-neutral-700">UTM campaign</span>
          <input
            className="mt-1 w-full rounded-lg border border-neutral-300 px-3 py-2 text-sm"
            value={utmCampaign}
            placeholder={slugifyForUtm(name)}
            onChange={(e) => {
              setUtmCampaign(e.target.value);
              markDirty();
            }}
          />
        </label>
      </section>

      <div className="flex flex-wrap gap-2">
        <button
          type="button"
          disabled={busy}
          onClick={handleSaveDraft}
          className="rounded-lg border border-neutral-300 bg-white px-4 py-2 text-sm font-medium hover:bg-neutral-50 disabled:opacity-50"
        >
          Sačuvaj kao draft
        </button>
        <button
          type="button"
          disabled={busy}
          onClick={handleSchedule}
          className="rounded-lg bg-neutral-900 px-4 py-2 text-sm font-medium text-white hover:bg-neutral-800 disabled:opacity-50"
        >
          Sačuvaj i zakaži
        </button>
        <button
          type="button"
          disabled={busy}
          onClick={handleSendNow}
          className="rounded-lg bg-emerald-600 px-4 py-2 text-sm font-medium text-white hover:bg-emerald-500 disabled:opacity-50"
        >
          Pošalji
        </button>
      </div>

      {previewOpen ? (
        <ModalPortal>
        <div
          className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4"
          onClick={() => setPreviewOpen(false)}
        >
          <div
            className="max-h-[90vh] w-full max-w-2xl overflow-auto rounded-xl bg-white p-6 shadow-xl"
            onClick={(e) => e.stopPropagation()}
          >
            <div className="mb-4 flex items-center justify-between">
              <h3 className="text-base font-semibold">Pregled emaila</h3>
              <button
                type="button"
                onClick={() => setPreviewOpen(false)}
                className="rounded-md px-2 py-1 text-sm hover:bg-neutral-100"
              >
                ✕
              </button>
            </div>
            <p className="mb-2 text-xs uppercase text-neutral-500">Subject:</p>
            <p className="mb-4 font-medium">{subject}</p>
            <div
              className="prose prose-sm max-w-none rounded-lg border border-neutral-200 p-4"
              dangerouslySetInnerHTML={{ __html: bodyHtml }}
            />
          </div>
        </div>
        </ModalPortal>
      ) : null}
    </form>
  );
}
