"use client";

import { useState, useEffect, useCallback } from "react";
import {
  Plus, Trash2, Edit2, X, Code2, MousePointer, FileText, Globe,
  ArrowDownToLine, Clock, Loader2, Power,
} from "lucide-react";

export interface CustomEvent {
  id: string;
  name: string;
  triggerType: "click" | "form_submit" | "page_visit" | "scroll_to" | "time_on_page";
  triggerConfig: Record<string, string | number>;
  properties: Array<{ name: string; source: "fixed" | "element_text" | "element_attr" | "url_param"; value: string }>;
  isActive: boolean;
  createdAt: string;
  lastTriggered?: string | null;
}

const TRIGGER_OPTIONS = [
  { value: "click", label: "Click on element", icon: MousePointer, configFields: [{ key: "selector", label: "CSS Selector", placeholder: ".pricing-button, #signup" }] },
  { value: "form_submit", label: "Form submission", icon: FileText, configFields: [{ key: "selector", label: "Form CSS Selector", placeholder: "#contact-form" }] },
  { value: "page_visit", label: "Page visit", icon: Globe, configFields: [
    { key: "matchType", label: "Match", placeholder: "exact | contains | regex" },
    { key: "url", label: "URL Pattern", placeholder: "/pricing or /blog/.*" },
  ] },
  { value: "scroll_to", label: "Scroll to element", icon: ArrowDownToLine, configFields: [{ key: "selector", label: "CSS Selector", placeholder: "#footer, .cta-section" }] },
  { value: "time_on_page", label: "Time on page", icon: Clock, configFields: [{ key: "seconds", label: "Seconds", placeholder: "30" }] },
] as const;

type TriggerType = CustomEvent["triggerType"];

export interface CustomEventsProps { brandId: string }

export function CustomEvents({ brandId }: CustomEventsProps) {
  const [events, setEvents] = useState<CustomEvent[]>([]);
  const [loading, setLoading] = useState(true);
  const [modalOpen, setModalOpen] = useState(false);
  const [editing, setEditing] = useState<CustomEvent | null>(null);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const res = await fetch(`/api/site-tag/custom-events?brandId=${brandId}`);
      if (res.ok) {
        const data = await res.json();
        setEvents(data.events ?? []);
      }
    } catch { /* ignore */ }
    setLoading(false);
  }, [brandId]);

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

  async function handleSave(event: Partial<CustomEvent>) {
    if (editing) {
      const res = await fetch("/api/site-tag/custom-events", {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ brandId, eventId: editing.id, patch: event }),
      });
      if (res.ok) {
        const data = await res.json();
        setEvents(data.events ?? []);
      }
    } else {
      const res = await fetch("/api/site-tag/custom-events", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ brandId, event }),
      });
      if (res.ok) {
        const data = await res.json();
        setEvents(data.events ?? []);
      }
    }
    setModalOpen(false);
    setEditing(null);
  }

  async function handleDelete(eventId: string) {
    const res = await fetch(`/api/site-tag/custom-events?brandId=${brandId}&eventId=${eventId}`, { method: "DELETE" });
    if (res.ok) {
      const data = await res.json();
      setEvents(data.events ?? []);
    }
  }

  async function handleToggle(event: CustomEvent) {
    const res = await fetch("/api/site-tag/custom-events", {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ brandId, eventId: event.id, patch: { isActive: !event.isActive } }),
    });
    if (res.ok) {
      const data = await res.json();
      setEvents(data.events ?? []);
    }
  }

  function openCreate() {
    setEditing(null);
    setModalOpen(true);
  }

  function openEdit(event: CustomEvent) {
    setEditing(event);
    setModalOpen(true);
  }

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between">
        <div>
          <h3 className="text-sm font-bold text-slate-800">Custom Events</h3>
          <p className="text-xs text-slate-500 mt-0.5">Define events without writing code</p>
        </div>
        <button
          onClick={openCreate}
          className="flex items-center gap-1.5 px-3 py-2 bg-brand-600 text-white text-xs font-semibold rounded-lg hover:bg-brand-700 transition-colors"
        >
          <Plus className="w-3.5 h-3.5" />
          Create Custom Event
        </button>
      </div>

      {loading ? (
        <div className="flex items-center justify-center py-8">
          <Loader2 className="w-5 h-5 animate-spin text-slate-300" />
        </div>
      ) : events.length === 0 ? (
        <div className="bg-slate-50 rounded-xl border border-dashed border-slate-200 p-8 text-center">
          <Code2 className="w-8 h-8 text-slate-300 mx-auto mb-2" />
          <p className="text-sm font-semibold text-slate-700">No custom events yet</p>
          <p className="text-xs text-slate-500 mt-1">Click &ldquo;Create Custom Event&rdquo; to track clicks, form submissions, scrolls, or time on page.</p>
        </div>
      ) : (
        <div className="grid grid-cols-1 lg:grid-cols-2 gap-3">
          {events.map((e) => {
            const trigger = TRIGGER_OPTIONS.find((t) => t.value === e.triggerType);
            const TriggerIcon = trigger?.icon ?? Code2;
            return (
              <div key={e.id} className="bg-white rounded-xl border border-slate-200 p-4 hover:border-slate-300 transition-colors">
                <div className="flex items-start justify-between mb-2">
                  <div className="flex items-center gap-2">
                    <span className={`w-7 h-7 rounded-lg flex items-center justify-center ${e.isActive ? "bg-brand-50" : "bg-slate-100"}`}>
                      <TriggerIcon className={`w-3.5 h-3.5 ${e.isActive ? "text-brand-600" : "text-slate-400"}`} />
                    </span>
                    <div>
                      <p className="font-mono text-xs font-bold text-slate-900">{e.name}</p>
                      <p className="text-[10px] text-slate-400">{trigger?.label ?? e.triggerType}</p>
                    </div>
                  </div>
                  <div className="flex items-center gap-1">
                    <button
                      onClick={() => handleToggle(e)}
                      className={`p-1.5 rounded-md transition-colors ${e.isActive ? "text-emerald-500 hover:bg-emerald-50" : "text-slate-300 hover:bg-slate-100"}`}
                      title={e.isActive ? "Deactivate" : "Activate"}
                    >
                      <Power className="w-3 h-3" />
                    </button>
                    <button
                      onClick={() => openEdit(e)}
                      className="p-1.5 text-slate-400 hover:text-slate-700 hover:bg-slate-100 rounded-md transition-colors"
                      title="Edit"
                    >
                      <Edit2 className="w-3 h-3" />
                    </button>
                    <button
                      onClick={() => handleDelete(e.id)}
                      className="p-1.5 text-slate-300 hover:text-red-500 hover:bg-red-50 rounded-md transition-colors"
                      title="Delete"
                    >
                      <Trash2 className="w-3 h-3" />
                    </button>
                  </div>
                </div>
                <div className="text-[10px] text-slate-500 space-y-0.5 pl-9">
                  {Object.entries(e.triggerConfig).map(([k, v]) => (
                    <div key={k}>
                      <span className="text-slate-400">{k}:</span> <span className="font-mono text-slate-700">{String(v)}</span>
                    </div>
                  ))}
                  {e.properties.length > 0 && (
                    <div className="text-slate-400">+ {e.properties.length} {e.properties.length === 1 ? "property" : "properties"}</div>
                  )}
                  {e.lastTriggered && (
                    <div className="text-slate-400">Last fired: {new Date(e.lastTriggered).toLocaleString()}</div>
                  )}
                </div>
              </div>
            );
          })}
        </div>
      )}

      {modalOpen && (
        <CustomEventModal
          initial={editing}
          onClose={() => { setModalOpen(false); setEditing(null); }}
          onSave={handleSave}
        />
      )}
    </div>
  );
}

// ─── Modal ──────────────────────────────────────────────────────────────────

function CustomEventModal({ initial, onClose, onSave }: {
  initial: CustomEvent | null;
  onClose: () => void;
  onSave: (e: Partial<CustomEvent>) => void;
}) {
  const [name, setName] = useState(initial?.name ?? "");
  const [triggerType, setTriggerType] = useState<TriggerType>(initial?.triggerType ?? "click");
  const [triggerConfig, setTriggerConfig] = useState<Record<string, string>>(() => {
    const cfg: Record<string, string> = {};
    if (initial) for (const [k, v] of Object.entries(initial.triggerConfig)) cfg[k] = String(v);
    return cfg;
  });
  const [properties, setProperties] = useState<Array<{ name: string; source: string; value: string }>>(initial?.properties as Array<{ name: string; source: string; value: string }> ?? []);
  const [isActive, setIsActive] = useState(initial?.isActive ?? true);

  const trigger = TRIGGER_OPTIONS.find((t) => t.value === triggerType)!;

  // Reset config fields when trigger type changes
  useEffect(() => {
    if (initial && initial.triggerType === triggerType) return;
    setTriggerConfig({});
  }, [triggerType, initial]);

  const generatedJs = `window.meSEO.track("${name || "event_name"}"${properties.length > 0 ? ", " + JSON.stringify(properties.reduce<Record<string, string>>((acc, p) => { acc[p.name] = p.value; return acc; }, {})) : ""});`;

  const canSave = name.trim().length > 0 && Object.keys(triggerConfig).length > 0;

  function addProperty() {
    setProperties([...properties, { name: "", source: "fixed", value: "" }]);
  }

  function updateProperty(i: number, patch: Partial<{ name: string; source: string; value: string }>) {
    setProperties(properties.map((p, j) => j === i ? { ...p, ...patch } : p));
  }

  function removeProperty(i: number) {
    setProperties(properties.filter((_, j) => j !== i));
  }

  function handleSave() {
    onSave({
      name: name.trim(),
      triggerType,
      triggerConfig,
      properties: properties as CustomEvent["properties"],
      isActive,
    });
  }

  return (
    <>
      <div className="fixed inset-0 z-40 bg-slate-900/30" onClick={onClose} />
      <div className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-50 bg-white rounded-2xl shadow-xl border border-slate-200 w-[640px] max-w-[calc(100vw-2rem)] max-h-[calc(100vh-4rem)] overflow-y-auto">
        <div className="px-6 py-4 border-b border-slate-100 flex items-center justify-between sticky top-0 bg-white">
          <div>
            <h3 className="text-base font-bold text-slate-900">{initial ? "Edit Custom Event" : "Create Custom Event"}</h3>
            <p className="text-xs text-slate-500 mt-0.5">Define what to track without writing code</p>
          </div>
          <button onClick={onClose} className="p-1.5 text-slate-400 hover:text-slate-700 rounded-md hover:bg-slate-100">
            <X className="w-4 h-4" />
          </button>
        </div>

        <div className="px-6 py-5 space-y-5">
          {/* Event name */}
          <div>
            <label className="text-xs font-semibold text-slate-700 block mb-1.5">Event Name</label>
            <input
              type="text"
              value={name}
              onChange={(e) => setName(e.target.value.replace(/\s+/g, "_").toLowerCase())}
              placeholder="newsletter_signup, video_play, pricing_click"
              className="w-full px-3 py-2 text-sm font-mono border border-slate-200 rounded-lg focus:outline-none focus:border-brand-400 focus:ring-2 focus:ring-brand-100"
            />
            <p className="text-[10px] text-slate-400 mt-1">Use snake_case. Spaces are auto-converted.</p>
          </div>

          {/* Trigger type */}
          <div>
            <label className="text-xs font-semibold text-slate-700 block mb-1.5">Trigger Type</label>
            <div className="grid grid-cols-2 sm:grid-cols-3 gap-2">
              {TRIGGER_OPTIONS.map((t) => {
                const Icon = t.icon;
                const active = triggerType === t.value;
                return (
                  <button
                    key={t.value}
                    type="button"
                    onClick={() => setTriggerType(t.value as TriggerType)}
                    className={`flex items-center gap-2 px-3 py-2.5 rounded-lg border text-left transition-all ${
                      active
                        ? "bg-brand-50 border-brand-300 text-brand-700"
                        : "bg-white border-slate-200 text-slate-600 hover:border-slate-300"
                    }`}
                  >
                    <Icon className="w-3.5 h-3.5 shrink-0" />
                    <span className="text-xs font-medium">{t.label}</span>
                  </button>
                );
              })}
            </div>
          </div>

          {/* Trigger config (depends on type) */}
          <div>
            <label className="text-xs font-semibold text-slate-700 block mb-1.5">Trigger Configuration</label>
            <div className="space-y-2">
              {trigger.configFields.map((field) => (
                <div key={field.key}>
                  <label className="text-[10px] text-slate-500 block mb-0.5">{field.label}</label>
                  <input
                    type="text"
                    value={triggerConfig[field.key] ?? ""}
                    onChange={(e) => setTriggerConfig({ ...triggerConfig, [field.key]: e.target.value })}
                    placeholder={field.placeholder}
                    className="w-full px-3 py-2 text-xs font-mono border border-slate-200 rounded-lg focus:outline-none focus:border-brand-400 focus:ring-2 focus:ring-brand-100"
                  />
                </div>
              ))}
            </div>
          </div>

          {/* Event properties (optional) */}
          <div>
            <div className="flex items-center justify-between mb-1.5">
              <label className="text-xs font-semibold text-slate-700">Event Properties <span className="text-slate-400 font-normal">(optional)</span></label>
              <button onClick={addProperty} className="text-[10px] font-semibold text-brand-600 hover:underline">+ Add property</button>
            </div>
            {properties.length === 0 ? (
              <p className="text-[10px] text-slate-400">No properties — the event will fire with just the name.</p>
            ) : (
              <div className="space-y-2">
                {properties.map((p, i) => (
                  <div key={i} className="flex items-center gap-2">
                    <input
                      type="text"
                      value={p.name}
                      onChange={(e) => updateProperty(i, { name: e.target.value })}
                      placeholder="property name"
                      className="flex-1 px-2.5 py-1.5 text-xs font-mono border border-slate-200 rounded-md focus:outline-none focus:border-brand-400"
                    />
                    <select
                      value={p.source}
                      onChange={(e) => updateProperty(i, { source: e.target.value })}
                      className="px-2 py-1.5 text-xs border border-slate-200 rounded-md focus:outline-none focus:border-brand-400 bg-white"
                    >
                      <option value="fixed">Fixed value</option>
                      <option value="element_text">Element text</option>
                      <option value="element_attr">Element attribute</option>
                      <option value="url_param">URL parameter</option>
                    </select>
                    <input
                      type="text"
                      value={p.value}
                      onChange={(e) => updateProperty(i, { value: e.target.value })}
                      placeholder="value"
                      className="flex-1 px-2.5 py-1.5 text-xs font-mono border border-slate-200 rounded-md focus:outline-none focus:border-brand-400"
                    />
                    <button onClick={() => removeProperty(i)} className="p-1 text-slate-300 hover:text-red-500">
                      <X className="w-3 h-3" />
                    </button>
                  </div>
                ))}
              </div>
            )}
          </div>

          {/* Generated JS preview */}
          <div>
            <label className="text-xs font-semibold text-slate-700 block mb-1.5">Generated JavaScript</label>
            <pre className="bg-slate-900 text-emerald-300 text-[11px] font-mono p-3 rounded-lg overflow-x-auto">{generatedJs}</pre>
            <p className="text-[10px] text-slate-400 mt-1">For now you can paste this into your site to fire the event manually. Auto-firing from the trigger config is on the roadmap.</p>
          </div>

          {/* Active toggle */}
          <label className="flex items-center gap-2 cursor-pointer">
            <input
              type="checkbox"
              checked={isActive}
              onChange={(e) => setIsActive(e.target.checked)}
              className="w-3.5 h-3.5 rounded border-slate-300 text-brand-600 focus:ring-brand-500"
            />
            <span className="text-xs text-slate-700">Active</span>
          </label>
        </div>

        <div className="px-6 py-4 border-t border-slate-100 flex items-center justify-end gap-2 sticky bottom-0 bg-white">
          <button onClick={onClose} className="px-4 py-2 text-xs font-semibold text-slate-600 hover:bg-slate-50 rounded-lg">
            Cancel
          </button>
          <button
            onClick={handleSave}
            disabled={!canSave}
            className="px-4 py-2 bg-brand-600 text-white text-xs font-semibold rounded-lg hover:bg-brand-700 disabled:opacity-50 disabled:cursor-not-allowed"
          >
            {initial ? "Save Changes" : "Create Event"}
          </button>
        </div>
      </div>
    </>
  );
}
