// @File: src/pages/ClientWhatsappCampaigns.tsx
// @Desc: Client-area Campaigns dashboard for the WhatsApp reseller
//        module. Lets the customer assemble a bulk-message campaign —
//        pick a message body, paste a recipient list, set throttle and
//        schedule, then start / pause / resume / cancel it. The heavy
//        sending work lives in the backend dispatcher; this page only
//        drives the service-layer state machine.
import { useCallback, useEffect, useMemo, useState } from "react";
import { Link } from "react-router-dom";
import {
  ArrowLeft,
  Loader2,
  BarChart3,
  Megaphone,
  Pause,
  Play,
  Plus,
  RefreshCw,
  Trash2,
  XCircle,
} from "lucide-react";

import {
  WhatsappCampaign,
  WhatsappCampaignStats,
  waCampaignStats,
  waCreateCampaign,
  waDeleteCampaign,
  waListCampaigns,
  waTransitionCampaign,
} from "@/lib/whatsappApi";

// Parse a free-form recipient textarea: one phone number per line or
// comma-separated. Empty lines are ignored so a pasted CSV behaves sanely.
function parseRecipients(raw: string): { phone_number: string }[] {
  return raw
    .split(/[\n,;]+/)
    .map((s) => s.trim())
    .filter((s) => s.length > 0)
    .map((phone_number) => ({ phone_number }));
}

function formatDate(iso: string | null): string {
  if (!iso) return "—";
  try {
    return new Date(iso).toLocaleString();
  } catch {
    return iso;
  }
}

const STATUS_STYLES: Record<string, string> = {
  draft: "bg-slate-200 text-slate-700",
  scheduled: "bg-sky-100 text-sky-700",
  running: "bg-emerald-100 text-emerald-700",
  paused: "bg-amber-100 text-amber-700",
  completed: "bg-indigo-100 text-indigo-700",
  failed: "bg-rose-100 text-rose-700",
};

export default function ClientWhatsappCampaigns() {
  const [campaigns, setCampaigns] = useState<WhatsappCampaign[]>([]);
  const [stats, setStats] = useState<WhatsappCampaignStats | null>(null);
  const [loading, setLoading] = useState(true);
  const [busyId, setBusyId] = useState<number | null>(null);
  const [showCreate, setShowCreate] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // Create form state
  const [name, setName] = useState("");
  const [body, setBody] = useState("");
  const [recipientsRaw, setRecipientsRaw] = useState("");
  const [scheduledAt, setScheduledAt] = useState("");
  const [throttle, setThrottle] = useState(30);
  const [submitting, setSubmitting] = useState(false);

  const reload = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const [list, s] = await Promise.all([waListCampaigns(), waCampaignStats()]);
      setCampaigns(list);
      setStats(s);
    } catch (err) {
      setError(err instanceof Error ? err.message : String(err));
    } finally {
      setLoading(false);
    }
  }, []);

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

  const parsedCount = useMemo(() => parseRecipients(recipientsRaw).length, [recipientsRaw]);

  const onCreate = useCallback(async () => {
    setSubmitting(true);
    setError(null);
    try {
      const recipients = parseRecipients(recipientsRaw);
      if (!name.trim()) throw new Error("Campaign name is required.");
      if (!body.trim()) throw new Error("Message body is required.");
      if (recipients.length === 0) throw new Error("Add at least one recipient.");
      await waCreateCampaign({
        name: name.trim(),
        message_body: body.trim(),
        throttle_per_minute: throttle,
        scheduled_at: scheduledAt ? new Date(scheduledAt).toISOString() : null,
        recipients,
      });
      setShowCreate(false);
      setName("");
      setBody("");
      setRecipientsRaw("");
      setScheduledAt("");
      setThrottle(30);
      await reload();
    } catch (err) {
      setError(err instanceof Error ? err.message : String(err));
    } finally {
      setSubmitting(false);
    }
  }, [name, body, recipientsRaw, scheduledAt, throttle, reload]);

  const onAction = useCallback(
    async (id: number, action: "start" | "pause" | "resume" | "cancel") => {
      setBusyId(id);
      setError(null);
      try {
        await waTransitionCampaign(id, action);
        await reload();
      } catch (err) {
        setError(err instanceof Error ? err.message : String(err));
      } finally {
        setBusyId(null);
      }
    },
    [reload],
  );

  const onDelete = useCallback(
    async (id: number) => {
      if (!window.confirm("Delete this campaign? This cannot be undone.")) return;
      setBusyId(id);
      setError(null);
      try {
        await waDeleteCampaign(id);
        await reload();
      } catch (err) {
        setError(err instanceof Error ? err.message : String(err));
      } finally {
        setBusyId(null);
      }
    },
    [reload],
  );

  return (
    <div className="min-h-screen bg-slate-50">
      <header className="sticky top-0 z-10 flex items-center gap-3 border-b border-slate-200 bg-[#128C7E] px-4 py-3 text-white shadow-sm">
        <Link
          to="/client/whatsapp/chat"
          className="inline-flex h-8 w-8 items-center justify-center rounded-full hover:bg-white/10"
          aria-label="Back to chat"
        >
          <ArrowLeft className="h-4 w-4" />
        </Link>
        <div className="min-w-0 flex-1">
          <h1 className="truncate text-sm font-semibold uppercase tracking-wide">
            WhatsApp Campaigns
          </h1>
          <p className="truncate text-xs text-white/80">
            Send broadcasts to your contacts with throttling and scheduling.
          </p>
        </div>
        <button
          type="button"
          onClick={() => void reload()}
          className="inline-flex h-8 w-8 items-center justify-center rounded-full hover:bg-white/10"
          aria-label="Refresh"
        >
          <RefreshCw className="h-4 w-4" />
        </button>
        <Link
          to="/client/whatsapp/campaigns/analytics"
          className="inline-flex items-center gap-1 rounded-full bg-white/15 px-3 py-1 text-xs font-medium hover:bg-white/25"
        >
          <BarChart3 className="h-3.5 w-3.5" />
          Analytics
        </Link>
        <button
          type="button"
          onClick={() => setShowCreate((v) => !v)}
          className="inline-flex items-center gap-1 rounded-full bg-white/15 px-3 py-1 text-xs font-medium hover:bg-white/25"
        >
          <Plus className="h-3.5 w-3.5" />
          New campaign
        </button>
      </header>

      <main className="mx-auto max-w-5xl space-y-6 px-4 py-6">
        {error ? (
          <div className="rounded-lg border border-rose-200 bg-rose-50 px-4 py-3 text-sm text-rose-700">
            {error}
          </div>
        ) : null}

        {/* Stats tiles */}
        <section className="grid grid-cols-2 gap-3 sm:grid-cols-4">
          {[
            { label: "Campaigns", value: stats?.campaigns ?? 0 },
            { label: "Recipients", value: stats?.recipients ?? 0 },
            { label: "Sent", value: stats?.sent ?? 0 },
            { label: "Failed", value: stats?.failed ?? 0 },
          ].map((t) => (
            <div
              key={t.label}
              className="rounded-lg border border-slate-200 bg-white p-4 shadow-sm"
            >
              <div className="text-xs uppercase tracking-wide text-slate-500">
                {t.label}
              </div>
              <div className="mt-1 text-2xl font-semibold text-slate-800">
                {t.value.toLocaleString()}
              </div>
            </div>
          ))}
        </section>

        {/* Create form */}
        {showCreate ? (
          <section className="rounded-lg border border-slate-200 bg-white p-4 shadow-sm">
            <h2 className="mb-3 text-sm font-semibold text-slate-700">
              Create a campaign
            </h2>
            <div className="space-y-3">
              <label className="block text-xs font-medium text-slate-600">
                Name
                <input
                  value={name}
                  onChange={(e) => setName(e.target.value)}
                  className="mt-1 w-full rounded border border-slate-300 px-3 py-2 text-sm text-slate-800 focus:border-[#128C7E] focus:outline-none"
                  placeholder="E.g. May promo"
                  maxLength={128}
                />
              </label>
              <label className="block text-xs font-medium text-slate-600">
                Message body
                <textarea
                  value={body}
                  onChange={(e) => setBody(e.target.value)}
                  className="mt-1 h-24 w-full resize-y rounded border border-slate-300 px-3 py-2 text-sm text-slate-800 focus:border-[#128C7E] focus:outline-none"
                  placeholder="Hi {name}, here's our latest offer…"
                  maxLength={4096}
                />
              </label>
              <label className="block text-xs font-medium text-slate-600">
                Recipients ({parsedCount} parsed)
                <textarea
                  value={recipientsRaw}
                  onChange={(e) => setRecipientsRaw(e.target.value)}
                  className="mt-1 h-28 w-full resize-y rounded border border-slate-300 px-3 py-2 text-sm text-slate-800 focus:border-[#128C7E] focus:outline-none"
                  placeholder="One phone per line, or comma-separated. Country code recommended."
                />
              </label>
              <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
                <label className="block text-xs font-medium text-slate-600">
                  Schedule (optional)
                  <input
                    type="datetime-local"
                    value={scheduledAt}
                    onChange={(e) => setScheduledAt(e.target.value)}
                    className="mt-1 w-full rounded border border-slate-300 px-3 py-2 text-sm text-slate-800 focus:border-[#128C7E] focus:outline-none"
                  />
                </label>
                <label className="block text-xs font-medium text-slate-600">
                  Throttle (messages / minute)
                  <input
                    type="number"
                    min={1}
                    max={240}
                    value={throttle}
                    onChange={(e) => setThrottle(Number(e.target.value) || 30)}
                    className="mt-1 w-full rounded border border-slate-300 px-3 py-2 text-sm text-slate-800 focus:border-[#128C7E] focus:outline-none"
                  />
                </label>
              </div>
              <div className="flex items-center justify-end gap-2 pt-1">
                <button
                  type="button"
                  onClick={() => setShowCreate(false)}
                  className="rounded px-3 py-1.5 text-sm text-slate-600 hover:bg-slate-100"
                >
                  Cancel
                </button>
                <button
                  type="button"
                  disabled={submitting}
                  onClick={onCreate}
                  className="inline-flex items-center gap-2 rounded bg-[#128C7E] px-3 py-1.5 text-sm font-medium text-white hover:bg-[#0e7265] disabled:cursor-not-allowed disabled:opacity-70"
                >
                  {submitting ? <Loader2 className="h-4 w-4 animate-spin" /> : null}
                  Save campaign
                </button>
              </div>
            </div>
          </section>
        ) : null}

        {/* Campaign list */}
        <section className="rounded-lg border border-slate-200 bg-white shadow-sm">
          <div className="flex items-center justify-between border-b border-slate-100 px-4 py-3">
            <h2 className="flex items-center gap-2 text-sm font-semibold text-slate-700">
              <Megaphone className="h-4 w-4 text-[#128C7E]" />
              Your campaigns
            </h2>
          </div>
          {loading ? (
            <div className="flex items-center justify-center py-12">
              <Loader2 className="h-5 w-5 animate-spin text-slate-400" />
            </div>
          ) : campaigns.length === 0 ? (
            <div className="py-12 text-center text-sm text-slate-500">
              No campaigns yet. Click <span className="font-medium">New campaign</span>{" "}
              to create one.
            </div>
          ) : (
            <ul className="divide-y divide-slate-100">
              {campaigns.map((c) => (
                <li key={c.id} className="px-4 py-3">
                  <div className="flex flex-wrap items-start justify-between gap-3">
                    <div className="min-w-0 flex-1">
                      <div className="flex items-center gap-2">
                        <span className="truncate text-sm font-medium text-slate-800">
                          {c.name}
                        </span>
                        <span
                          className={`rounded-full px-2 py-0.5 text-[10px] font-medium uppercase ${
                            STATUS_STYLES[c.status] ?? "bg-slate-200 text-slate-700"
                          }`}
                        >
                          {c.status}
                        </span>
                      </div>
                      <p className="mt-1 line-clamp-2 text-xs text-slate-500">
                        {c.message_body}
                      </p>
                      <div className="mt-2 grid grid-cols-2 gap-1 text-[11px] text-slate-500 sm:grid-cols-4">
                        <span>Recipients: {c.total_recipients}</span>
                        <span>Sent: {c.sent_count}</span>
                        <span>Replied: {c.replied_count}</span>
                        <span>Failed: {c.failed_count}</span>
                        <span>Scheduled: {formatDate(c.scheduled_at)}</span>
                        <span>Started: {formatDate(c.started_at)}</span>
                        <span>Completed: {formatDate(c.completed_at)}</span>
                        <span>Throttle: {c.throttle_per_minute}/min</span>
                      </div>
                      {c.last_error ? (
                        <p className="mt-1 text-xs text-rose-600">{c.last_error}</p>
                      ) : null}
                    </div>
                    <div className="flex flex-shrink-0 flex-wrap items-center gap-1">
                      {(c.status === "draft" ||
                        c.status === "scheduled" ||
                        c.status === "paused") && (
                        <button
                          type="button"
                          disabled={busyId === c.id}
                          onClick={() =>
                            void onAction(
                              c.id,
                              c.status === "paused" ? "resume" : "start",
                            )
                          }
                          className="inline-flex items-center gap-1 rounded bg-emerald-50 px-2 py-1 text-xs font-medium text-emerald-700 hover:bg-emerald-100 disabled:opacity-50"
                        >
                          <Play className="h-3 w-3" />
                          {c.status === "paused" ? "Resume" : "Start"}
                        </button>
                      )}
                      {c.status === "running" && (
                        <button
                          type="button"
                          disabled={busyId === c.id}
                          onClick={() => void onAction(c.id, "pause")}
                          className="inline-flex items-center gap-1 rounded bg-amber-50 px-2 py-1 text-xs font-medium text-amber-700 hover:bg-amber-100 disabled:opacity-50"
                        >
                          <Pause className="h-3 w-3" />
                          Pause
                        </button>
                      )}
                      {!["completed", "failed"].includes(c.status) && (
                        <button
                          type="button"
                          disabled={busyId === c.id}
                          onClick={() => void onAction(c.id, "cancel")}
                          className="inline-flex items-center gap-1 rounded bg-rose-50 px-2 py-1 text-xs font-medium text-rose-700 hover:bg-rose-100 disabled:opacity-50"
                        >
                          <XCircle className="h-3 w-3" />
                          Cancel
                        </button>
                      )}
                      <button
                        type="button"
                        disabled={busyId === c.id}
                        onClick={() => void onDelete(c.id)}
                        className="inline-flex items-center gap-1 rounded px-2 py-1 text-xs font-medium text-slate-500 hover:bg-slate-100 disabled:opacity-50"
                      >
                        <Trash2 className="h-3 w-3" />
                        Delete
                      </button>
                    </div>
                  </div>
                </li>
              ))}
            </ul>
          )}
        </section>
      </main>
    </div>
  );
}