/* ============================================================
   admin-panel.jsx — Tab Admin customizer (Mức 1)
   Tuỳ biến: Font · Màu · Bố cục (kéo-thả bật/tắt & đổi thứ tự mục)
   Lưu localStorage (xem trước) · Xuất config-<bên>.json (deploy cho mọi người)
   Chỉ hiện khi ?admin=1.
   ============================================================ */
(function () {
  const { useState } = React;

  // ---- Phát hiện admin (đồng bộ với image-slot.js) ----
  function isAdmin() {
    try {
      const p = new URLSearchParams(location.search);
      if (p.get('admin') === '1') localStorage.setItem('wedding-admin', '1');
      if (p.get('admin') === '0') localStorage.removeItem('wedding-admin');
      return localStorage.getItem('wedding-admin') === '1';
    } catch { return false; }
  }

  // ---- Danh sách mục có thể bật/tắt + đổi thứ tự ----
  const SECTION_DEFS = [
    { id: 'invite',    label: 'Thiệp mời + Gia đình' },
    { id: 'band1',     label: 'Dải ảnh 1' },
    { id: 'countdown', label: 'Đếm ngược' },
    { id: 'album',     label: 'Album ảnh' },
    { id: 'events',    label: 'Sự kiện' },
    { id: 'map',       label: 'Bản đồ + QR' },
    { id: 'band2',     label: 'Dải ảnh 2' },
    { id: 'wishes',    label: 'Sổ lưu bút' },
    { id: 'closing',   label: 'Lời kết' },
  ];

  // ---- Bảng màu mặc định theo bên ----
  const PALETTE = {
    'nha-trai': { sage: '#8C9A7C', sageDeep: '#5C6A4E', sageSoft: '#BCC4AE', sageMist: '#DCE0D2' },
    'nha-gai':  { sage: '#C9A06B', sageDeep: '#8A6A42', sageSoft: '#EFD8BD', sageMist: '#F4E8D7' },
  };

  // ---- Font: nhãn → font-family ----
  const FONTS = {
    'Cormorant Garamond': '"Cormorant Garamond", "EB Garamond", Georgia, serif',
    'EB Garamond':        '"EB Garamond", Georgia, serif',
    'Georgia':            'Georgia, "Times New Roman", serif',
  };

  // ---- Các trường nội dung sửa được (dot path) ----
  const CONTENT_GROUPS = [
    { group: 'Tên & Ngày', fields: [
      { key: 'nameA', label: 'Tên hiển thị trước', type: 'text' },
      { key: 'nameB', label: 'Tên hiển thị sau', type: 'text' },
      { key: 'monogram', label: 'Monogram (vd V & S)', type: 'text' },
      { key: 'heroLogo', label: 'Logo hero (đường dẫn ảnh, trống = dùng chữ)', type: 'text' },
      { key: 'dateText', label: 'Ngày (ngắn)', type: 'text' },
      { key: 'dateLong', label: 'Ngày (đầy đủ)', type: 'text' },
      { key: 'dateISO', label: 'Ngày giờ ISO (đếm ngược)', type: 'text' },
      { key: 'weekday', label: 'Thứ', type: 'text' },
      { key: 'day', label: 'Ngày (số)', type: 'text' },
      { key: 'month', label: 'Tháng (số)', type: 'text' },
      { key: 'year', label: 'Năm', type: 'text' },
    ]},
    { group: 'Lễ & Tiệc', fields: [
      { key: 'ceremony.label', label: 'Lễ — tên', type: 'text' },
      { key: 'ceremony.time', label: 'Lễ — giờ', type: 'text' },
      { key: 'ceremony.note', label: 'Lễ — ghi chú', type: 'text' },
      { key: 'party.label', label: 'Tiệc — tên', type: 'text' },
      { key: 'party.time', label: 'Tiệc — giờ', type: 'text' },
      { key: 'party.note', label: 'Tiệc — ghi chú', type: 'text' },
    ]},
    { group: 'Địa điểm', fields: [
      { key: 'venueFull', label: 'Tên địa điểm', type: 'text' },
      { key: 'hall', label: 'Sảnh / đường', type: 'text' },
      { key: 'address', label: 'Địa chỉ', type: 'text' },
      { key: 'mapsEmbed', label: 'Link bản đồ nhúng (embed)', type: 'textarea' },
      { key: 'mapsLink', label: 'Link chỉ đường', type: 'textarea' },
    ]},
    { group: 'Gia đình', fields: [
      { key: 'groomParents', label: 'Nhà trai (mỗi dòng 1 người)', type: 'list' },
      { key: 'groomAddress', label: 'Nhà trai — địa chỉ', type: 'text' },
      { key: 'brideParents', label: 'Nhà gái (mỗi dòng 1 người)', type: 'list' },
      { key: 'brideAddress', label: 'Nhà gái — địa chỉ', type: 'text' },
    ]},
    { group: 'Lời chữ', fields: [
      { key: 'announce', label: 'Dòng báo tin (trên tên)', type: 'text' },
      { key: 'invite', label: 'Lời mời', type: 'textarea' },
      { key: 'closing', label: 'Lời kết', type: 'text' },
      { key: 'bandText', label: 'Chữ trên dải ảnh 2', type: 'text' },
    ]},
    { group: 'Album & Ảnh band', fields: [
      { key: 'albumCount', label: 'Số ảnh album', type: 'text' },
      { key: 'band1Focus', label: 'Canh ảnh band 1 (vd 50% 50%)', type: 'text' },
      { key: 'band2Focus', label: 'Canh ảnh band 2', type: 'text' },
    ]},
  ];

  // ---- Tiện ích đọc/ghi theo dot path + deep merge ----
  function getPath(obj, path) {
    return path.split('.').reduce((o, k) => (o == null ? undefined : o[k]), obj);
  }
  function setPath(obj, path, val) {
    const ks = path.split('.'), out = Array.isArray(obj) ? obj.slice() : { ...obj };
    let cur = out;
    for (let i = 0; i < ks.length - 1; i++) {
      cur[ks[i]] = (cur[ks[i]] && typeof cur[ks[i]] === 'object') ? { ...cur[ks[i]] } : {};
      cur = cur[ks[i]];
    }
    cur[ks[ks.length - 1]] = val;
    return out;
  }
  function deepMerge(base, over) {
    const out = { ...base };
    for (const k in (over || {})) {
      const v = over[k];
      if (v && typeof v === 'object' && !Array.isArray(v) && base[k] && typeof base[k] === 'object' && !Array.isArray(base[k])) {
        out[k] = deepMerge(base[k], v);
      } else { out[k] = v; }
    }
    return out;
  }

  function defaultCfg(side) {
    return {
      order: SECTION_DEFS.map((s) => s.id),
      hidden: {},
      theme: { ...(PALETTE[side] || PALETTE['nha-trai']) },
      font: 'Cormorant Garamond',
      text: {}, // ghi đè nội dung WED (chỉ field nào admin sửa)
    };
  }

  function loadCfg(side) {
    const def = defaultCfg(side);
    try {
      const s = JSON.parse(localStorage.getItem('wedding-cfg:' + side) || 'null');
      if (s) return mergeCfg(def, s);
    } catch {}
    return def;
  }
  function mergeCfg(def, s) {
    return {
      order: Array.isArray(s.order) && s.order.length ? s.order : def.order,
      hidden: s.hidden || {},
      theme: { ...def.theme, ...(s.theme || {}) },
      font: s.font || def.font,
      text: s.text || {},
    };
  }
  function saveCfg(side, cfg) {
    try { localStorage.setItem('wedding-cfg:' + side, JSON.stringify(cfg)); } catch {}
  }
  function fontFamily(name) { return FONTS[name] || FONTS['Cormorant Garamond']; }

  // ---- Xuất file config để deploy (mọi khách thấy) ----
  function exportCfg(side, cfg) {
    const blob = new Blob([JSON.stringify(cfg, null, 2)], { type: 'application/json' });
    const a = document.createElement('a');
    a.href = URL.createObjectURL(blob);
    a.download = 'config-' + side + '.json';
    a.click();
    URL.revokeObjectURL(a.href);
  }

  // ---- Panel UI ----
  function AdminPanel({ side, cfg, setCfg }) {
    const [open, setOpen] = useState(false);
    const [tab, setTab] = useState('layout');
    const [dragIdx, setDragIdx] = useState(null);
    const labelOf = (id) => (SECTION_DEFS.find((s) => s.id === id) || {}).label || id;

    const patch = (p) => setCfg((c) => ({ ...c, ...p }));
    const setTheme = (k, v) => setCfg((c) => ({ ...c, theme: { ...c.theme, [k]: v } }));
    const toggleHide = (id) => setCfg((c) => ({ ...c, hidden: { ...c.hidden, [id]: !c.hidden[id] } }));

    // Giá trị hiện tại của 1 field nội dung (config > mặc định)
    const base = window.__WED_BASE || {};
    const fieldVal = (key) => {
      const v = getPath(cfg.text || {}, key);
      return v !== undefined ? v : getPath(base, key);
    };
    const setText = (key, val) => setCfg((c) => ({ ...c, text: setPath(c.text || {}, key, val) }));

    const onDrop = (to) => {
      if (dragIdx === null || dragIdx === to) return;
      setCfg((c) => {
        const order = c.order.slice();
        const [m] = order.splice(dragIdx, 1);
        order.splice(to, 0, m);
        return { ...c, order };
      });
      setDragIdx(null);
    };

    const colorRow = (key, label) => (
      <label className="ap-color">
        <span>{label}</span>
        <input type="color" value={cfg.theme[key] || '#000000'} onChange={(e) => setTheme(key, e.target.value)} />
        <code>{cfg.theme[key]}</code>
      </label>
    );

    return (
      <>
        <button className="ap-fab" onClick={() => setOpen((o) => !o)} aria-label="Tùy biến">
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
            <circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>
          </svg>
        </button>

        {open && (
          <div className="ap-drawer">
            <div className="ap-head">
              <strong>Tùy biến · {side === 'nha-gai' ? 'Nhà Gái' : 'Nhà Trai'}</strong>
              <button className="ap-x" onClick={() => setOpen(false)}>✕</button>
            </div>

            <div className="ap-tabs">
              {[['content', 'Nội dung'], ['layout', 'Bố cục'], ['theme', 'Màu & Font']].map(([k, l]) => (
                <button key={k} className={'ap-tab' + (tab === k ? ' on' : '')} onClick={() => setTab(k)}>{l}</button>
              ))}
            </div>

            <div className="ap-body">
              {tab === 'content' && (
                <>
                  <p className="ap-hint">Sửa nội dung thiệp. Để trống = dùng mặc định.</p>
                  {CONTENT_GROUPS.map((g) => (
                    <div key={g.group} className="ap-group">
                      <p className="ap-group-title">{g.group}</p>
                      {g.fields.map((f) => {
                        const raw = fieldVal(f.key);
                        if (f.type === 'list') {
                          const txt = Array.isArray(raw) ? raw.join('\n') : (raw || '');
                          return (
                            <label className="ap-field" key={f.key}>
                              <span>{f.label}</span>
                              <textarea rows={2} value={txt}
                                onChange={(e) => setText(f.key, e.target.value.split('\n').map((s) => s.trim()).filter(Boolean))} />
                            </label>
                          );
                        }
                        if (f.type === 'textarea') {
                          return (
                            <label className="ap-field" key={f.key}>
                              <span>{f.label}</span>
                              <textarea rows={3} value={raw || ''} onChange={(e) => setText(f.key, e.target.value)} />
                            </label>
                          );
                        }
                        return (
                          <label className="ap-field" key={f.key}>
                            <span>{f.label}</span>
                            <input type="text" value={raw == null ? '' : raw} onChange={(e) => setText(f.key, e.target.value)} />
                          </label>
                        );
                      })}
                    </div>
                  ))}
                </>
              )}

              {tab === 'layout' && (
                <>
                  <p className="ap-hint">Kéo ⋮⋮ để đổi thứ tự · bỏ tick để ẩn mục</p>
                  {cfg.order.map((id, i) => (
                    <div key={id} className="ap-row" draggable
                      onDragStart={() => setDragIdx(i)}
                      onDragOver={(e) => e.preventDefault()}
                      onDrop={() => onDrop(i)}>
                      <span className="ap-grip">⋮⋮</span>
                      <label className="ap-check">
                        <input type="checkbox" checked={!cfg.hidden[id]} onChange={() => toggleHide(id)} />
                        <span>{labelOf(id)}</span>
                      </label>
                    </div>
                  ))}
                </>
              )}

              {tab === 'theme' && (
                <>
                  <label className="ap-field">
                    <span>Font chữ</span>
                    <select value={cfg.font} onChange={(e) => patch({ font: e.target.value })}>
                      {Object.keys(FONTS).map((f) => <option key={f} value={f}>{f}</option>)}
                    </select>
                  </label>
                  {colorRow('sage', 'Màu nhấn chính')}
                  {colorRow('sageDeep', 'Màu nhấn đậm (chữ/nút)')}
                  {colorRow('sageSoft', 'Màu be sáng')}
                  {colorRow('sageMist', 'Màu nền nhạt')}
                  <button className="ap-link" onClick={() => patch({ theme: { ...PALETTE[side] } })}>↺ Khôi phục màu gốc</button>
                </>
              )}
            </div>

            <div className="ap-foot">
              <button className="ap-btn ap-btn--solid" onClick={() => { saveCfg(side, cfg); alert('Đã lưu (xem trước trên máy này).'); }}>Lưu</button>
              <button className="ap-btn" onClick={() => exportCfg(side, cfg)}>Xuất config</button>
              <button className="ap-btn ap-btn--ghost" onClick={() => { if (confirm('Đặt lại toàn bộ về mặc định?')) { localStorage.removeItem('wedding-cfg:' + side); setCfg(defaultCfg(side)); } }}>Đặt lại</button>
            </div>
            <p className="ap-note">“Lưu” = chỉ máy này xem. “Xuất config” → bỏ file vào thư mục web rồi deploy → mọi khách thấy.</p>
          </div>
        )}
      </>
    );
  }

  Object.assign(window, {
    __ADMIN: isAdmin(),
    AdminPanel, SECTION_DEFS, loadCfg, saveCfg, defaultCfg, fontFamily, mergeCfg, deepMerge,
  });
})();
