import React, { useState, useEffect, useRef, useCallback } from 'react';

declare const jalpiEditorConfig: {
  apiUrl: string;
  nonce: string;
};

interface TagDef {
  tag: string;
  label: string;
  example: string;
  hint?: string;
  param?: string;
}

interface TagGroup {
  key: string;
  label: string;
  icon: string;
  tags: TagDef[];
}

interface Props {
  postId: number;
  /** Called with the complete {{tag:param|fallback}} string to insert. */
  onInsert: (tagString: string) => void;
}

const GROUP_ICONS: Record<string, React.ReactElement> = {
  file:     <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>,
  user:     <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>,
  image:    <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5" fill="currentColor" stroke="none"/><polyline points="21 15 16 10 5 21"/></svg>,
  tag:      <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z"/><line x1="7" y1="7" x2="7.01" y2="7"/></svg>,
  globe:    <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>,
  database: <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"/><path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"/></svg>,
  acf:      <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><rect x="2" y="3" width="20" height="14" rx="2"/><path d="M8 21h8M12 17v4"/></svg>,
  mb:       <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M9 21V9"/></svg>,
  pods:     <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/></svg>,
};

export function DynamicTagPicker({ postId, onInsert }: Props) {
  const [isOpen,   setIsOpen]   = useState(false);
  const [groups,   setGroups]   = useState<TagGroup[]>([]);
  const [loading,  setLoading]  = useState(false);
  const [search,   setSearch]   = useState('');
  const [selected, setSelected] = useState<TagDef | null>(null);
  const [fallback, setFallback] = useState('');
  const containerRef = useRef<HTMLDivElement>(null);
  const searchRef    = useRef<HTMLInputElement>(null);

  // Fetch tag list once when the popover first opens
  useEffect(() => {
    if (!isOpen || groups.length > 0) return;
    setLoading(true);
    fetch(
      `${jalpiEditorConfig.apiUrl}/jalpi-page-builder/v1/dynamic-tags?post_id=${postId}`,
      { headers: { 'X-WP-Nonce': jalpiEditorConfig.nonce } }
    )
      .then((r) => r.json())
      .then((data: TagGroup[]) => {
        setGroups(Array.isArray(data) ? data : []);
        setLoading(false);
      })
      .catch(() => setLoading(false));
  }, [isOpen, postId, groups.length]);

  // Close on outside click / Escape
  useEffect(() => {
    if (!isOpen) return;
    const onMouse = (e: MouseEvent) => {
      if (containerRef.current && !containerRef.current.contains(e.target as Node)) {
        close();
      }
    };
    const onKey = (e: KeyboardEvent) => {
      if (e.key === 'Escape') close();
    };
    document.addEventListener('mousedown', onMouse);
    document.addEventListener('keydown',   onKey);
    return () => {
      document.removeEventListener('mousedown', onMouse);
      document.removeEventListener('keydown',   onKey);
    };
  }, [isOpen]);

  // Focus search box when popover opens
  useEffect(() => {
    if (isOpen) requestAnimationFrame(() => searchRef.current?.focus());
  }, [isOpen]);

  const close = () => {
    setIsOpen(false);
    setSelected(null);
    setFallback('');
    setSearch('');
  };

  const buildTagString = useCallback((t: TagDef): string => {
    const base = t.param ? `${t.tag}:${t.param}` : t.tag;
    return fallback ? `{{${base}|${fallback}}}` : `{{${base}}}`;
  }, [fallback]);

  const handleInsert = useCallback(() => {
    if (!selected) return;
    onInsert(buildTagString(selected));
    close();
  }, [selected, buildTagString, onInsert]);

  const filtered = search.trim()
    ? groups
        .map((g) => ({
          ...g,
          tags: g.tags.filter(
            (t) =>
              t.label.toLowerCase().includes(search.toLowerCase()) ||
              t.tag.toLowerCase().includes(search.toLowerCase()) ||
              (t.param || '').toLowerCase().includes(search.toLowerCase())
          ),
        }))
        .filter((g) => g.tags.length > 0)
    : groups;

  return (
    <div className="jalpi-dyntag" ref={containerRef}>
      <button
        type="button"
        className={`jalpi-dyntag__btn${isOpen ? ' is-open' : ''}`}
        title="Insert dynamic tag"
        onClick={() => setIsOpen((v) => !v)}
      >
        <svg width="11" height="11" viewBox="0 0 20 20" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
          <path d="M6 6L2 10l4 4M14 6l4 4-4 4M11 3l-2 14"/>
        </svg>
        Dynamic
      </button>

      {isOpen && (
        <div className="jalpi-dyntag__popover">
          {/* Search */}
          <div className="jalpi-dyntag__search">
            <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>
            </svg>
            <input
              ref={searchRef}
              type="text"
              placeholder="Search tags…"
              value={search}
              onChange={(e) => setSearch(e.target.value)}
            />
          </div>

          {/* Tag list */}
          <div className="jalpi-dyntag__body">
            {loading && (
              <div className="jalpi-dyntag__state">Loading…</div>
            )}
            {!loading && filtered.length === 0 && (
              <div className="jalpi-dyntag__state">No tags found.</div>
            )}
            {filtered.map((group) => (
              <div key={group.key} className="jalpi-dyntag__group">
                <div className="jalpi-dyntag__group-hd">
                  {GROUP_ICONS[group.icon] ?? GROUP_ICONS.file}
                  {group.label}
                </div>
                {group.tags.map((tag) => (
                  <button
                    key={tag.example}
                    type="button"
                    className={`jalpi-dyntag__item${selected?.example === tag.example ? ' is-active' : ''}`}
                    onClick={() =>
                      setSelected((s) => (s?.example === tag.example ? null : tag))
                    }
                  >
                    <span className="jalpi-dyntag__item-lbl">{tag.label}</span>
                    <code className="jalpi-dyntag__item-code">{tag.example}</code>
                  </button>
                ))}
              </div>
            ))}
          </div>

          {/* Confirm panel — shown when a tag is selected */}
          {selected && (
            <div className="jalpi-dyntag__footer">
              <div className="jalpi-dyntag__footer-preview">
                <code>{buildTagString(selected)}</code>
                {selected.hint && <span className="jalpi-dyntag__footer-hint">{selected.hint}</span>}
              </div>
              <input
                type="text"
                className="jalpi-dyntag__fallback"
                placeholder="Fallback value if empty…"
                value={fallback}
                onChange={(e) => setFallback(e.target.value)}
              />
              <button
                type="button"
                className="jalpi-dyntag__insert-btn"
                onClick={handleInsert}
              >
                Insert
              </button>
            </div>
          )}
        </div>
      )}
    </div>
  );
}
