// @File: src/pages/ClientWhatsappWorkflows.tsx
// @Desc: Client-area Automation Workflows console. Lets a customer pair
//        a trigger (keyword, new message, first-message, outside hours,
//        no-reply timeout, added-to-campaign) with an ordered list of
//        actions (send reply, tag contact, mark lead, notify admin) and
//        dry-run the rule against a sample message.
import { useCallback, useEffect, useMemo, useState } from "react";
import { Link } from "react-router-dom";
import {
  ArrowLeft,
  Bot,
  Loader2,
  Plus,
  RefreshCw,
  Trash2,
  Zap,
} from "lucide-react";

import {
  WhatsappWorkflow,
  WhatsappWorkflowAction,
  WhatsappWorkflowActionType,
  WhatsappWorkflowTrigger,
  WhatsappWorkflowTriggerType,
  WhatsappWorkflowTestResult,
  waCreateWorkflow,
  waDeleteWorkflow,
  waListWorkflows,
  waTestWorkflow,
  waUpdateWorkflow,
} from "@/lib/whatsappApi";

const TRIGGER_OPTIONS: { value: WhatsappWorkflowTriggerType; label: string }[] = [
  { value: "new_message", label: "Any new message" },
  { value: "keyword", label: "Keyword matches" },
  { value: "first_message", label: "First message from a contact" },
  { value: "outside_hours", label: "Message outside business hours" },
  { value: "no_reply_after", label: "No reply after N minutes" },
  { value: "added_to_campaign", label: "Contact added to a campaign" },
];

const ACTION_OPTIONS: { value: WhatsappWorkflowActionType; label: string }[] = [
  { value: "send_message", label: "Send a reply" },
  { value: "assign_tag", label: "Tag the contact" },
  { value: "mark_lead", label: "Mark as lead" },
  { value: "notify_admin", label: "Notify admin" },
];

interface Draft {
  id: number | null;
  name: string;
  description: string;
  is_active: boolean;
  trigger: WhatsappWorkflowTrigger;
  actions: WhatsappWorkflowAction[];
}

function emptyDraft(): Draft {
  return {
    id: null,
    name: "",
    description: "",
    is_active: true,
    trigger: { type: "keyword", keyword: "" },
    actions: [{ type: "send_message", body: "" }],
  };
}

function summarizeTrigger(t: WhatsappWorkflowTrigger): string {
  switch (t.type) {
    case "keyword":
      return `Keyword: "${t.keyword ?? ""}"`;
    case "no_reply_after":
      return `No reply for ${t.minutes ?? 0} min`;
    case "added_to_campaign":
      return `Added to campaign #${t.campaign_id ?? "?"}`;
    default:
      return TRIGGER_OPTIONS.find((o) => o.value === t.type)?.label ?? t.type;
  }
}

function summarizeAction(a: WhatsappWorkflowAction): string {
  switch (a.type) {
    case "send_message":
      return a.body ? `Reply: "${a.body.slice(0, 60)}"` : "Reply";
    case "assign_tag":
      return `Tag: ${a.tag ?? ""}`;
    case "mark_lead":
      return "Mark as lead";
    case "notify_admin":
      return `Notify admin${a.note ? `: ${a.note}` : ""}`;
    default:
      return a.type;
  }
}

export default function ClientWhatsappWorkflows() {
  const [workflows, setWorkflows] = useState<WhatsappWorkflow[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [busyId, setBusyId] = useState<number | null>(null);
  const [editor, setEditor] = useState<Draft | null>(null);
  const [submitting, setSubmitting] = useState(false);
  const [testSample, setTestSample] = useState("");
  const [testResult, setTestResult] = useState<WhatsappWorkflowTestResult | null>(null);

  const reload = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      setWorkflows(await waListWorkflows());
    } catch (err) {
      setError(err instanceof Error ? err.message : String(err));
    } finally {
      setLoading(false);
    }
  }, []);

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

  const beginCreate = useCallback(() => {
    setEditor(emptyDraft());
    setTestResult(null);
    setTestSample("");
  }, []);

  const beginEdit = useCallback((w: WhatsappWorkflow) => {
    setEditor({
      id: w.id,
      name: w.name,
      description: w.description ?? "",
      is_active: w.is_active,
      trigger: { ...w.trigger },
      actions: w.actions.length > 0 ? w.actions.map((a) => ({ ...a })) : [{ type: "send_message", body: "" }],
    });
    setTestResult(null);
    setTestSample("");
  }, []);

  const patchTrigger = useCallback(
    (patch: Partial<WhatsappWorkflowTrigger>) => {
      setEditor((prev) =>
        prev ? { ...prev, trigger: { ...prev.trigger, ...patch } } : prev,
      );
    },
    [],
  );

  const patchAction = useCallback(
    (idx: number, patch: Partial<WhatsappWorkflowAction>) => {
      setEditor((prev) => {
        if (!prev) return prev;
        const actions = prev.actions.map((a, i) => (i === idx ? { ...a, ...patch } : a));
        return { ...prev, actions };
      });
    },
    [],
  );

  const addAction = useCallback(() => {
    setEditor((prev) =>
      prev ? { ...prev, actions: [...prev.actions, { type: "send_message", body: "" }] } : prev,
    );
  }, []);

  const removeAction = useCallback((idx: number) => {
    setEditor((prev) => {
      if (!prev) return prev;
      const actions = prev.actions.filter((_, i) => i !== idx);
      return {
        ...prev,
        actions: actions.length > 0 ? actions : [{ type: "send_message", body: "" }],
      };
    });
  }, []);

  const onSave = useCallback(async () => {
    if (!editor) return;
    setSubmitting(true);
    setError(null);
    try {
      if (!editor.name.trim()) throw new Error("Workflow name is required.");
      if (editor.actions.length === 0) throw new Error("Add at least one action.");
      const payload = {
        name: editor.name.trim(),
        description: editor.description.trim() || null,
        is_active: editor.is_active,
        trigger: editor.trigger,
        actions: editor.actions,
      };
      if (editor.id === null) {
        await waCreateWorkflow(payload);
      } else {
        await waUpdateWorkflow(editor.id, payload);
      }
      setEditor(null);
      await reload();
    } catch (err) {
      setError(err instanceof Error ? err.message : String(err));
    } finally {
      setSubmitting(false);
    }
  }, [editor, reload]);

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

  const onToggle = useCallback(
    async (w: WhatsappWorkflow) => {
      setBusyId(w.id);
      setError(null);
      try {
        await waUpdateWorkflow(w.id, { is_active: !w.is_active });
        await reload();
      } catch (err) {
        setError(err instanceof Error ? err.message : String(err));
      } finally {
        setBusyId(null);
      }
    },
    [reload],
  );

  const onTest = useCallback(async () => {
    if (!editor?.id) {
      setError("Save the workflow first before running a test.");
      return;
    }
    setError(null);
    try {
      const event =
        editor.trigger.type === "first_message" ||
        editor.trigger.type === "outside_hours" ||
        editor.trigger.type === "no_reply_after" ||
        editor.trigger.type === "added_to_campaign"
          ? editor.trigger.type
          : "new_message";
      setTestResult(await waTestWorkflow(editor.id, testSample, event));
    } catch (err) {
      setError(err instanceof Error ? err.message : String(err));
    }
  }, [editor, testSample]);

  const triggerNeedsKeyword = editor?.trigger.type === "keyword";
  const triggerNeedsMinutes = editor?.trigger.type === "no_reply_after";
  const triggerNeedsCampaign = editor?.trigger.type === "added_to_campaign";

  const workflowEmpty = useMemo(() => workflows.length === 0, [workflows.length]);

  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 Automation
          </h1>
          <p className="truncate text-xs text-white/80">
            Trigger-driven replies, tagging, and lead capture.
          </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>
        <button
          type="button"
          onClick={beginCreate}
          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 workflow
        </button>
      </header>

      <main className="mx-auto grid max-w-6xl grid-cols-1 gap-6 px-4 py-6 lg:grid-cols-5">
        <section className="lg:col-span-3">
          {error ? (
            <div className="mb-4 rounded-lg border border-rose-200 bg-rose-50 px-4 py-3 text-sm text-rose-700">
              {error}
            </div>
          ) : null}
          <div 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">
                <Zap className="h-4 w-4 text-[#128C7E]" />
                Your workflows
              </h2>
            </div>
            {loading ? (
              <div className="flex items-center justify-center py-12">
                <Loader2 className="h-5 w-5 animate-spin text-slate-400" />
              </div>
            ) : workflowEmpty ? (
              <div className="py-12 text-center text-sm text-slate-500">
                No workflows yet. Click{" "}
                <span className="font-medium">New workflow</span> to build your first
                automation.
              </div>
            ) : (
              <ul className="divide-y divide-slate-100">
                {workflows.map((w) => (
                  <li key={w.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">
                            {w.name}
                          </span>
                          <span
                            className={`rounded-full px-2 py-0.5 text-[10px] font-medium uppercase ${
                              w.is_active
                                ? "bg-emerald-100 text-emerald-700"
                                : "bg-slate-200 text-slate-600"
                            }`}
                          >
                            {w.is_active ? "Active" : "Paused"}
                          </span>
                        </div>
                        {w.description ? (
                          <p className="mt-1 text-xs text-slate-500">{w.description}</p>
                        ) : null}
                        <div className="mt-2 text-xs text-slate-600">
                          <span className="font-semibold">When:</span>{" "}
                          {summarizeTrigger(w.trigger)}
                        </div>
                        <ul className="mt-1 text-xs text-slate-600">
                          {w.actions.map((a, i) => (
                            <li key={i}>
                              <span className="font-semibold">Then:</span>{" "}
                              {summarizeAction(a)}
                            </li>
                          ))}
                        </ul>
                        <p className="mt-2 text-[11px] text-slate-400">
                          Runs: {w.run_count} · Last run:{" "}
                          {w.last_run_at
                            ? new Date(w.last_run_at).toLocaleString()
                            : "never"}
                        </p>
                      </div>
                      <div className="flex flex-shrink-0 flex-wrap items-center gap-1">
                        <button
                          type="button"
                          disabled={busyId === w.id}
                          onClick={() => void onToggle(w)}
                          className="rounded px-2 py-1 text-xs font-medium text-slate-700 hover:bg-slate-100 disabled:opacity-50"
                        >
                          {w.is_active ? "Pause" : "Activate"}
                        </button>
                        <button
                          type="button"
                          onClick={() => beginEdit(w)}
                          className="rounded px-2 py-1 text-xs font-medium text-[#128C7E] hover:bg-emerald-50"
                        >
                          Edit
                        </button>
                        <button
                          type="button"
                          disabled={busyId === w.id}
                          onClick={() => void onDelete(w.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>
            )}
          </div>
        </section>

        {/* Editor column */}
        <section className="lg:col-span-2">
          <div className="sticky top-[80px] rounded-lg border border-slate-200 bg-white p-4 shadow-sm">
            <h2 className="mb-3 flex items-center gap-2 text-sm font-semibold text-slate-700">
              <Bot className="h-4 w-4 text-[#128C7E]" />
              {editor
                ? editor.id === null
                  ? "New workflow"
                  : `Edit: ${editor.name || "Untitled"}`
                : "Workflow builder"}
            </h2>
            {!editor ? (
              <p className="text-sm text-slate-500">
                Pick a workflow on the left to edit, or create a new one.
              </p>
            ) : (
              <div className="space-y-3">
                <label className="block text-xs font-medium text-slate-600">
                  Name
                  <input
                    value={editor.name}
                    onChange={(e) => setEditor({ ...editor, name: e.target.value })}
                    className="mt-1 w-full rounded border border-slate-300 px-2 py-1.5 text-sm focus:border-[#128C7E] focus:outline-none"
                  />
                </label>
                <label className="block text-xs font-medium text-slate-600">
                  Description
                  <textarea
                    value={editor.description}
                    onChange={(e) =>
                      setEditor({ ...editor, description: e.target.value })
                    }
                    rows={2}
                    className="mt-1 w-full resize-y rounded border border-slate-300 px-2 py-1.5 text-sm focus:border-[#128C7E] focus:outline-none"
                  />
                </label>

                <div>
                  <label className="block text-xs font-medium text-slate-600">
                    Trigger
                    <select
                      value={editor.trigger.type}
                      onChange={(e) =>
                        patchTrigger({
                          type: e.target.value as WhatsappWorkflowTriggerType,
                          // reset fields that don't apply to the new type
                          keyword: undefined,
                          minutes: undefined,
                          campaign_id: undefined,
                        })
                      }
                      className="mt-1 w-full rounded border border-slate-300 px-2 py-1.5 text-sm focus:border-[#128C7E] focus:outline-none"
                    >
                      {TRIGGER_OPTIONS.map((o) => (
                        <option key={o.value} value={o.value}>
                          {o.label}
                        </option>
                      ))}
                    </select>
                  </label>
                  {triggerNeedsKeyword && (
                    <input
                      value={editor.trigger.keyword ?? ""}
                      onChange={(e) => patchTrigger({ keyword: e.target.value })}
                      placeholder="Keyword, e.g. pricing"
                      className="mt-2 w-full rounded border border-slate-300 px-2 py-1.5 text-sm focus:border-[#128C7E] focus:outline-none"
                    />
                  )}
                  {triggerNeedsMinutes && (
                    <input
                      type="number"
                      min={1}
                      max={10080}
                      value={editor.trigger.minutes ?? 30}
                      onChange={(e) =>
                        patchTrigger({ minutes: Number(e.target.value) || 30 })
                      }
                      placeholder="Minutes"
                      className="mt-2 w-full rounded border border-slate-300 px-2 py-1.5 text-sm focus:border-[#128C7E] focus:outline-none"
                    />
                  )}
                  {triggerNeedsCampaign && (
                    <input
                      type="number"
                      min={1}
                      value={editor.trigger.campaign_id ?? ""}
                      onChange={(e) =>
                        patchTrigger({
                          campaign_id: Number(e.target.value) || null,
                        })
                      }
                      placeholder="Campaign ID"
                      className="mt-2 w-full rounded border border-slate-300 px-2 py-1.5 text-sm focus:border-[#128C7E] focus:outline-none"
                    />
                  )}
                </div>

                <div>
                  <div className="mb-1 flex items-center justify-between text-xs font-medium text-slate-600">
                    <span>Actions</span>
                    <button
                      type="button"
                      onClick={addAction}
                      className="text-xs font-medium text-[#128C7E] hover:underline"
                    >
                      + Add action
                    </button>
                  </div>
                  <div className="space-y-2">
                    {editor.actions.map((a, idx) => (
                      <div
                        key={idx}
                        className="rounded border border-slate-200 bg-slate-50 p-2"
                      >
                        <div className="flex items-center gap-2">
                          <select
                            value={a.type}
                            onChange={(e) =>
                              patchAction(idx, {
                                type: e.target.value as WhatsappWorkflowActionType,
                                body: undefined,
                                tag: undefined,
                                note: undefined,
                              })
                            }
                            className="flex-1 rounded border border-slate-300 px-2 py-1 text-sm focus:border-[#128C7E] focus:outline-none"
                          >
                            {ACTION_OPTIONS.map((o) => (
                              <option key={o.value} value={o.value}>
                                {o.label}
                              </option>
                            ))}
                          </select>
                          <button
                            type="button"
                            onClick={() => removeAction(idx)}
                            className="rounded p-1 text-slate-400 hover:bg-slate-200 hover:text-slate-600"
                            aria-label="Remove action"
                          >
                            <Trash2 className="h-3.5 w-3.5" />
                          </button>
                        </div>
                        {a.type === "send_message" && (
                          <textarea
                            value={a.body ?? ""}
                            onChange={(e) => patchAction(idx, { body: e.target.value })}
                            rows={2}
                            placeholder="Reply body"
                            className="mt-2 w-full resize-y rounded border border-slate-300 px-2 py-1 text-sm focus:border-[#128C7E] focus:outline-none"
                          />
                        )}
                        {a.type === "assign_tag" && (
                          <input
                            value={a.tag ?? ""}
                            onChange={(e) => patchAction(idx, { tag: e.target.value })}
                            placeholder="Tag name"
                            className="mt-2 w-full rounded border border-slate-300 px-2 py-1 text-sm focus:border-[#128C7E] focus:outline-none"
                          />
                        )}
                        {a.type === "notify_admin" && (
                          <input
                            value={a.note ?? ""}
                            onChange={(e) => patchAction(idx, { note: e.target.value })}
                            placeholder="Optional note for the admin"
                            className="mt-2 w-full rounded border border-slate-300 px-2 py-1 text-sm focus:border-[#128C7E] focus:outline-none"
                          />
                        )}
                      </div>
                    ))}
                  </div>
                </div>

                <label className="flex items-center gap-2 text-xs text-slate-600">
                  <input
                    type="checkbox"
                    checked={editor.is_active}
                    onChange={(e) =>
                      setEditor({ ...editor, is_active: e.target.checked })
                    }
                  />
                  Activate this workflow
                </label>

                <div className="flex items-center justify-end gap-2">
                  <button
                    type="button"
                    onClick={() => setEditor(null)}
                    className="rounded px-3 py-1.5 text-sm text-slate-600 hover:bg-slate-100"
                  >
                    Close
                  </button>
                  <button
                    type="button"
                    disabled={submitting}
                    onClick={onSave}
                    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:opacity-70"
                  >
                    {submitting ? <Loader2 className="h-4 w-4 animate-spin" /> : null}
                    Save
                  </button>
                </div>

                {editor.id !== null && (
                  <div className="mt-3 rounded border border-dashed border-slate-300 p-3">
                    <div className="text-xs font-semibold text-slate-700">
                      Test this workflow
                    </div>
                    <p className="mt-1 text-[11px] text-slate-500">
                      Runs the trigger against a sample message. No replies are sent.
                    </p>
                    <input
                      value={testSample}
                      onChange={(e) => setTestSample(e.target.value)}
                      placeholder="Sample incoming message"
                      className="mt-2 w-full rounded border border-slate-300 px-2 py-1 text-sm focus:border-[#128C7E] focus:outline-none"
                    />
                    <button
                      type="button"
                      onClick={onTest}
                      className="mt-2 rounded bg-slate-800 px-3 py-1.5 text-xs font-medium text-white hover:bg-slate-700"
                    >
                      Dry-run
                    </button>
                    {testResult ? (
                      <div className="mt-2 rounded bg-slate-50 p-2 text-xs text-slate-700">
                        <div>
                          <span className="font-semibold">Matched:</span>{" "}
                          {testResult.matched ? "yes" : "no"}
                        </div>
                        {testResult.preview_actions.length > 0 && (
                          <ul className="mt-1 list-inside list-disc">
                            {testResult.preview_actions.map((p, i) => (
                              <li key={i}>
                                {p.type} — {p.status}
                                {p.body ? `: ${p.body}` : ""}
                                {p.tag ? ` #${p.tag}` : ""}
                              </li>
                            ))}
                          </ul>
                        )}
                      </div>
                    ) : null}
                  </div>
                )}
              </div>
            )}
          </div>
        </section>
      </main>
    </div>
  );
}