"use client";

import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useAuth } from "@/hooks/useAuth";
import { useRouter } from "next/navigation";
import { apiFetch } from "@/lib/api";

// ─── Types ────────────────────────────────────────────────────────────────────

type WAStatus =
  | "WORKING"
  | "CONNECTED"
  | "SCAN_QR_CODE"
  | "STARTING"
  | "FAILED"
  | "STOPPED"
  | string;

interface ConfigResponse {
  tokenMasked: string;
  instanceId:  string;
  hasToken:    boolean;
  hasInstance: boolean;
  configured:  boolean;
}

interface StatusResponse {
  status:   WAStatus;
  message?: string;
}

// ─── Helpers ──────────────────────────────────────────────────────────────────

const STATUS_COLORS: Record<string, string> = {
  WORKING:      "bg-green-100 text-green-800 border-green-300",
  CONNECTED:    "bg-green-100 text-green-800 border-green-300",
  SCAN_QR_CODE: "bg-yellow-100 text-yellow-800 border-yellow-300",
  STARTING:     "bg-blue-100 text-blue-800 border-blue-300",
  FAILED:       "bg-red-100 text-red-800 border-red-300",
  STOPPED:      "bg-gray-100 text-gray-700 border-gray-300",
};

const STATUS_ICONS: Record<string, string> = {
  WORKING:      "🟢",
  CONNECTED:    "🟢",
  SCAN_QR_CODE: "📷",
  STARTING:     "🔄",
  FAILED:       "🔴",
  STOPPED:      "⚫",
};

const ACTIVE_STATUSES = new Set(["WORKING", "CONNECTED"]);
const POLLING_STATUSES = new Set(["STARTING", "SCAN_QR_CODE", "FAILED", "STOPPED"]);

function Spinner() {
  return (
    <svg
      className="animate-spin h-4 w-4 text-indigo-600"
      xmlns="http://www.w3.org/2000/svg"
      fill="none"
      viewBox="0 0 24 24"
    >
      <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
      <path
        className="opacity-75"
        fill="currentColor"
        d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
      />
    </svg>
  );
}

function Alert({
  type,
  children,
}: {
  type: "ok" | "err" | "info";
  children: React.ReactNode;
}) {
  const cls =
    type === "ok"
      ? "bg-green-50 text-green-800 border-green-200"
      : type === "err"
      ? "bg-red-50 text-red-800 border-red-200"
      : "bg-blue-50 text-blue-800 border-blue-200";
  return (
    <div className={`p-3 rounded-lg text-sm border ${cls}`}>{children}</div>
  );
}

// ─── Page ─────────────────────────────────────────────────────────────────────

export default function WhatsAppAdminPage() {
  const { user, loading, token } = useAuth();
  const router = useRouter();
  const isAdmin = useMemo(() => user?.role === "admin", [user]);

  useEffect(() => {
    if (loading) return;
    if (!user || !isAdmin) router.replace("/dashboard");
  }, [user, loading, isAdmin, router]);

  // ── Config state (drives wizard steps) ──────────────────────────────────────
  const [cfg, setCfg] = useState<ConfigResponse | null>(null);
  const [cfgLoading, setCfgLoading] = useState(true);

  // Derived wizard step: 1 = no token, 2 = token but no instance, 3 = fully configured
  const step = !cfg ? 0 : !cfg.hasToken ? 1 : !cfg.hasInstance ? 2 : 3;

  // ── Step 1 inputs ────────────────────────────────────────────────────────────
  const [inputToken, setInputToken] = useState("");
  const [savingToken, setSavingToken] = useState(false);

  // ── Step 2 inputs ────────────────────────────────────────────────────────────
  const [instanceMode, setInstanceMode] = useState<"enter" | "create">("create");
  const [inputInstanceId, setInputInstanceId] = useState("");
  const [savingInstance, setSavingInstance] = useState(false);

  // ── Step 3: session state ────────────────────────────────────────────────────
  const [status, setStatus]       = useState<WAStatus | null>(null);
  const [statusMsg, setStatusMsg] = useState<string | null>(null);
  const [qrSrc, setQrSrc]         = useState<string | null>(null);
  const [pairingPhone, setPairingPhone] = useState("");

  // ── Shared action feedback ───────────────────────────────────────────────────
  const [actionMsg, setActionMsg] = useState<{ type: "ok" | "err"; text: string } | null>(null);
  const [busy, setBusy]           = useState<string | null>(null);

  // ── Load config ──────────────────────────────────────────────────────────────
  const fetchConfig = useCallback(async () => {
    if (!token) return;
    try {
      const res = await apiFetch<ConfigResponse>("/api/whatsapp/config", { authToken: token });
      setCfg(res);
    } catch {
      // network error — leave cfg null, user sees loading state
    } finally {
      setCfgLoading(false);
    }
  }, [token]);

  useEffect(() => { fetchConfig(); }, [fetchConfig]);

  // ── Status fetch (step 3 only) ───────────────────────────────────────────────
  const fetchStatus = useCallback(async () => {
    if (!token || step !== 3) return;
    try {
      const res = await apiFetch<StatusResponse>("/api/whatsapp/status", { authToken: token });
      setStatus(res.status ?? null);
      setStatusMsg(res.message ?? null);
    } catch (e: any) {
      // Re-fetch config — if the session was not found, backend clears the
      // instance ID and the step recomputes to 2 (Session Instance setup).
      await fetchConfig();
      setStatus("FAILED");
      setStatusMsg(null);
    }
  }, [token, step, fetchConfig]);

  useEffect(() => { if (step === 3) fetchStatus(); }, [step, fetchStatus]);

  // Auto-poll status when not stable
  useEffect(() => {
    if (step !== 3 || status === null) return;
    if (ACTIVE_STATUSES.has(status)) return;
    const id = setInterval(fetchStatus, 5_000);
    return () => clearInterval(id);
  }, [step, status, fetchStatus]);

  // ── QR fetch ─────────────────────────────────────────────────────────────────
  const fetchQr = useCallback(async () => {
    if (!token) return;
    try {
      const res = await apiFetch<{ qr?: string }>("/api/whatsapp/qr", { authToken: token });
      if (res.qr) setQrSrc(`data:image/png;base64,${res.qr}`);
    } catch {
      setQrSrc(null);
    }
  }, [token]);

  useEffect(() => {
    if (status === "SCAN_QR_CODE") { fetchQr(); }
    else { setQrSrc(null); }
  }, [status, fetchQr]);

  // Auto-refresh QR every 20s while waiting
  useEffect(() => {
    if (status !== "SCAN_QR_CODE") return;
    const id = setInterval(fetchQr, 20_000);
    return () => clearInterval(id);
  }, [status, fetchQr]);

  // ── Generic session action ───────────────────────────────────────────────────
  const doAction = async (action: string, body?: object) => {
    if (!token) return;
    setBusy(action);
    setActionMsg(null);
    try {
      const res = await apiFetch<any>(`/api/whatsapp/${action}`, {
        method: "POST",
        authToken: token,
        body,
      });
      setActionMsg({ type: "ok", text: res?.message || `${action} successful.` });
      await fetchStatus();
      await fetchConfig();
    } catch (e: any) {
      let msg = e?.message || `${action} failed.`;
      try { msg = JSON.parse(msg)?.message || msg; } catch {}
      // SESSION_NOT_FOUND: backend cleared the instance ID — re-fetch config so
      // the wizard steps back to Step 2; no need to show an error message.
      await fetchConfig();
      if (!msg.includes("SESSION_NOT_FOUND")) {
        setActionMsg({ type: "err", text: msg });
      }
      await fetchStatus();
    } finally {
      setBusy(null);
    }
  };

  // ─── Step 1: Save token ──────────────────────────────────────────────────────
  const saveToken = async () => {
    if (!inputToken.trim()) {
      setActionMsg({ type: "err", text: "Please enter your WAWP access token." });
      return;
    }
    setSavingToken(true);
    setActionMsg(null);
    try {
      await apiFetch("/api/whatsapp/config", {
        method: "POST",
        authToken: token!,
        body: { token: inputToken.trim(), instanceId: "" },
      });
      setInputToken("");
      await fetchConfig();
    } catch (e: any) {
      setActionMsg({ type: "err", text: e?.message || "Failed to save token." });
    } finally {
      setSavingToken(false);
    }
  };

  // ─── Step 2: Enter existing instance ID ──────────────────────────────────────
  const saveInstanceId = async () => {
    if (!inputInstanceId.trim()) {
      setActionMsg({ type: "err", text: "Please enter the Instance ID." });
      return;
    }
    setSavingInstance(true);
    setActionMsg(null);
    try {
      await apiFetch("/api/whatsapp/config", {
        method: "POST",
        authToken: token!,
        body: { token: "", instanceId: inputInstanceId.trim() },
        // token left blank → backend keeps existing token
      });
      setInputInstanceId("");
      await fetchConfig();
    } catch (e: any) {
      setActionMsg({ type: "err", text: e?.message || "Failed to save Instance ID." });
    } finally {
      setSavingInstance(false);
    }
  };

  // ─── Step 2: Create new instance ─────────────────────────────────────────────
  const createInstance = async () => {
    setSavingInstance(true);
    setActionMsg(null);
    try {
      const res = await apiFetch<any>("/api/whatsapp/create-instance", {
        method: "POST",
        authToken: token!,
      });
      setActionMsg({ type: "ok", text: res?.message || "Instance created." });
      await fetchConfig();
    } catch (e: any) {
      setActionMsg({ type: "err", text: e?.message || "Failed to create instance." });
    } finally {
      setSavingInstance(false);
    }
  };

  // ─── Pairing code ────────────────────────────────────────────────────────────
  const requestPairingCode = async () => {
    if (!pairingPhone.trim()) {
      setActionMsg({ type: "err", text: "Enter your phone number first." });
      return;
    }
    await doAction("request-code", { phoneNumber: pairingPhone.trim() });
  };

  // ─── Reset credentials (go back to step 1) ───────────────────────────────────
  const resetToken = async () => {
    if (!confirm("This will clear your saved access token. You will need to re-enter it. Continue?")) return;
    try {
      await apiFetch("/api/whatsapp/config", {
        method: "POST",
        authToken: token!,
        body: { token: "_clear_", instanceId: "" },
      });
    } catch {}
    // Force a re-read — even if the above fails, clear local state
    setCfg(prev => prev ? { ...prev, hasToken: false, hasInstance: false, configured: false, tokenMasked: "", instanceId: "" } : null);
  };

  // ────────────────────────────────────────────────────────────────────────────
  // Render
  // ────────────────────────────────────────────────────────────────────────────

  if (loading || cfgLoading) {
    return (
      <div className="max-w-xl mx-auto w-full p-6 flex items-center gap-2 text-sm text-gray-500">
        <Spinner /> Loading…
      </div>
    );
  }

  return (
    <div className="max-w-xl mx-auto w-full p-6 space-y-6">
      {/* Back button */}
      <button
        onClick={() => router.push("/dashboard")}
        className="flex items-center gap-1.5 text-sm text-gray-500 hover:text-gray-800 transition-colors"
      >
        <svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4" viewBox="0 0 20 20" fill="currentColor">
          <path fillRule="evenodd" d="M9.707 16.707a1 1 0 01-1.414 0l-6-6a1 1 0 010-1.414l6-6a1 1 0 011.414 1.414L5.414 9H17a1 1 0 110 2H5.414l4.293 4.293a1 1 0 010 1.414z" clipRule="evenodd" />
        </svg>
        Back
      </button>

      {/* Header */}
      <div className="flex items-center gap-3">
        <span className="text-3xl">💬</span>
        <div>
          <h1 className="text-2xl font-semibold leading-tight">WhatsApp Integration</h1>
          <p className="text-sm text-gray-500">Powered by WAWP</p>
        </div>
      </div>

      {/* Step indicator */}
      <StepIndicator step={step} />

      {/* Global action message */}
      {actionMsg && (
        <Alert type={actionMsg.type}>{actionMsg.text}</Alert>
      )}

      {/* ── STEP 1: Enter access token ──────────────────────────────────────── */}
      {step === 1 && (
        <section className="border rounded-xl p-6 bg-white shadow-sm space-y-4">
          <h2 className="text-lg font-semibold">Step 1 — Enter your WAWP Access Token</h2>
          <p className="text-sm text-gray-600">
            Your access token is found in your WAWP account dashboard at{" "}
            <a
              href="https://app.wawp.net"
              target="_blank"
              rel="noopener noreferrer"
              className="text-indigo-600 hover:underline"
            >
              app.wawp.net
            </a>
            .
          </p>
          <div className="space-y-2">
            <label className="block text-xs font-medium text-gray-700">Access Token</label>
            <input
              type="password"
              value={inputToken}
              onChange={e => setInputToken(e.target.value)}
              onKeyDown={e => e.key === "Enter" && saveToken()}
              placeholder="Paste your WAWP access token"
              className="w-full border rounded-lg px-3 py-2 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-indigo-500"
            />
          </div>
          <button
            onClick={saveToken}
            disabled={savingToken}
            className="flex items-center gap-2 px-5 py-2.5 rounded-lg bg-indigo-600 text-white text-sm font-medium hover:bg-indigo-700 disabled:opacity-50"
          >
            {savingToken && <Spinner />}
            {savingToken ? "Saving…" : "Save Token & Continue"}
          </button>
        </section>
      )}

      {/* ── STEP 2: Instance ID ─────────────────────────────────────────────── */}
      {step === 2 && (
        <section className="border rounded-xl p-6 bg-white shadow-sm space-y-5">
          <div className="flex items-center justify-between">
            <h2 className="text-lg font-semibold">Step 2 — Set Up Session Instance</h2>
            <span className="text-xs text-gray-400 font-mono bg-gray-100 px-2 py-0.5 rounded">
              Token: {cfg?.tokenMasked}
            </span>
          </div>
          <p className="text-sm text-gray-600">
            You need a WAWP session instance. Either create a brand-new one, or enter an
            existing Instance ID.
          </p>

          {/* Tab toggle */}
          <div className="flex rounded-lg border overflow-hidden text-sm font-medium">
            <button
              onClick={() => setInstanceMode("create")}
              className={`flex-1 px-4 py-2.5 transition-colors ${
                instanceMode === "create"
                  ? "bg-indigo-600 text-white"
                  : "bg-white text-gray-600 hover:bg-gray-50"
              }`}
            >
              Create new instance
            </button>
            <button
              onClick={() => setInstanceMode("enter")}
              className={`flex-1 px-4 py-2.5 border-l transition-colors ${
                instanceMode === "enter"
                  ? "bg-indigo-600 text-white"
                  : "bg-white text-gray-600 hover:bg-gray-50"
              }`}
            >
              Enter existing ID
            </button>
          </div>

          {instanceMode === "create" && (
            <div className="space-y-3">
              <p className="text-sm text-gray-600">
                Click below to create a new WAWP session. The Instance ID will be saved
                automatically.
              </p>
              <button
                onClick={createInstance}
                disabled={savingInstance}
                className="flex items-center gap-2 px-5 py-2.5 rounded-lg bg-indigo-600 text-white text-sm font-medium hover:bg-indigo-700 disabled:opacity-50"
              >
                {savingInstance && <Spinner />}
                {savingInstance ? "Creating…" : "Create Instance"}
              </button>
            </div>
          )}

          {instanceMode === "enter" && (
            <div className="space-y-3">
              <div>
                <label className="block text-xs font-medium text-gray-700 mb-1">
                  Instance ID
                </label>
                <input
                  type="text"
                  value={inputInstanceId}
                  onChange={e => setInputInstanceId(e.target.value)}
                  onKeyDown={e => e.key === "Enter" && saveInstanceId()}
                  placeholder="e.g. BF14B761C364"
                  className="w-full border rounded-lg px-3 py-2 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-indigo-500"
                />
              </div>
              <button
                onClick={saveInstanceId}
                disabled={savingInstance}
                className="flex items-center gap-2 px-5 py-2.5 rounded-lg bg-indigo-600 text-white text-sm font-medium hover:bg-indigo-700 disabled:opacity-50"
              >
                {savingInstance && <Spinner />}
                {savingInstance ? "Saving…" : "Save & Continue"}
              </button>
            </div>
          )}

          <button
            onClick={resetToken}
            className="text-xs text-gray-400 hover:text-red-500 hover:underline"
          >
            ← Change access token
          </button>
        </section>
      )}

      {/* ── STEP 3: Full management ─────────────────────────────────────────── */}
      {step === 3 && (
        <>
          {/* Status card */}
          <section className="border rounded-xl p-5 bg-white shadow-sm space-y-3">
            <div className="flex items-center justify-between">
              <h2 className="text-lg font-semibold">Session Status</h2>
              <button
                onClick={fetchStatus}
                className="text-xs text-indigo-600 hover:underline"
              >
                Refresh
              </button>
            </div>

            {status === null ? (
              <div className="flex items-center gap-2 text-sm text-gray-500">
                <Spinner /> Fetching status…
              </div>
            ) : (
              <div className="flex items-center gap-2">
                <span className="text-lg">{STATUS_ICONS[status] ?? "⚪"}</span>
                <span
                  className={`inline-flex items-center px-3 py-1 rounded-full border text-sm font-semibold ${
                    STATUS_COLORS[status] ?? "bg-gray-100 text-gray-700 border-gray-300"
                  }`}
                >
                  {status}
                </span>
              </div>
            )}

            {statusMsg && <p className="text-xs text-gray-500">{statusMsg}</p>}

            {status === "FAILED" && (
              <Alert type="err">
                The session has failed. The system will attempt to auto-restart. You can also
                restart manually below.
              </Alert>
            )}

            {status && POLLING_STATUSES.has(status) && (
              <p className="text-xs text-gray-400 flex items-center gap-1">
                <Spinner /> Auto-refreshing every 5 seconds…
              </p>
            )}

            {/* Config info strip */}
            <div className="flex flex-wrap gap-3 pt-2 border-t text-xs text-gray-500">
              <span>
                Token: <span className="font-mono">{cfg?.tokenMasked || "—"}</span>
              </span>
              <span>
                Instance: <span className="font-mono">{cfg?.instanceId || "—"}</span>
              </span>
            </div>
          </section>

          {/* QR Code */}
          {status === "SCAN_QR_CODE" && (
            <section className="border rounded-xl p-5 bg-white shadow-sm space-y-4">
              <div className="flex items-center justify-between">
                <h2 className="text-lg font-semibold">Scan QR Code</h2>
                <button
                  onClick={fetchQr}
                  className="text-xs text-indigo-600 hover:underline"
                >
                  Refresh QR
                </button>
              </div>
              <p className="text-sm text-gray-600">
                Open WhatsApp → Linked Devices → Link a Device, then scan the code below.
              </p>
              {qrSrc ? (
                <img
                  src={qrSrc}
                  alt="WhatsApp QR Code"
                  className="w-56 h-56 border rounded-lg"
                />
              ) : (
                <div className="flex items-center gap-2 text-sm text-gray-400">
                  <Spinner /> Loading QR…
                </div>
              )}
              <p className="text-xs text-gray-400">
                QR codes expire after ~20 seconds — click Refresh QR if it stops working.
              </p>
            </section>
          )}

          {/* Pairing code */}
          {status === "SCAN_QR_CODE" && (
            <section className="border rounded-xl p-5 bg-white shadow-sm space-y-4">
              <h2 className="text-lg font-semibold">Link by Phone Number Instead</h2>
              <p className="text-sm text-gray-600">
                Enter your WhatsApp number (SA format, e.g. 082 123 4567) to receive a pairing
                code on your phone.
              </p>
              <div className="flex gap-2">
                <input
                  type="tel"
                  value={pairingPhone}
                  onChange={e => setPairingPhone(e.target.value)}
                  placeholder="082 123 4567"
                  className="flex-1 border rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500"
                />
                <button
                  onClick={requestPairingCode}
                  disabled={busy === "request-code"}
                  className="flex items-center gap-1.5 px-4 py-2 rounded-lg bg-indigo-600 text-white text-sm font-medium hover:bg-indigo-700 disabled:opacity-50"
                >
                  {busy === "request-code" && <Spinner />}
                  {busy === "request-code" ? "Sending…" : "Send code"}
                </button>
              </div>
            </section>
          )}

          {/* Session controls */}
          <section className="border rounded-xl p-5 bg-white shadow-sm space-y-4">
            <h2 className="text-lg font-semibold">Session Controls</h2>
            <div className="flex flex-wrap gap-3">
              <ActionButton
                label="Start"
                busyLabel="Starting…"
                isBusy={busy === "start"}
                disabled={!!busy}
                color="green"
                onClick={() => doAction("start")}
              />
              <ActionButton
                label="Restart"
                busyLabel="Restarting…"
                isBusy={busy === "restart"}
                disabled={!!busy}
                color="amber"
                onClick={() => doAction("restart")}
              />
              <ActionButton
                label="Logout"
                busyLabel="Logging out…"
                isBusy={busy === "logout"}
                disabled={!!busy}
                color="red-outline"
                onClick={() => {
                  if (!confirm("This will log out the linked WhatsApp account. Are you sure?")) return;
                  doAction("logout");
                }}
              />
            </div>
          </section>

          {/* Instance management */}
          <section className="border rounded-xl p-5 bg-white shadow-sm space-y-4">
            <h2 className="text-lg font-semibold">Instance Management</h2>
            <p className="text-sm text-gray-600">
              Create a brand-new instance or permanently delete the current one. Deleting will
              require you to set up a new instance.
            </p>
            <div className="flex flex-wrap gap-3">
              <ActionButton
                label="Create New Instance"
                busyLabel="Creating…"
                isBusy={busy === "create-instance"}
                disabled={!!busy}
                color="blue"
                onClick={() => doAction("create-instance")}
              />
              <ActionButton
                label="Delete Instance"
                busyLabel="Deleting…"
                isBusy={busy === "delete-instance"}
                disabled={!!busy}
                color="red-outline"
                onClick={() => {
                  if (!confirm("This will PERMANENTLY delete the instance. You'll need to create a new one. Are you sure?")) return;
                  doAction("delete-instance");
                }}
              />
            </div>
          </section>

          {/* Update credentials */}
          <details className="border rounded-xl bg-white shadow-sm">
            <summary className="p-5 cursor-pointer text-sm font-semibold text-gray-700 select-none list-none flex items-center justify-between">
              <span>Update Credentials</span>
              <span className="text-gray-400 text-xs">expand ▾</span>
            </summary>
            <div className="px-5 pb-5 space-y-3 border-t pt-4">
              <p className="text-sm text-gray-600">
                Change your WAWP access token or Instance ID. Leave a field blank to keep the
                current value.
              </p>
              <div>
                <label className="block text-xs font-medium text-gray-700 mb-1">
                  New Access Token
                </label>
                <input
                  type="password"
                  value={inputToken}
                  onChange={e => setInputToken(e.target.value)}
                  placeholder="Leave blank to keep current token"
                  className="w-full border rounded-lg px-3 py-2 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-indigo-500"
                />
              </div>
              <div>
                <label className="block text-xs font-medium text-gray-700 mb-1">
                  New Instance ID
                </label>
                <input
                  type="text"
                  value={inputInstanceId}
                  onChange={e => setInputInstanceId(e.target.value)}
                  placeholder="Leave blank to keep current instance"
                  className="w-full border rounded-lg px-3 py-2 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-indigo-500"
                />
              </div>
              <button
                onClick={async () => {
                  if (!inputToken.trim() && !inputInstanceId.trim()) {
                    setActionMsg({ type: "err", text: "Enter at least one field to update." });
                    return;
                  }
                  setSavingToken(true);
                  setActionMsg(null);
                  try {
                    await apiFetch("/api/whatsapp/config", {
                      method: "POST",
                      authToken: token!,
                      body: {
                        token:      inputToken.trim() || undefined,
                        instanceId: inputInstanceId.trim() || undefined,
                      },
                    });
                    setActionMsg({ type: "ok", text: "Credentials updated." });
                    setInputToken("");
                    setInputInstanceId("");
                    await fetchConfig();
                  } catch (e: any) {
                    setActionMsg({ type: "err", text: e?.message || "Failed to update." });
                  } finally {
                    setSavingToken(false);
                  }
                }}
                disabled={savingToken}
                className="flex items-center gap-2 px-4 py-2 rounded-lg bg-indigo-600 text-white text-sm font-medium hover:bg-indigo-700 disabled:opacity-50"
              >
                {savingToken && <Spinner />}
                {savingToken ? "Saving…" : "Save Changes"}
              </button>
            </div>
          </details>
        </>
      )}

      <p className="text-xs text-gray-400 text-center">
        WhatsApp notifications powered by{" "}
        <a
          href="https://wawp.net"
          target="_blank"
          rel="noopener noreferrer"
          className="hover:underline"
        >
          WAWP
        </a>
        . Session auto-recovers on failure; admin alert sent if recovery fails.
      </p>
    </div>
  );
}

// ─── Sub-components ───────────────────────────────────────────────────────────

function StepIndicator({ step }: { step: number }) {
  const steps = [
    { n: 1, label: "Access Token" },
    { n: 2, label: "Session Instance" },
    { n: 3, label: "Connected" },
  ];
  return (
    <div className="flex items-center gap-0">
      {steps.map((s, i) => {
        const done    = step > s.n;
        const current = step === s.n;
        return (
          <React.Fragment key={s.n}>
            <div className="flex flex-col items-center">
              <div
                className={`w-8 h-8 rounded-full flex items-center justify-center text-sm font-bold border-2 transition-colors ${
                  done
                    ? "bg-green-500 border-green-500 text-white"
                    : current
                    ? "bg-indigo-600 border-indigo-600 text-white"
                    : "bg-white border-gray-300 text-gray-400"
                }`}
              >
                {done ? "✓" : s.n}
              </div>
              <span
                className={`text-xs mt-1 font-medium ${
                  done || current ? "text-gray-700" : "text-gray-400"
                }`}
              >
                {s.label}
              </span>
            </div>
            {i < steps.length - 1 && (
              <div
                className={`flex-1 h-0.5 mb-5 mx-1 transition-colors ${
                  done ? "bg-green-400" : "bg-gray-200"
                }`}
              />
            )}
          </React.Fragment>
        );
      })}
    </div>
  );
}

type ButtonColor = "green" | "amber" | "blue" | "red-outline";

function ActionButton({
  label,
  busyLabel,
  isBusy,
  disabled,
  color,
  onClick,
}: {
  label: string;
  busyLabel: string;
  isBusy: boolean;
  disabled: boolean;
  color: ButtonColor;
  onClick: () => void;
}) {
  const base = "flex items-center gap-1.5 px-4 py-2 rounded-lg text-sm font-medium disabled:opacity-50 transition-colors";
  const colors: Record<ButtonColor, string> = {
    green:       "bg-green-600 text-white hover:bg-green-700",
    amber:       "bg-amber-500 text-white hover:bg-amber-600",
    blue:        "bg-blue-600 text-white hover:bg-blue-700",
    "red-outline": "border border-red-600 text-red-600 hover:bg-red-50",
  };
  return (
    <button onClick={onClick} disabled={disabled} className={`${base} ${colors[color]}`}>
      {isBusy && <Spinner />}
      {isBusy ? busyLabel : label}
    </button>
  );
}