import { useState, useEffect, useMemo } from 'react';
import { guests as api } from '../api';

interface NodeItem { name: string; type: string; server?: string }
interface NodeGroup { label: string; nodes: NodeItem[] }

export default function Guests() {
  const [links, setLinks] = useState<any[]>([]);
  const [selectedId, setSelectedId] = useState<number | null>(null);
  const [detail, setDetail] = useState<any>(null);
  const [available, setAvailable] = useState<{ static: any[]; subscriptions: any[] }>({ static: [], subscriptions: [] });
  const [selectedNames, setSelectedNames] = useState<Set<string>>(new Set());
  const [editName, setEditName] = useState('');
  const [regexInput, setRegexInput] = useState('');
  const [newName, setNewName] = useState('');
  const [saving, setSaving] = useState(false);
  const [copied, setCopied] = useState('');

  const loadLinks = () => api.list().then(setLinks).catch(console.error);
  useEffect(() => {
    loadLinks();
    api.availableNodes().then(setAvailable).catch(console.error);
  }, []);

  useEffect(() => {
    if (selectedId == null) { setDetail(null); return; }
    api.get(selectedId).then(d => {
      setDetail(d);
      setEditName(d.name);
      setSelectedNames(new Set<string>(d.node_names || []));
    }).catch(console.error);
  }, [selectedId]);

  // Flatten available nodes into render groups
  const groups: NodeGroup[] = useMemo(() => {
    const g: NodeGroup[] = [];
    if (available.static.length > 0) {
      g.push({ label: '自定义节点', nodes: available.static.map((n: any) => ({ name: n.name, type: n.type })) });
    }
    for (const sub of available.subscriptions) {
      if (sub.nodes.length > 0) {
        g.push({ label: sub.name, nodes: sub.nodes.map((n: any) => ({ name: n.name, type: n.type, server: n.server })) });
      }
    }
    return g;
  }, [available]);

  const allNames = useMemo(() => groups.flatMap(g => g.nodes.map(n => n.name)), [groups]);

  const toggleName = (name: string) => {
    setSelectedNames(prev => {
      const next = new Set(prev);
      if (next.has(name)) next.delete(name); else next.add(name);
      return next;
    });
  };

  const selectAll = (enabled: boolean) => {
    setSelectedNames(prev => {
      const next = new Set(prev);
      for (const n of allNames) { if (enabled) next.add(n); else next.delete(n); }
      return next;
    });
  };

  const regexBatch = (enabled: boolean) => {
    if (!regexInput.trim()) return;
    let re: RegExp;
    try { re = new RegExp(regexInput, 'i'); } catch { alert('无效的正则表达式'); return; }
    setSelectedNames(prev => {
      const next = new Set(prev);
      for (const n of allNames) { if (re.test(n)) { if (enabled) next.add(n); else next.delete(n); } }
      return next;
    });
  };

  const regexMatchCount = useMemo(() => {
    if (!regexInput) return null;
    try { const re = new RegExp(regexInput, 'i'); return allNames.filter(n => re.test(n)).length; }
    catch { return -1; }
  }, [regexInput, allNames]);

  const handleCreate = async () => {
    if (!newName.trim()) return;
    const { id } = await api.create(newName.trim());
    setNewName('');
    await loadLinks();
    setSelectedId(id);
  };

  const handleSave = async () => {
    if (selectedId == null) return;
    setSaving(true);
    try {
      await api.update(selectedId, {
        name: editName.trim() || detail.name,
        node_names: [...selectedNames],
      });
      await loadLinks();
      const d = await api.get(selectedId);
      setDetail(d);
    } finally {
      setSaving(false);
    }
  };

  const handleToggleEnabled = async (link: any) => {
    await api.update(link.id, { enabled: link.enabled ? 0 : 1 });
    loadLinks();
  };

  const handleDelete = async (link: any) => {
    if (!confirm(`删除游客链接「${link.name}」？该链接将立即失效。`)) return;
    await api.delete(link.id);
    if (selectedId === link.id) setSelectedId(null);
    loadLinks();
  };

  const copy = (key: string, url: string) => {
    navigator.clipboard.writeText(url);
    setCopied(key);
    setTimeout(() => setCopied(''), 2000);
  };

  const origin = window.location.origin;
  const selectedCount = allNames.filter(n => selectedNames.has(n)).length;

  return (
    <div>
      <h2 style={styles.title}>游客链接</h2>
      <p style={styles.subtitle}>为他人生成独立订阅链接，仅返回勾选的白名单节点。可随时编辑，链接保持不变。</p>

      <div style={{ display: 'flex', gap: 20, alignItems: 'flex-start' }}>
        {/* Left: link list */}
        <div style={{ width: 260, flexShrink: 0 }}>
          <div style={{ display: 'flex', gap: 8, marginBottom: 12 }}>
            <input
              placeholder="新链接名称"
              value={newName}
              onChange={e => setNewName(e.target.value)}
              onKeyDown={e => { if (e.key === 'Enter') handleCreate(); }}
              style={{ flex: 1, fontSize: 12 }}
            />
            <button className="primary small" onClick={handleCreate}>新建</button>
          </div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
            {links.map(link => (
              <div
                key={link.id}
                onClick={() => setSelectedId(link.id)}
                style={{
                  border: '1px solid',
                  borderColor: selectedId === link.id ? 'var(--accent)' : 'var(--border)',
                  background: selectedId === link.id ? 'var(--bg-active)' : 'var(--bg-input)',
                  borderRadius: 'var(--radius)',
                  padding: '10px 12px',
                  cursor: 'pointer',
                  opacity: link.enabled ? 1 : 0.5,
                }}
              >
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                  <span style={{ fontFamily: 'var(--font-mono)', fontSize: 13, color: 'var(--accent)' }}>{link.name}</span>
                  <input
                    type="checkbox"
                    className="toggle"
                    checked={!!link.enabled}
                    onClick={e => e.stopPropagation()}
                    onChange={() => handleToggleEnabled(link)}
                    title="启用/禁用此链接"
                  />
                </div>
                <div style={{ fontSize: 10, color: 'var(--text-muted)', marginTop: 4 }}>
                  {link.node_count} 个节点
                </div>
              </div>
            ))}
            {links.length === 0 && (
              <div style={{ color: 'var(--text-muted)', fontSize: 12, padding: 12, textAlign: 'center' }}>
                暂无游客链接
              </div>
            )}
          </div>
        </div>

        {/* Right: editor */}
        <div style={{ flex: 1, minWidth: 0 }}>
          {!detail ? (
            <div style={{ color: 'var(--text-muted)', fontSize: 13, padding: 40, textAlign: 'center' }}>
              选择左侧链接进行编辑，或新建一个
            </div>
          ) : (
            <>
              {/* Name + delete */}
              <div style={{ display: 'flex', gap: 8, alignItems: 'center', marginBottom: 12 }}>
                <input
                  value={editName}
                  onChange={e => setEditName(e.target.value)}
                  style={{ width: 220, fontSize: 13 }}
                />
                <button className="primary" onClick={handleSave} disabled={saving}>
                  {saving ? '保存中...' : '保存'}
                </button>
                <button className="small danger" onClick={() => handleDelete(detail)}>删除链接</button>
              </div>

              {/* URLs */}
              {(['surge', 'clash', 'ssr'] as const).map(kind => {
                const url = `${origin}/${kind}/${detail.token}`;
                const label = kind === 'surge' ? 'SURGE' : kind === 'clash' ? 'CLASH / STASH' : 'SSR / QX / 小火箭';
                return (
                  <div key={kind} style={styles.urlRow}>
                    <span style={styles.urlLabel}>{label}</span>
                    <code style={styles.urlCode}>{url}</code>
                    <button className="small" onClick={() => copy(kind, url)}>
                      {copied === kind ? '已复制' : '复制'}
                    </button>
                  </div>
                );
              })}

              {/* Batch controls (same as 节点选择) */}
              <div style={{ display: 'flex', flexDirection: 'column', gap: 10, margin: '16px 0' }}>
                <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
                  <button className="small" onClick={() => selectAll(true)}>全选</button>
                  <button className="small" onClick={() => selectAll(false)}>全不选</button>
                  <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--text-secondary)', marginLeft: 8 }}>
                    {selectedCount}/{allNames.length} 已选
                  </span>
                </div>
                <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
                  <input
                    placeholder="正则匹配节点名（如 香港|HK）"
                    value={regexInput}
                    onChange={e => setRegexInput(e.target.value)}
                    style={{ width: 260, fontSize: 12 }}
                  />
                  <button className="small" onClick={() => regexBatch(true)}>匹配启用</button>
                  <button className="small" onClick={() => regexBatch(false)}>匹配禁用</button>
                  {regexInput && (
                    <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--text-muted)' }}>
                      {regexMatchCount === -1 ? '无效正则' : `匹配 ${regexMatchCount} 个`}
                    </span>
                  )}
                </div>
              </div>

              {/* Node list grouped */}
              <table>
                <thead>
                  <tr>
                    <th style={{ width: 50 }}>白名单</th>
                    <th>名称</th>
                    <th style={{ width: 80 }}>协议</th>
                    <th>服务器</th>
                  </tr>
                </thead>
                <tbody>
                  {groups.map(group => (
                    <FragmentGroup
                      key={group.label}
                      group={group}
                      selectedNames={selectedNames}
                      onToggle={toggleName}
                    />
                  ))}
                  {allNames.length === 0 && (
                    <tr>
                      <td colSpan={4} style={{ textAlign: 'center', color: 'var(--text-muted)', padding: 40 }}>
                        暂无可选节点，请先添加静态节点或抓取订阅
                      </td>
                    </tr>
                  )}
                </tbody>
              </table>
            </>
          )}
        </div>
      </div>
    </div>
  );
}

function FragmentGroup({ group, selectedNames, onToggle }: {
  group: NodeGroup;
  selectedNames: Set<string>;
  onToggle: (name: string) => void;
}) {
  return (
    <>
      <tr>
        <td colSpan={4} style={{
          background: 'var(--bg-active)',
          fontFamily: 'var(--font-mono)',
          fontSize: 11,
          color: 'var(--text-muted)',
          textTransform: 'uppercase',
          letterSpacing: '0.05em',
        }}>
          {group.label} · {group.nodes.length}
        </td>
      </tr>
      {group.nodes.map((node, i) => {
        const checked = selectedNames.has(node.name);
        return (
          <tr key={`${group.label}-${i}-${node.name}`} style={{ opacity: checked ? 1 : 0.55 }}>
            <td>
              <input
                type="checkbox"
                className="toggle"
                checked={checked}
                onChange={() => onToggle(node.name)}
              />
            </td>
            <td style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: checked ? 'var(--accent)' : 'var(--text-secondary)' }}>
              {node.name}
            </td>
            <td>
              <span style={{
                fontFamily: 'var(--font-mono)', fontSize: 10, padding: '2px 6px',
                borderRadius: 'var(--radius)', background: 'var(--bg-active)',
                color: 'var(--text-secondary)', textTransform: 'uppercase',
              }}>
                {node.type}
              </span>
            </td>
            <td style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--text-secondary)' }}>
              {node.server || '—'}
            </td>
          </tr>
        );
      })}
    </>
  );
}

const styles = {
  title: {
    fontFamily: 'var(--font-mono)' as const,
    fontSize: 16,
    fontWeight: 600 as const,
    color: 'var(--text-primary)',
    marginBottom: 4,
  },
  subtitle: {
    fontSize: 12,
    color: 'var(--text-secondary)',
    marginBottom: 20,
  },
  urlRow: {
    display: 'flex' as const,
    gap: 8,
    alignItems: 'center' as const,
    marginBottom: 6,
  },
  urlLabel: {
    fontFamily: 'var(--font-mono)' as const,
    fontSize: 10,
    color: 'var(--text-muted)',
    width: 120,
    flexShrink: 0,
  },
  urlCode: {
    flex: 1,
    fontFamily: 'var(--font-mono)' as const,
    fontSize: 12,
    color: 'var(--accent)',
    userSelect: 'all' as const,
    overflow: 'hidden',
    textOverflow: 'ellipsis',
    whiteSpace: 'nowrap' as const,
    background: 'var(--bg-input)',
    border: '1px solid var(--border)',
    borderRadius: 'var(--radius)',
    padding: '6px 10px',
  },
};
