/* ============================================================
   Sozlamalar — Viloyatlar · Dillerlar · Mahsulotlar (admin)
   ============================================================ */
function Settings({ showToast, user, isSuper, perms }) {
  perms = perms || {};
  const [, force] = useState(0);
  const refresh = () => force(n => n + 1);

  const tabs = [
    ...(perms.settings ? [
      { key: 'regions', label: 'Viloyatlar', icon: 'pin', count: DB.activeRegions().length },
      { key: 'dists', label: 'Dillerlar', icon: 'user', count: DB.activeDistributors().length },
      { key: 'products', label: 'Mahsulotlar', icon: 'box', count: DB.PRODUCTS.length },
      { key: 'factory', label: 'Zavod quvvati', icon: 'box', count: DB.FACTORY_CAPACITY.length },
    ] : []),
    ...(isSuper ? [{ key: 'users', label: 'Foydalanuvchilar', icon: 'lock', count: DB.USERS.length }] : []),
    ...(perms.managePerms ? [{ key: 'roles', label: 'Ruxsatlar', icon: 'shield', count: Object.keys(DB.ROLES).length }] : []),
    ...(isSuper ? [{ key: 'backup', label: 'Zaxira', icon: 'clock' }] : []),
    ...(isSuper ? [{ key: 'sellout', label: 'Sell-Out', icon: 'trendUp' }] : []),
    { key: 'telegram', label: 'Telegram', icon: 'send' },
    { key: 'theme', label: "Ko'rinish", icon: 'gear' },
  ];
  const [tab, setTab] = useState(tabs.length ? tabs[0].key : 'regions');

  return (
    <div style={{ padding: '8px 28px 32px', overflowY: 'auto', height: '100%' }}>
      <div style={{ margin: '6px 0 18px' }}>
        <h2 style={{ fontSize: 20, fontWeight: 800, letterSpacing: '-.02em', margin: 0 }}>Sozlamalar</h2>
        <p style={{ fontSize: 12.5, color: 'var(--ink-4)', margin: '5px 0 0' }}>{perms.settings ? "Viloyat, diller va mahsulotlar ma'lumotnomasi" : "Telegram ulanishi va ko'rinish sozlamalari"}</p>
      </div>

      {/* Sub-tabs */}
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: '2px 6px', borderBottom: '1px solid var(--border)', marginBottom: 20 }}>
        {tabs.map(t => (
          <button key={t.key} onClick={() => setTab(t.key)}
            style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '10px 14px', border: 'none', background: 'transparent',
                     fontWeight: 700, fontSize: 13.5, color: tab === t.key ? 'var(--brand-700)' : 'var(--ink-3)',
                     borderBottom: '2px solid ' + (tab === t.key ? 'var(--brand)' : 'transparent'), marginBottom: -1 }}>
            <Icon name={t.icon} size={16} stroke={1.9} /> {t.label}
            <span className="chip" style={{ padding: '1px 7px', fontSize: 11, background: tab === t.key ? 'var(--brand-tint)' : 'var(--bg-2)', color: tab === t.key ? 'var(--brand-700)' : 'var(--ink-3)' }}>{t.count}</span>
          </button>
        ))}
      </div>

      {tab === 'regions' && <RegionsPanel refresh={refresh} showToast={showToast} />}
      {tab === 'dists' && <DistsPanel refresh={refresh} showToast={showToast} />}
      {tab === 'products' && <ProductsPanel refresh={refresh} showToast={showToast} />}
      {tab === 'factory' && <FactoryPanel refresh={refresh} showToast={showToast} />}
      {tab === 'users' && <UsersPanel refresh={refresh} showToast={showToast} currentUser={user} />}
      {tab === 'roles' && <RolesPanel refresh={refresh} showToast={showToast} />}
      {tab === 'backup' && <BackupPanel showToast={showToast} />}
      {tab === 'sellout' && <SelloutPanel showToast={showToast} />}
      {tab === 'telegram' && <TelegramPanel showToast={showToast} isSuper={isSuper} />}
      {tab === 'theme' && <ThemePanel showToast={showToast} canBrand={!!perms.settings} />}
    </div>
  );
}

/* ---------- Logo paneli (faqat settings ruxsati) ---------- */
function LogoPanel({ showToast }) {
  const [logo, setLogo] = useState((DB.BRANDING && DB.BRANDING.logo) || null);
  const [busy, setBusy] = useState(false);
  const fileRef = useRef(null);

  async function pick(e) {
    const file = e.target.files && e.target.files[0];
    e.target.value = '';
    if (!file) return;
    try { setLogo(await fileToDataURL(file, 240, 'image/png')); }
    catch (ex) { showToast(ex.message || 'Logoni yuklab boʻlmadi'); }
  }
  async function save(next) {
    setBusy(true);
    try {
      const { logo: saved } = await API.updateBranding(next);
      DB.BRANDING = { ...(DB.BRANDING || {}), logo: saved };
      setLogo(saved);
      window.dispatchEvent(new Event('branding-changed'));
      showToast(saved ? 'Logo yangilandi' : 'Standart logo tiklandi');
    } catch (ex) { showToast(ex.message || 'Saqlashda xatolik'); }
    finally { setBusy(false); }
  }

  const current = (DB.BRANDING && DB.BRANDING.logo) || null;
  const changed = (logo || null) !== current;
  return (
    <div style={{ marginBottom: 30, paddingBottom: 26, borderBottom: '1px solid var(--border)' }}>
      <div style={{ fontWeight: 700, fontSize: 14.5, marginBottom: 4 }}>Logo</div>
      <div style={{ fontSize: 12, color: 'var(--ink-4)', marginBottom: 12 }}>Platforma logosini almashtiring. Tavsif: PNG (shaffof fon), kichik hajm.</div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 16, flexWrap: 'wrap' }}>
        <div style={{ height: 60, minWidth: 150, padding: '0 16px', borderRadius: 'var(--r)', border: '1px solid var(--border)',
                      background: 'var(--surface)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          {logo ? <img src={logo} alt="Logo" style={{ height: 40, maxWidth: 180, objectFit: 'contain' }} />
                : <div style={{ fontWeight: 800, fontSize: 18, letterSpacing: '.02em' }}>GUM<span style={{ color: 'var(--brand)' }}>STAR</span></div>}
        </div>
        <input ref={fileRef} type="file" accept="image/*" style={{ display: 'none' }} onChange={pick} />
        <button className="btn btn--ghost" onClick={() => fileRef.current && fileRef.current.click()}>
          <Icon name="upload" size={15} /> Logo tanlash
        </button>
        {changed && (
          <button className="btn btn--primary" disabled={busy} onClick={() => save(logo)}>
            <Icon name="check" size={16} stroke={2.4} /> Saqlash
          </button>
        )}
        {current && !changed && (
          <button className="btn btn--ghost" style={{ color: '#C2453A' }} disabled={busy} onClick={() => save(null)}>
            <Icon name="trash" size={15} /> Standartga qaytarish
          </button>
        )}
      </div>
    </div>
  );
}

/* ---------- Ko'rinish (tema: light/dark + accent) ---------- */
function ThemePanel({ showToast, canBrand }) {
  const [, force] = useState(0);
  const t = window.Theme.get();
  const mode = t.mode === 'dark' ? 'dark' : 'light';
  const accent = t.accent || 'graphite';
  const scale = t.scale || 2;

  function pickMode(m) { window.Theme.set({ mode: m }); force(n => n + 1); showToast(m === 'dark' ? 'Dark rejim yoqildi' : 'Light rejim yoqildi'); }
  function pickAccent(a) { window.Theme.set({ accent: a }); force(n => n + 1); }
  function pickScale(s) { window.Theme.set({ scale: s }); force(n => n + 1); showToast('Yozuv o\'lchami: ' + (window.Theme.SCALES.find(x => x.id === s) || {}).note); }

  const modes = [
    { id: 'light', label: 'Light', bg: '#F2F5F4', fg: '#14211F', card: '#FFFFFF' },
    { id: 'dark', label: 'Dark', bg: '#0F1514', fg: '#E7EDEB', card: '#171F1D' },
  ];

  return (
    <div style={{ maxWidth: 560 }}>
      {canBrand && <LogoPanel showToast={showToast} />}
      <div style={{ fontWeight: 700, fontSize: 14.5, marginBottom: 4 }}>Rejim</div>
      <div style={{ fontSize: 12, color: 'var(--ink-4)', marginBottom: 12 }}>Yorug' yoki qorong'i ko'rinishni tanlang.</div>
      <div style={{ display: 'flex', gap: 12, marginBottom: 26 }}>
        {modes.map(m => {
          const on = mode === m.id;
          return (
            <button key={m.id} onClick={() => pickMode(m.id)}
              style={{ flex: 1, textAlign: 'left', padding: 12, borderRadius: 'var(--r)', cursor: 'pointer',
                       background: 'var(--surface)', border: '2px solid ' + (on ? 'var(--brand)' : 'var(--border)') }}>
              <div style={{ height: 56, borderRadius: 8, background: m.bg, border: '1px solid var(--border)', padding: 8, marginBottom: 9, display: 'flex', gap: 6 }}>
                <div style={{ width: 26, background: m.card, borderRadius: 4, border: '1px solid rgba(128,128,128,.25)' }} />
                <div style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: 4, paddingTop: 3 }}>
                  <div style={{ height: 6, width: '70%', borderRadius: 3, background: m.fg, opacity: .85 }} />
                  <div style={{ height: 6, width: '45%', borderRadius: 3, background: m.fg, opacity: .4 }} />
                </div>
              </div>
              <div style={{ display: 'flex', alignItems: 'center', gap: 7, fontWeight: 700, fontSize: 13 }}>
                {on && <Icon name="check" size={15} stroke={2.6} style={{ color: 'var(--brand)' }} />}
                {m.label}
              </div>
            </button>
          );
        })}
      </div>

      <div style={{ fontWeight: 700, fontSize: 14.5, marginBottom: 4 }}>Yozuv o'lchami</div>
      <div style={{ fontSize: 12, color: 'var(--ink-4)', marginBottom: 12 }}>Platforma yozuvlarini katta yoki kichik qiling — tanlagan zahoti qo'llanadi.</div>
      <div style={{ display: 'flex', gap: 12, marginBottom: 26 }}>
        {window.Theme.SCALES.map(s => {
          const on = scale === s.id;
          return (
            <button key={s.id} onClick={() => pickScale(s.id)}
              style={{ flex: 1, textAlign: 'center', padding: '14px 10px', borderRadius: 'var(--r)', cursor: 'pointer',
                       background: on ? 'var(--brand-tint)' : 'var(--surface)', border: '2px solid ' + (on ? 'var(--brand)' : 'var(--border)'),
                       transition: 'all .15s var(--ease)' }}>
              <div style={{ fontWeight: 800, color: on ? 'var(--brand-700)' : 'var(--ink-2)', lineHeight: 1,
                            fontSize: s.id === 1 ? 16 : s.id === 2 ? 22 : 30 }}>Aa</div>
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 5, marginTop: 9, fontWeight: 700, fontSize: 12.5 }}>
                {on && <Icon name="check" size={14} stroke={2.6} style={{ color: 'var(--brand)' }} />}
                {s.note}
              </div>
              <div style={{ fontSize: 11, color: 'var(--ink-4)', marginTop: 2 }}>{s.name}</div>
            </button>
          );
        })}
      </div>

      <div style={{ fontWeight: 700, fontSize: 14.5, marginBottom: 4 }}>Asosiy rang</div>
      <div style={{ fontSize: 12, color: 'var(--ink-4)', marginBottom: 12 }}>Tugmalar, havolalar va urg'u rangi.</div>
      <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
        {window.Theme.ACCENTS.map(a => {
          const on = accent === a.id;
          return (
            <button key={a.id} onClick={() => pickAccent(a.id)} title={a.name}
              style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6, padding: 6, border: 'none', background: 'transparent', cursor: 'pointer' }}>
              <span style={{ width: 40, height: 40, borderRadius: '50%', background: a.brand, display: 'grid', placeItems: 'center',
                             boxShadow: on ? '0 0 0 3px var(--surface), 0 0 0 5px ' + a.brand : 'var(--sh-1)' }}>
                {on && <Icon name="check" size={18} stroke={3} style={{ color: '#fff' }} />}
              </span>
              <span style={{ fontSize: 11, fontWeight: 700, color: on ? 'var(--ink)' : 'var(--ink-4)' }}>{a.name}</span>
            </button>
          );
        })}
      </div>
    </div>
  );
}

/* ---------- Ruxsatlar (rol × funksiya matritsasi) — managePerms ---------- */
const PERM_GROUPS = [
  { label: 'Zakazlar', perms: [
    ['addOrder', 'Zakaz qoʼshish'],
    ['editOrder', 'Zakazni tahrirlash'],
    ['plan', 'Rejaga olish'],
    ['moveAny', 'Istalgan ustunga koʻchirish'],
    ['moveBeyondPlanned', 'Rejadan oldinga oʻtkazish'],
    ['reorderQueue', 'Navbatni qayta tartiblash'],
  ] },
  { label: 'Hududlar', perms: [
    ['regionScoped', 'Viloyatga bogʼlash (faqat oʼz hududi)'],
  ] },
  { label: 'Brendlar', perms: [
    ['brandScoped', 'Brendga bogʼlash (faqat oʼz brendi)'],
  ] },
  { label: 'Vazifalar', perms: [
    ['taskView', 'Vazifalarni koʼrish'],
    ['taskAdd', 'Vazifa qoʼshish'],
    ['taskEdit', 'Vazifani tahrirlash'],
    ['taskDelete', 'Vazifani oʼchirish'],
    ['taskManageBoard', 'Doskani boshqarish (ustunlar)'],
  ] },
  { label: 'Tizim', perms: [
    ['settings', 'Sozlamalar (maʼlumotnoma)'],
    ['viewLog', 'Tarixni koʼrish'],
    ['managePerms', 'Ruxsatlarni boshqarish'],
  ] },
  { label: "Ko'rinish (bo'limlar)", perms: [
    ['viewDashboard', "Dashboard bo'limi"],
    ['viewBoard', "Zakazlar bo'limi"],
    ['viewSalesdoc', "Distributsiya bo'limi (SalesDoc)"],
    ['viewChecklist', "Cheklist bo'limi"],
    ['viewFactory', "Zavod quvvati bo'limi"],
    ['viewAi', "AI Insights bo'limi"],
    ['viewPlanfakt', "SELL IN (plan-fakt) bo'limi"],
    ['viewRegion', "SELL OUT (viloyat) bo'limi"],
    ['viewStorecheck', "Storecheck bo'limi"],
    ['viewMaosh', "Maosh bo'limi"],
    ['viewRecruiting', "Ishga olish bo'limi"],
    ['viewHr', "Davomat bo'limi"],
  ] },
  { label: 'Cheklist', perms: [
    ['checklistViewAll', "Barcha cheklistlarni ko'rish (super rollarda standart yoniq)"],
  ] },
];
// boshliq uchun bu ruxsatlar har doim yoniq (lockout oldini olish)
const LOCKED_ON = { boshliq: ['managePerms', 'settings'] };
// Tizim (standart) rollari — o'chirib bo'lmaydi
const DEFAULT_ROLE_KEYS = ['boshliq', 'general', 'regional', 'operator'];

function RolesPanel({ refresh, showToast }) {
  // Mahalliy tahrir holati: { roleKey: { permKey: bool } }
  const roleKeys = Object.keys(DB.ROLES);
  const [draft, setDraft] = useState(() => {
    const d = {};
    roleKeys.forEach(k => { d[k] = { ...(DB.ROLES[k].perms || {}) }; });
    return d;
  });
  const [saving, setSaving] = useState(null);
  const [addOpen, setAddOpen] = useState(false);
  const [removing, setRemoving] = useState(null);

  function onCreated(role) {
    DB.ROLES[role.key] = role;
    setDraft(prev => ({ ...prev, [role.key]: { ...(role.perms || {}) } }));
    setAddOpen(false);
    showToast(role.label + ' roli qoʼshildi');
    refresh();
  }
  async function removeRole(key) {
    setRemoving(key);
    try {
      await API.deleteRole(key);
      delete DB.ROLES[key];
      setDraft(prev => { const c = { ...prev }; delete c[key]; return c; });
      showToast('Rol oʼchirildi');
      refresh();
    } catch (ex) {
      showToast(ex.message || 'Oʼchirishda xatolik');
    }
    setRemoving(null);
  }

  function isLocked(roleKey, permKey) {
    return (LOCKED_ON[roleKey] || []).includes(permKey);
  }
  function toggle(roleKey, permKey) {
    if (DB.ROLES[roleKey].super && isLocked(roleKey, permKey)) return;
    setDraft(prev => ({ ...prev, [roleKey]: { ...prev[roleKey], [permKey]: !prev[roleKey][permKey] } }));
  }
  function dirty(roleKey) {
    const cur = DB.ROLES[roleKey].perms || {};
    const d = draft[roleKey] || {};
    return Object.keys(d).some(p => !!d[p] !== !!cur[p]);
  }
  async function save(roleKey) {
    setSaving(roleKey);
    try {
      const perms = { ...draft[roleKey] };
      (LOCKED_ON[roleKey] || []).forEach(p => { if (DB.ROLES[roleKey].super) perms[p] = true; });
      const { role } = await API.updateRole(roleKey, { perms });
      DB.ROLES[roleKey] = role;
      setDraft(prev => ({ ...prev, [roleKey]: { ...(role.perms || {}) } }));
      showToast(role.label + ' ruxsatlari yangilandi');
      refresh();
    } catch (ex) {
      showToast(ex.message || 'Saqlashda xatolik');
    }
    setSaving(null);
  }

  const colW = 120;
  return (
    <>
      <div style={{ marginBottom: 14, display: 'flex', alignItems: 'flex-start', gap: 12 }}>
        <div style={{ flex: 1 }}>
          <span style={{ fontWeight: 700, fontSize: 14.5 }}>Rollar va ruxsatlar</span>
          <p style={{ fontSize: 12, color: 'var(--ink-4)', margin: '4px 0 0' }}>Har bir rol uchun qaysi funksiyalarga ruxsat borligini belgilang. Oʼzgartirgach <b>Saqlash</b> tugmasini bosing.</p>
        </div>
        <button className="btn btn--primary btn--sm" onClick={() => setAddOpen(true)} style={{ flex: 'none', whiteSpace: 'nowrap' }}>
          <Icon name="plus" size={15} stroke={2.4} /> Yangi rol
        </button>
      </div>
      <Card>
        <div style={{ overflowX: 'auto' }}>
          <table style={{ borderCollapse: 'collapse', width: '100%', minWidth: 520 }}>
            <thead>
              <tr>
                <th style={{ textAlign: 'left', padding: '13px 16px', fontSize: 12.5, fontWeight: 700, color: 'var(--ink-3)', borderBottom: '1px solid var(--border)', position: 'sticky', left: 0, background: 'var(--surface)' }}>Funksiya</th>
                {roleKeys.map(k => (
                  <th key={k} style={{ padding: '13px 10px', minWidth: colW, borderBottom: '1px solid var(--border)', borderLeft: '1px solid var(--border)' }}>
                    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4 }}>
                      <div style={{ display: 'flex', alignItems: 'center', gap: 5 }}>
                        <span style={{ fontSize: 12.5, fontWeight: 800, color: DB.ROLES[k].super ? 'var(--brand-700)' : 'var(--ink)' }}>{DB.ROLES[k].label}</span>
                        {!DEFAULT_ROLE_KEYS.includes(k) && (
                          <button onClick={() => removeRole(k)} disabled={removing === k} title="Rolni oʼchirish" aria-label="Rolni oʼchirish"
                            style={{ border: 'none', background: 'transparent', color: '#C2453A', cursor: 'pointer', padding: 2, display: 'grid', placeItems: 'center', opacity: removing === k ? .4 : 1 }}>
                            <Icon name="trash" size={13} />
                          </button>
                        )}
                      </div>
                      <button className="btn btn--primary btn--sm" disabled={!dirty(k) || saving === k} onClick={() => save(k)}
                        style={{ padding: '4px 10px', fontSize: 11.5, opacity: dirty(k) ? 1 : .45 }}>
                        {saving === k ? '...' : 'Saqlash'}
                      </button>
                    </div>
                  </th>
                ))}
              </tr>
            </thead>
            <tbody>
              {PERM_GROUPS.map(group => (
                <React.Fragment key={group.label}>
                  <tr>
                    <td colSpan={roleKeys.length + 1} style={{ padding: '9px 16px', fontSize: 11, fontWeight: 800, letterSpacing: '.06em', textTransform: 'uppercase', color: 'var(--ink-4)', background: 'var(--bg-2)', borderBottom: '1px solid var(--border)' }}>{group.label}</td>
                  </tr>
                  {group.perms.map(([pk, plabel]) => (
                    <tr key={pk}>
                      <td style={{ padding: '11px 16px', fontSize: 13, fontWeight: 600, color: 'var(--ink-2)', borderBottom: '1px solid var(--border)', position: 'sticky', left: 0, background: 'var(--surface)' }}>{plabel}</td>
                      {roleKeys.map(rk => {
                        const locked = DB.ROLES[rk].super && isLocked(rk, pk);
                        const on = !!(draft[rk] && draft[rk][pk]);
                        return (
                          <td key={rk} style={{ textAlign: 'center', padding: '11px 10px', borderBottom: '1px solid var(--border)', borderLeft: '1px solid var(--border)' }}>
                            <button onClick={() => toggle(rk, pk)} disabled={locked} title={locked ? 'Bu rol uchun majburiy' : ''}
                              aria-pressed={on}
                              style={{ width: 30, height: 30, borderRadius: 8, border: '1px solid ' + (on ? 'var(--brand)' : 'var(--border)'),
                                       background: on ? 'var(--brand)' : 'var(--surface)', color: on ? '#fff' : 'transparent',
                                       cursor: locked ? 'not-allowed' : 'pointer', opacity: locked ? .6 : 1, display: 'grid', placeItems: 'center',
                                       transition: 'all .12s var(--ease)' }}>
                              <Icon name="check" size={16} stroke={3} />
                            </button>
                          </td>
                        );
                      })}
                    </tr>
                  ))}
                </React.Fragment>
              ))}
            </tbody>
          </table>
        </div>
      </Card>
      <div style={{ fontSize: 11.5, color: 'var(--ink-4)', marginTop: 12, display: 'flex', alignItems: 'center', gap: 6 }}>
        <Icon name="info" size={13} /> Super admin (boshliq) uchun <b>Ruxsatlarni boshqarish</b> va <b>Sozlamalar</b> har doim yoniq qoladi. Tizim rollarini oʼchirib boʼlmaydi.
      </div>
      {addOpen && <AddRoleModal onClose={() => setAddOpen(false)} onCreated={onCreated} showToast={showToast} />}
    </>
  );
}

/* ---------- Yangi rol qo'shish modali ---------- */
function AddRoleModal({ onClose, onCreated, showToast }) {
  const [label, setLabel] = useState('');
  const [short, setShort] = useState('');
  const [busy, setBusy] = useState(false);
  const invalid = !label.trim();

  async function submit() {
    if (invalid || busy) return;
    setBusy(true);
    try {
      const { role } = await API.createRole({ label: label.trim(), short: short.trim() || undefined });
      onCreated(role);
    } catch (ex) {
      showToast(ex.message || 'Qoʼshishda xatolik');
      setBusy(false);
    }
  }

  return (
    <Modal onClose={onClose} width={420}>
      <ModalHeader title="Yangi rol" subtitle="Rol qoʼshilgach ruxsatlarini matritsadan belgilang" onClose={onClose} />
      <div style={{ padding: '20px 22px', display: 'grid', gap: 14 }}>
        <div>
          <label className="field-label">Rol nomi<span style={{ color: '#C2453A', fontWeight: 700 }}> *</span></label>
          <input className="input" value={label} autoFocus placeholder="masalan: Logist"
            onChange={e => setLabel(e.target.value)} onKeyDown={e => { if (e.key === 'Enter') submit(); }} />
        </div>
        <div>
          <label className="field-label">Qisqa nom (ixtiyoriy)</label>
          <input className="input" value={short} placeholder="masalan: Logist"
            onChange={e => setShort(e.target.value)} onKeyDown={e => { if (e.key === 'Enter') submit(); }} />
        </div>
        <div style={{ fontSize: 11.5, color: 'var(--ink-4)', display: 'flex', alignItems: 'center', gap: 6 }}>
          <Icon name="info" size={13} /> Yangi rol dastlab faqat <b>Vazifalarni koʼrish</b> ruxsatiga ega boʼladi.
        </div>
      </div>
      <div style={{ padding: '14px 22px', borderTop: '1px solid var(--border)', display: 'flex', gap: 10, justifyContent: 'flex-end' }}>
        <button className="btn btn--ghost" onClick={onClose}>Bekor qilish</button>
        <button className="btn btn--primary" disabled={invalid || busy} onClick={submit}>
          <Icon name="check" size={16} stroke={2.4} /> {busy ? '...' : 'Qoʼshish'}
        </button>
      </div>
    </Modal>
  );
}

/* ---------- Zaxira (backup) — faqat super admin ---------- */
function BackupPanel({ showToast }) {
  const [status, setStatus] = useState(null);
  const [loading, setLoading] = useState(true);
  const [running, setRunning] = useState(false);

  async function load() {
    try { setStatus(await API.backupStatus()); }
    catch (ex) { showToast(ex.message || 'Holatni olib boʼlmadi'); }
    setLoading(false);
  }
  useEffect(() => { load(); }, []);

  async function runNow() {
    setRunning(true);
    try {
      const { result } = await API.runBackup();
      if (result && result.ok) showToast('Zaxira bajarildi: ' + result.rows + ' qator');
      else showToast('Zaxira xatosi: ' + ((result && result.error) || 'nomaʼlum'));
      await load();
    } catch (ex) { showToast(ex.message || 'Zaxirada xatolik'); }
    setRunning(false);
  }

  const last = status && status.last;
  const enabled = !!(status && status.enabled);

  return (
    <>
      <div style={{ marginBottom: 14 }}>
        <span style={{ fontWeight: 700, fontSize: 14.5 }}>Maʼlumotlar zaxirasi (backup)</span>
        <p style={{ fontSize: 12, color: 'var(--ink-4)', margin: '4px 0 0' }}>
          Platformadagi barcha maʼlumot har kuni avtomatik ravishda alohida maxfiy Google Sheet'ga nusxalanadi. Bu — riskni kamaytirish uchun.
        </p>
      </div>

      {loading ? (
        <Card><Row last><span style={{ color: 'var(--ink-4)', fontSize: 13 }}>Yuklanmoqda…</span></Row></Card>
      ) : (
        <Card>
          <Row>
            <span style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13.5, fontWeight: 600 }}>
              <span style={{ width: 9, height: 9, borderRadius: '50%', background: enabled ? 'var(--st-delivered)' : 'var(--st-loading)' }} />
              Holat
            </span>
            <div style={{ flex: 1 }} />
            <span style={{ fontSize: 13, fontWeight: 700, color: enabled ? 'var(--st-delivered)' : 'var(--ink-4)' }}>
              {enabled ? 'Yoqilgan' : 'Sozlanmagan'}
            </span>
          </Row>
          <Row>
            <span style={{ fontSize: 13.5, color: 'var(--ink-2)' }}>Avtomatik vaqt</span>
            <div style={{ flex: 1 }} />
            <span style={{ fontSize: 13, color: 'var(--ink-3)' }}>
              Har kuni soat {String(status.hour).padStart(2, '0')}:00 (UTC+{status.tzOffset})
            </span>
          </Row>
          <Row last={!last}>
            <span style={{ fontSize: 13.5, color: 'var(--ink-2)' }}>Oxirgi zaxira</span>
            <div style={{ flex: 1 }} />
            <span style={{ fontSize: 13, color: 'var(--ink-3)' }}>
              {last ? DB.fmtDeadline(last.at) : 'hali bajarilmagan'}
            </span>
          </Row>
          {last && (
            <Row last>
              <span style={{ fontSize: 13.5, color: 'var(--ink-2)' }}>Natija</span>
              <div style={{ flex: 1 }} />
              <span style={{ fontSize: 13, fontWeight: 700, color: last.ok ? 'var(--st-delivered)' : '#C2453A' }}>
                {last.ok ? `✓ ${last.rows} qator · ${last.tables} tab${last.month ? ' · ' + last.month : ''}` : '✕ ' + (last.error || 'xato')}
              </span>
            </Row>
          )}
        </Card>
      )}

      <div style={{ marginTop: 14, display: 'flex', gap: 10, alignItems: 'center' }}>
        <button className="btn btn--primary" disabled={running || !enabled} onClick={runNow}>
          <Icon name="clock" size={16} stroke={2.2} /> {running ? 'Bajarilmoqda…' : 'Hozir zaxira qilish'}
        </button>
        {!enabled && (
          <span style={{ fontSize: 11.5, color: 'var(--st-loading)' }}>
            Avval serverda <b>BACKUP_WEBAPP_URL</b> va <b>BACKUP_TOKEN</b> sozlang.
          </span>
        )}
      </div>
    </>
  );
}

/* ---------- Telegram bot paneli (har user ulanadi; admin sozlaydi) ---------- */
function TgToggle({ on, onChange, disabled }) {
  return (
    <button onClick={() => !disabled && onChange(!on)} role="switch" aria-checked={on} disabled={disabled}
      style={{ width: 42, height: 24, borderRadius: 999, border: 'none', cursor: disabled ? 'default' : 'pointer', padding: 2, flex: 'none',
        background: on ? 'var(--brand)' : 'var(--bg-3, #D6CEC5)', opacity: disabled ? .6 : 1, transition: 'background .2s', display: 'flex', alignItems: 'center' }}>
      <span style={{ width: 20, height: 20, borderRadius: '50%', background: '#fff', boxShadow: '0 1px 2px rgba(0,0,0,.25)', transition: 'transform .2s', transform: on ? 'translateX(18px)' : 'translateX(0)' }} />
    </button>
  );
}

function TelegramPanel({ showToast, isSuper }) {
  const [me, setMe] = useState(null);
  const [admin, setAdmin] = useState(null);
  const [loading, setLoading] = useState(true);
  const [busy, setBusy] = useState('');

  async function load() {
    setLoading(true);
    try {
      setMe(await API.telegramMe());
      if (isSuper) { try { setAdmin(await API.telegramStatus()); } catch (_) { /* admin holatsiz */ } }
    } catch (ex) { showToast(ex.message || "Telegram holatini olib bo'lmadi"); }
    setLoading(false);
  }
  useEffect(() => { load(); }, []);

  async function unlink() {
    if (!confirm('Telegram akkauntini uzasizmi?')) return;
    setBusy('unlink');
    try { await API.telegramUnlink(); showToast('Telegram uzildi'); await load(); }
    catch (ex) { showToast(ex.message); }
    setBusy('');
  }
  async function setCfg(patch) {
    setBusy('cfg');
    try { const { config } = await API.telegramUpdateConfig(patch); setAdmin(a => ({ ...a, config })); }
    catch (ex) { showToast(ex.message); }
    setBusy('');
  }
  async function setupWebhook() {
    setBusy('hook');
    try { await API.telegramSetupWebhook(); showToast("Webhook o'rnatildi"); await load(); }
    catch (ex) { showToast(ex.message || 'Webhook xatosi'); }
    setBusy('');
  }
  async function test() {
    setBusy('test');
    try { await API.telegramTest(); showToast('Sinov hisoboti yuborildi — Telegramni tekshiring'); }
    catch (ex) { showToast(ex.message || 'Sinov xatosi'); }
    setBusy('');
  }
  async function runDaily() {
    if (!confirm('Kunlik hisobotni hozir barcha ulangan foydalanuvchilarga yuborilsinmi?')) return;
    setBusy('daily');
    try { const r = await API.telegramRunDaily(); showToast('Yuborildi: ' + (r.sent || 0) + ' ta'); await load(); }
    catch (ex) { showToast(ex.message); }
    setBusy('');
  }
  async function runGroup() {
    setBusy('group');
    try { await API.telegramRunGroup(); showToast('Guruhga yuborildi'); await load(); }
    catch (ex) { showToast(ex.message || "Guruhga yuborib bo'lmadi"); }
    setBusy('');
  }
  async function runAttendance() {
    setBusy('att');
    try { const r = await API.telegramRunAttendance(); showToast('Davomat hisoboti yuborildi: ' + (r.sent || 0) + ' ta'); }
    catch (ex) { showToast(ex.message || "Davomat hisobotini yuborib bo'lmadi"); }
    setBusy('');
  }

  if (loading) return <Card><Row last><span style={{ color: 'var(--ink-4)', fontSize: 13 }}>Yuklanmoqda…</span></Row></Card>;

  const connected = !!(me && me.connected);
  const cfg = (admin && admin.config) || null;
  const sec = (cfg && cfg.sections) || {};
  const sections = [
    { k: 'sales', t: 'Sotuv / reja-fakt', d: "Reja, fakt, prognoz (regional menejerga — o'z viloyatlari)" },
    { k: 'tasks', t: 'Vazifalar', d: 'Ochiq, kechikkan va bugun muddati keladigan vazifalar' },
    { k: 'orders', t: 'Zakazlar', d: "Statuslar bo'yicha zakazlar soni" },
    { k: 'storecheck', t: 'Storecheck', d: "So'nggi 7 kun do'kon tekshiruvlari soni" },
  ];

  return (
    <>
      {/* 1) Mening ulanishim — har bir foydalanuvchi uchun */}
      <div style={{ marginBottom: 14 }}>
        <span style={{ fontWeight: 700, fontSize: 14.5 }}>Mening Telegram ulanishim</span>
        <p style={{ fontSize: 12, color: 'var(--ink-4)', margin: '4px 0 0' }}>
          Vazifa biriktirilganda va har kuni hisobot shaxsiy Telegramingizga keladi.
        </p>
      </div>

      {!me || !me.botConfigured ? (
        <Card><Row last><span style={{ fontSize: 12.5, color: 'var(--st-loading)' }}>
          Bot hali sozlanmagan — administrator serverda <b>TELEGRAM_BOT_TOKEN</b> ni kiritishi kerak.
        </span></Row></Card>
      ) : (
        <Card>
          <Row last={!(connected) && !(me.link || me.code)}>
            <span style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13.5, fontWeight: 600 }}>
              <span style={{ width: 9, height: 9, borderRadius: '50%', background: connected ? 'var(--st-delivered)' : 'var(--st-loading)' }} />
              Holat
            </span>
            <div style={{ flex: 1 }} />
            <span style={{ fontSize: 13, fontWeight: 700, color: connected ? 'var(--st-delivered)' : 'var(--ink-4)' }}>
              {connected ? ('Ulangan' + (me.telegramUsername ? ' · ' + me.telegramUsername : '')) : 'Ulanmagan'}
            </span>
          </Row>
          {!connected && me.link && (
            <Row last>
              <span style={{ fontSize: 13.5, color: 'var(--ink-2)' }}>Ulash</span>
              <div style={{ flex: 1 }} />
              <a href={me.link} target="_blank" rel="noopener noreferrer" className="btn btn--primary" style={{ textDecoration: 'none' }}>
                <Icon name="send" size={15} stroke={2.2} /> Telegramda ochish
              </a>
            </Row>
          )}
          {!connected && !me.link && me.code && (
            <Row last><span style={{ fontSize: 12.5, color: 'var(--ink-3)' }}>Botni oching va yuboring: <b>/start {me.code}</b></span></Row>
          )}
          {connected && (
            <Row last>
              <span style={{ fontSize: 13.5, color: 'var(--ink-2)' }}>Boshqaruv</span>
              <div style={{ flex: 1 }} />
              <button className="btn" disabled={busy === 'unlink'} onClick={unlink}>Uzish</button>
            </Row>
          )}
        </Card>
      )}

      {/* 2) Administrator sozlamasi */}
      {isSuper && (
        <div style={{ marginTop: 26 }}>
          <div style={{ marginBottom: 14 }}>
            <span style={{ fontWeight: 700, fontSize: 14.5 }}>Bot boshqaruvi (administrator)</span>
            <p style={{ fontSize: 12, color: 'var(--ink-4)', margin: '4px 0 0' }}>
              Kunlik hisobotda qaysi ma'lumotlar bo'lishini va yuborilish vaqtini sozlang.
            </p>
          </div>

          {!admin || !admin.configured ? (
            <Card><Row last><span style={{ fontSize: 12.5, color: 'var(--st-loading)' }}>
              Bot sozlanmagan — serverda <b>TELEGRAM_BOT_TOKEN</b> va <b>TELEGRAM_BOT_USERNAME</b> ni kiriting.
            </span></Row></Card>
          ) : (
            <>
              <Card>
                <Row><span style={{ fontSize: 13.5, color: 'var(--ink-2)' }}>Bot</span><div style={{ flex: 1 }} /><span style={{ fontSize: 13, color: 'var(--ink-3)' }}>@{admin.botUsername || '—'}</span></Row>
                <Row><span style={{ fontSize: 13.5, color: 'var(--ink-2)' }}>Ulangan foydalanuvchilar</span><div style={{ flex: 1 }} /><span style={{ fontSize: 13, fontWeight: 700 }}>{admin.linkedUsers || 0}</span></Row>
                <Row last={!admin.lastDaily}><span style={{ fontSize: 13.5, color: 'var(--ink-2)' }}>Webhook</span><div style={{ flex: 1 }} /><span style={{ fontSize: 12.5, color: admin.webhook ? 'var(--st-delivered)' : 'var(--ink-4)' }}>{admin.webhook ? "o'rnatilgan" : "o'rnatilmagan"}</span></Row>
                {admin.lastDaily && (
                  <Row last><span style={{ fontSize: 13.5, color: 'var(--ink-2)' }}>Oxirgi hisobot</span><div style={{ flex: 1 }} /><span style={{ fontSize: 12.5, color: 'var(--ink-3)' }}>{DB.fmtDeadline(admin.lastDaily.at)} · {admin.lastDaily.sent} yuborildi</span></Row>
                )}
              </Card>

              <div style={{ marginTop: 16, marginBottom: 6, fontWeight: 700, fontSize: 13 }}>Hisobot bo'limlari</div>
              <Card>
                {sections.map((s, i) => (
                  <Row key={s.k} last={i === sections.length - 1}>
                    <div style={{ minWidth: 0 }}>
                      <div style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--ink-2)' }}>{s.t}</div>
                      <div style={{ fontSize: 11.5, color: 'var(--ink-4)' }}>{s.d}</div>
                    </div>
                    <div style={{ flex: 1 }} />
                    <TgToggle on={!!sec[s.k]} disabled={busy === 'cfg'} onChange={(v) => setCfg({ sections: { [s.k]: v } })} />
                  </Row>
                ))}
              </Card>

              <Card>
                <Row>
                  <span style={{ fontSize: 13.5, color: 'var(--ink-2)' }}>Kunlik hisobot vaqti</span>
                  <div style={{ flex: 1 }} />
                  <select className="select" value={cfg.dailyHour} disabled={busy === 'cfg'} onChange={e => setCfg({ dailyHour: parseInt(e.target.value, 10) })} style={{ width: 100 }}>
                    {Array.from({ length: 24 }).map((_, h) => <option key={h} value={h}>{String(h).padStart(2, '0')}:00</option>)}
                  </select>
                </Row>
                <Row>
                  <div style={{ minWidth: 0 }}>
                    <div style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--ink-2)' }}>Vazifa biriktirilganda xabar</div>
                    <div style={{ fontSize: 11.5, color: 'var(--ink-4)' }}>Yangi vazifa biriktirilganda darrov Telegram xabari</div>
                  </div>
                  <div style={{ flex: 1 }} />
                  <TgToggle on={cfg.taskAssignNotify !== false} disabled={busy === 'cfg'} onChange={(v) => setCfg({ taskAssignNotify: v })} />
                </Row>
                <Row>
                  <div style={{ minWidth: 0 }}>
                    <div style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--ink-2)' }}>Zakaz statusi o'zgarganda xabar</div>
                    <div style={{ fontSize: 11.5, color: 'var(--ink-4)' }}>Status o'zgarsa, zakazni yaratgan menejerga to'liq ma'lumot</div>
                  </div>
                  <div style={{ flex: 1 }} />
                  <TgToggle on={cfg.orderStatusNotify !== false} disabled={busy === 'cfg'} onChange={(v) => setCfg({ orderStatusNotify: v })} />
                </Row>
                <Row>
                  <div style={{ minWidth: 0 }}>
                    <div style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--ink-2)' }}>Yangi zakaz (Rejalanmagan) xabari</div>
                    <div style={{ fontSize: 11.5, color: 'var(--ink-4)' }}>Rejalanmagan ustuniga zakaz qo'shilsa — Operator, General menejer va Super adminga</div>
                  </div>
                  <div style={{ flex: 1 }} />
                  <TgToggle on={cfg.newOrderNotify !== false} disabled={busy === 'cfg'} onChange={(v) => setCfg({ newOrderNotify: v })} />
                </Row>
                <Row>
                  <div style={{ minWidth: 0 }}>
                    <div style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--ink-2)' }}>Kunlik davomat hisoboti</div>
                    <div style={{ fontSize: 11.5, color: 'var(--ink-4)' }}>Har kuni super adminlarga: kim keldi / kech qoldi / kelmadi</div>
                  </div>
                  <div style={{ flex: 1 }} />
                  <TgToggle on={cfg.attendanceReportEnabled !== false} disabled={busy === 'cfg'} onChange={(v) => setCfg({ attendanceReportEnabled: v })} />
                </Row>
                <Row last>
                  <span style={{ fontSize: 13.5, color: 'var(--ink-2)' }}>Davomat hisoboti vaqti</span>
                  <div style={{ flex: 1 }} />
                  <select className="select" value={cfg.attendanceReportHour != null ? cfg.attendanceReportHour : 19} disabled={busy === 'cfg'} onChange={e => setCfg({ attendanceReportHour: parseInt(e.target.value, 10) })} style={{ width: 100 }}>
                    {Array.from({ length: 24 }).map((_, h) => <option key={h} value={h}>{String(h).padStart(2, '0')}:00</option>)}
                  </select>
                </Row>
              </Card>

              <div style={{ marginTop: 16 }}>
                <div style={{ fontSize: 12.5, color: 'var(--ink-3)', marginBottom: 6 }}>Har hisobot oxiriga qo'shimcha matn (ixtiyoriy)</div>
                <textarea className="input" rows={2} defaultValue={cfg.customText || ''}
                  onBlur={e => { if ((e.target.value || '') !== (cfg.customText || '')) setCfg({ customText: e.target.value }); }}
                  placeholder="Masalan: Eslatma — ertaga oylik hisobot yopiladi." style={{ width: '100%', resize: 'vertical' }} />
              </div>

              {/* Guruh eslatmasi — bajarilmagan vazifalar */}
              <div style={{ marginTop: 22, marginBottom: 6, fontWeight: 700, fontSize: 13 }}>Guruhga eslatma (bajarilmagan vazifalar)</div>
              <Card>
                <Row>
                  <span style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13.5, fontWeight: 600 }}>
                    <span style={{ width: 9, height: 9, borderRadius: '50%', background: (admin.group && admin.group.connected) ? 'var(--st-delivered)' : 'var(--st-loading)' }} />
                    Guruh
                  </span>
                  <div style={{ flex: 1 }} />
                  <span style={{ fontSize: 13, fontWeight: 700, color: (admin.group && admin.group.connected) ? 'var(--st-delivered)' : 'var(--ink-4)' }}>
                    {(admin.group && admin.group.connected) ? ((admin.group.title || 'Ulangan')) : 'Ulanmagan'}
                  </span>
                </Row>
                {(!admin.group || !admin.group.connected) ? (
                  <Row last><span style={{ fontSize: 12.5, color: 'var(--ink-3)' }}>
                    Botni guruhga qo'shing, so'ng guruhda <b>/start</b> yozing — guruh shu yerda avtomatik ulanadi.
                  </span></Row>
                ) : (
                  <>
                    <Row>
                      <div style={{ minWidth: 0 }}>
                        <div style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--ink-2)' }}>Eslatma yoqilgan</div>
                        <div style={{ fontSize: 11.5, color: 'var(--ink-4)' }}>O'chirilsa, guruhga eslatma yuborilmaydi</div>
                      </div>
                      <div style={{ flex: 1 }} />
                      <TgToggle on={admin.group.enabled !== false} disabled={busy === 'cfg'} onChange={(v) => setCfg({ groupReminderEnabled: v })} />
                    </Row>
                    <Row last>
                      <div style={{ minWidth: 0 }}>
                        <div style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--ink-2)' }}>Yuborish soatlari</div>
                        <div style={{ fontSize: 11.5, color: 'var(--ink-4)' }}>Vergul bilan, masalan: 9, 13, 17</div>
                      </div>
                      <div style={{ flex: 1 }} />
                      <input className="input" defaultValue={(admin.group.hours || []).join(', ')}
                        onBlur={e => {
                          const hrs = (e.target.value || '').split(',').map(x => parseInt(x.trim(), 10)).filter(x => !isNaN(x) && x >= 0 && x <= 23);
                          setCfg({ groupReminderHours: hrs.length ? hrs : [9, 13, 17] });
                        }}
                        placeholder="9, 13, 17" style={{ width: 120, textAlign: 'center' }} />
                    </Row>
                  </>
                )}
              </Card>

              <div style={{ marginTop: 16, display: 'flex', gap: 10, flexWrap: 'wrap' }}>
                <button className="btn" disabled={busy === 'hook'} onClick={setupWebhook}><Icon name="send" size={15} stroke={2.2} /> Webhookni o'rnatish</button>
                <button className="btn" disabled={busy === 'test' || !connected} onClick={test}>Menga sinov yuborish</button>
                <button className="btn btn--primary" disabled={busy === 'daily'} onClick={runDaily}>Kunlik hisobotni hozir yuborish</button>
                {admin.group && admin.group.connected && (
                  <button className="btn" disabled={busy === 'group'} onClick={runGroup}>Guruhga hozir yuborish</button>
                )}
                <button className="btn" disabled={busy === 'att'} onClick={runAttendance}>Davomat hisobotini hozir yuborish</button>
              </div>
              {!connected && <div style={{ marginTop: 8, fontSize: 11.5, color: 'var(--ink-4)' }}>Sinov yuborish uchun avval o'z akkauntingizni yuqorida ulang.</div>}
            </>
          )}
        </div>
      )}
    </>
  );
}

function PanelHead({ title, onAdd, addLabel }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 14 }}>
      <span style={{ fontWeight: 700, fontSize: 14.5 }}>{title}</span>
      <button className="btn btn--primary btn--sm" onClick={onAdd}><Icon name="plus" size={15} stroke={2.4} /> {addLabel}</button>
    </div>
  );
}
function Card({ children }) {
  return <div className="gx-card" style={{ background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 'var(--r-lg)', overflow: 'hidden', boxShadow: 'var(--sh-1)' }}>{children}</div>;
}
function Row({ children, last }) {
  return <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '13px 16px', borderBottom: last ? 'none' : '1px solid var(--border)' }}>{children}</div>;
}
function RowActions({ onEdit, onDelete }) {
  return (
    <div style={{ display: 'flex', gap: 4 }}>
      <button className="btn btn--icon btn--ghost" style={{ padding: 7, borderColor: 'transparent', color: 'var(--ink-3)' }} onClick={onEdit} aria-label="Tahrirlash"><Icon name="edit" size={15} /></button>
      <button className="btn btn--icon btn--ghost" style={{ padding: 7, borderColor: 'transparent', color: 'var(--ink-3)' }} onClick={onDelete} aria-label="O'chirish"><Icon name="trash" size={15} /></button>
    </div>
  );
}

/* ---------- Viloyatlar ---------- */
function RegionsPanel({ refresh, showToast }) {
  const [modal, setModal] = useState(null); // {id?, name}
  const [syncing, setSyncing] = useState(false);
  async function syncFromSheet() {
    if (syncing) return;
    setSyncing(true);
    try {
      const res = await API.syncSheet();
      const r = res.regions || {}, d = res.distributors || {};
      // Butun platforma yangi nomlarni ko'rishi uchun bootstrap'ni qayta yuklaymiz.
      try { const b = await API.bootstrap(); DB.hydrate(b); } catch (_) {}
      const parts = [
        `Hudud: +${(r.created || []).length} yangi, ${(r.renamed || []).length} nomlandi`,
        `Diller: +${(d.created || []).length} yangi, ${(d.renamed || []).length} nomlandi`,
      ];
      const arR = (r.archived || []).length, arD = (d.archived || []).length;
      const delR = (r.deleted || []).length, delD = (d.deleted || []).length;
      if (arR || arD) parts.push(`arxiv (eski oy uchun yashirin): hudud ${arR}, diller ${arD}`);
      if (delR || delD) parts.push(`o'chirildi: hudud ${delR}, diller ${delD}`);
      showToast('Sinxronlandi — ' + parts.join(' · '));
      refresh();
    } catch (ex) {
      showToast(ex.message || 'Sinxronlashda xatolik');
    } finally {
      setSyncing(false);
    }
  }
  async function save(data) {
    try {
      if (modal.id) {
        const { region } = await API.updateRegion(modal.id, data);
        const r = DB.REGIONS.find(x => x.id === modal.id); if (r) Object.assign(r, region);
        showToast('Viloyat yangilandi');
      } else {
        const { region } = await API.createRegion(data);
        DB.REGIONS.push(region);
        showToast('Viloyat qo\u02bcshildi');
      }
      setModal(null); refresh();
    } catch (ex) { showToast(ex.message || 'Saqlashda xatolik'); }
  }
  async function del(id) {
    if (DB.DISTRIBUTORS.some(d => d.region === id)) { showToast('Avval bu viloyatdagi dillerlarni o\u02bcchiring'); return; }
    try {
      await API.deleteRegion(id);
      const i = DB.REGIONS.findIndex(x => x.id === id); if (i >= 0) DB.REGIONS.splice(i, 1);
      showToast('Viloyat o\u02bcchirildi'); refresh();
    } catch (ex) { showToast(ex.message || 'O\u02bcchirishda xatolik'); }
  }
  return (
    <>
      <PanelHead title="Viloyatlar va regional menejerlar" addLabel="Viloyat qo'shish" onAdd={() => setModal({ name: '' })} />
      <div style={{ margin: '0 0 12px', display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
        <button className="btn btn--ghost" onClick={syncFromSheet} disabled={syncing} style={{ gap: 8 }}>
          <Icon name="refresh" size={15} />
          {syncing ? 'Sinxronlanmoqda…' : 'Jadval bilan sinxronlash'}
        </button>
        <span style={{ fontSize: 11.5, color: 'var(--ink-4)' }}>
          JORIY oy (Avgust) SELL IN + SELL OUT jadvalidagi hudud va dillerlarni platformaga moslaydi — faqat shular ko'rinadi (zakaz urish, menejer). Eski oylarda bo'lib, hozir yo'qlar ARXIVlanadi (yashirin, lekin eski oyga o'tilganda tarixi ko'rinadi). Hech qanday ma'lumoti yo'qlar o'chiriladi. ID'lar saqlanadi — zakazlar buzilmaydi.
        </span>
      </div>
      <Card>
        {DB.activeRegions().map((r, i, arr) => {
          const n = DB.activeDistributors().filter(d => d.region === r.id).length;
          const mgrs = DB.regionManagers(r.id); // [{user, brandId}]
          const mgrLabel = mgrs.length
            ? mgrs.map(m => m.user.name + (m.brandId ? ' · ' + DB.brandName(m.brandId) : '')).join(', ')
            : 'Menejer biriktirilmagan';
          return (
            <Row key={r.id} last={i === arr.length - 1}>
              <span style={{ width: 30, height: 30, borderRadius: 8, background: 'var(--brand-tint)', color: 'var(--brand-700)', display: 'grid', placeItems: 'center' }}><Icon name="pin" size={15} /></span>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontWeight: 700, fontSize: 13.5 }}>{r.name}</div>
                <div style={{ display: 'flex', alignItems: 'center', gap: 5, fontSize: 11.5, color: 'var(--ink-4)', marginTop: 2 }}>
                  <Icon name="user" size={12} stroke={1.9} /> {mgrLabel}
                </div>
              </div>
              <span className="chip">{n} diller</span>
              <RowActions onEdit={() => setModal({ id: r.id, name: r.name })} onDelete={() => del(r.id)} />
            </Row>
          );
        })}
      </Card>
      {modal && <RegionModal initial={modal} onClose={() => setModal(null)} onSave={save} />}
    </>
  );
}

/* ---------- Dillerlar ---------- */
function DistsPanel({ refresh, showToast }) {
  const [modal, setModal] = useState(null);
  async function save(data) {
    try {
      if (modal.id) {
        const { distributor } = await API.updateDistributor(modal.id, data);
        const d = DB.DISTRIBUTORS.find(x => x.id === modal.id); if (d) Object.assign(d, distributor);
        showToast('Diller yangilandi');
      } else {
        const { distributor } = await API.createDistributor(data);
        DB.DISTRIBUTORS.push(distributor);
        showToast('Diller qo\u02bcshildi');
      }
      setModal(null); refresh();
    } catch (ex) { showToast(ex.message || 'Saqlashda xatolik'); }
  }
  async function del(id) {
    try {
      await API.deleteDistributor(id);
      const i = DB.DISTRIBUTORS.findIndex(x => x.id === id); if (i >= 0) DB.DISTRIBUTORS.splice(i, 1);
      showToast('Diller o\u02bcchirildi'); refresh();
    } catch (ex) { showToast(ex.message || 'O\u02bcchirishda xatolik'); }
  }
  return (
    <>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 14 }}>
        <span style={{ fontWeight: 700, fontSize: 14.5 }}>Dillerlar</span>
        <button className="btn btn--primary btn--sm" disabled={!DB.activeRegions().length}
          title={DB.activeRegions().length ? '' : 'Avval viloyat qoʼshing'}
          onClick={() => setModal({ name: '', region: DB.activeRegions()[0].id })}><Icon name="plus" size={15} stroke={2.4} /> Diller qo'shish</button>
      </div>
      <Card>
        {DB.activeDistributors().map((d, i, arr) => (
          <Row key={d.id} last={i === arr.length - 1}>
            <span style={{ width: 30, height: 30, borderRadius: 8, background: 'var(--bg-2)', color: 'var(--ink-2)', display: 'grid', placeItems: 'center', fontWeight: 800, fontSize: 12 }}>
              {d.name.split(' ').map(s => s[0]).join('').slice(0, 2)}
            </span>
            <span style={{ fontWeight: 700, fontSize: 13.5, flex: 1 }}>{d.name}</span>
            <span className="chip" style={{ background: 'var(--brand-tint)', color: 'var(--brand-700)' }}><Icon name="pin" size={12} /> {DB.regionName(d.region)}</span>
            <RowActions onEdit={() => setModal({ id: d.id, name: d.name, region: d.region })} onDelete={() => del(d.id)} />
          </Row>
        ))}
      </Card>
      {modal && <DistModal initial={modal} onClose={() => setModal(null)} onSave={save} />}
    </>
  );
}

/* ---------- Mahsulotlar ---------- */
function ProductsPanel({ refresh, showToast }) {
  const [modal, setModal] = useState(null);
  const [catModal, setCatModal] = useState(null); // {id?, name, brand}
  const [brandModal, setBrandModal] = useState(null); // {id?, name, color}
  const [groupModal, setGroupModal] = useState(null); // {id?, name, productIds:[]}
  const [importing, setImporting] = useState(false);
  const fileRef = useRef(null);

  async function saveGroup(data) {
    try {
      if (groupModal.id) {
        const { productGroup } = await API.updateProductGroup(groupModal.id, data);
        const g = DB.PRODUCT_GROUPS.find(x => x.id === groupModal.id); if (g) Object.assign(g, productGroup);
        showToast('Guruh yangilandi');
      } else {
        const { productGroup } = await API.createProductGroup(data);
        DB.PRODUCT_GROUPS.push(productGroup);
        showToast('Guruh qoʼshildi');
      }
      setGroupModal(null); refresh();
    } catch (ex) { showToast(ex.message || 'Saqlashda xatolik'); }
  }
  async function delGroup(id) {
    try {
      await API.deleteProductGroup(id);
      const i = DB.PRODUCT_GROUPS.findIndex(x => x.id === id); if (i >= 0) DB.PRODUCT_GROUPS.splice(i, 1);
      showToast('Guruh oʼchirildi'); refresh();
    } catch (ex) { showToast(ex.message || 'Oʼchirishda xatolik'); }
  }

  async function saveCat(data) {
    try {
      if (catModal.id) {
        const { category } = await API.updateCategory(catModal.id, data);
        const c = DB.CATEGORIES.find(x => x.id === catModal.id); if (c) Object.assign(c, category);
        showToast('Kategoriya yangilandi');
      } else {
        const { category } = await API.createCategory(data);
        DB.CATEGORIES.push(category);
        showToast('Kategoriya qoʼshildi');
      }
      setCatModal(null); refresh();
    } catch (ex) { showToast(ex.message || 'Saqlashda xatolik'); }
  }
  async function delCat(id) {
    if (DB.PRODUCTS.some(p => p.cat === id)) { showToast('Avval bu kategoriyadagi mahsulotlarni oʼchiring'); return; }
    try {
      await API.deleteCategory(id);
      const i = DB.CATEGORIES.findIndex(x => x.id === id); if (i >= 0) DB.CATEGORIES.splice(i, 1);
      showToast('Kategoriya oʼchirildi'); refresh();
    } catch (ex) { showToast(ex.message || 'Oʼchirishda xatolik'); }
  }

  async function saveBrand(data) {
    try {
      if (brandModal.id) {
        const { brand } = await API.updateBrand(brandModal.id, data);
        const b = DB.BRANDS.find(x => x.id === brandModal.id); if (b) Object.assign(b, brand);
        showToast('Brend yangilandi');
      } else {
        const { brand } = await API.createBrand(data);
        DB.BRANDS.push(brand);
        showToast("Brend qo'shildi");
      }
      setBrandModal(null); refresh();
    } catch (ex) { showToast(ex.message || 'Saqlashda xatolik'); }
  }
  async function delBrand(id) {
    if (DB.CATEGORIES.some(c => c.brand === id)) { showToast("Avval bu brenddagi kategoriyalarni o'chiring"); return; }
    if (!window.confirm("Brendni o'chirasizmi?")) return;
    try {
      await API.deleteBrand(id);
      const i = DB.BRANDS.findIndex(x => x.id === id); if (i >= 0) DB.BRANDS.splice(i, 1);
      showToast("Brend o'chirildi"); refresh();
    } catch (ex) { showToast(ex.message || "O'chirishda xatolik"); }
  }

  // Namuna xls — qaysi tartibda yuklashni ko'rsatadi
  // Eslatma: import kategoriyani NOMI bo'yicha topadi, shuning uchun namunadagi
  // brand/category qiymatlari aynan tizimdagi joriy nomlardan olinadi.
  function downloadSample() {
    if (typeof XLSX === 'undefined') { showToast('XLSX kutubxonasi yuklanmadi'); return; }
    const header = ['brand', 'category', 'name', 'sku', 'price', 'unit'];
    const brandName = (id) => { const b = DB.BRANDS.find(x => x.id === id); return b ? b.name : ''; };

    // Joriy kategoriyalardan birinchi 2 tasini namuna sifatida olamiz
    const cats = (DB.CATEGORIES || []).slice(0, 2);
    let sample;
    if (cats.length) {
      sample = cats.map((c, i) => ({
        brand: brandName(c.brand),
        category: c.name,
        name: c.name + ' namuna ' + (i + 1),
        sku: i === 0 ? '5 ta blister' : '1L',
        price: i === 0 ? 12000 : 9000,
        unit: i === 0 ? 'blok' : 'karobka',
      }));
    } else {
      // Hali kategoriya yo'q bo'lsa — umumiy namuna
      sample = [
        { brand: 'Brend A', category: 'Kategoriya 1', name: 'Mahsulot namuna 1', sku: '5 ta blister', price: 12000, unit: 'blok' },
        { brand: 'Brend B', category: 'Kategoriya 2', name: 'Mahsulot namuna 2', sku: '1L', price: 9000, unit: 'karobka' },
      ];
    }
    const ws = XLSX.utils.json_to_sheet(sample, { header });
    ws['!cols'] = [{ wch: 10 }, { wch: 16 }, { wch: 22 }, { wch: 16 }, { wch: 10 }, { wch: 10 }];
    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, 'Mahsulotlar');
    XLSX.writeFile(wb, 'mahsulot-namuna.xlsx');
  }

  // Mavjud BARCHA mahsulotlar ro'yxatini yuklab olish: Brend · Kategoriya · Nomi
  function downloadAll() {
    if (typeof XLSX === 'undefined') { showToast('XLSX kutubxonasi yuklanmadi'); return; }
    const prods = DB.PRODUCTS || [];
    if (!prods.length) { showToast('Mahsulotlar topilmadi'); return; }
    const catById = {}; (DB.CATEGORIES || []).forEach(c => { catById[c.id] = c; });
    const brandById = {}; (DB.BRANDS || []).forEach(b => { brandById[b.id] = b; });
    const rows = prods.map(p => {
      const c = catById[p.cat];
      const b = c ? brandById[c.brand] : null;
      return { Brend: b ? b.name : '', Kategoriya: c ? c.name : '', Nomi: p.name || '' };
    }).sort((a, b) =>
      (a.Brend || '').localeCompare(b.Brend || '') ||
      (a.Kategoriya || '').localeCompare(b.Kategoriya || '') ||
      (a.Nomi || '').localeCompare(b.Nomi || '')
    );
    const ws = XLSX.utils.json_to_sheet(rows, { header: ['Brend', 'Kategoriya', 'Nomi'] });
    ws['!cols'] = [{ wch: 12 }, { wch: 22 }, { wch: 32 }];
    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, 'Mahsulotlar');
    XLSX.writeFile(wb, 'mahsulotlar.xlsx');
    showToast(`${rows.length} ta mahsulot yuklab olindi`);
  }

  async function onFile(e) {
    const file = e.target.files && e.target.files[0];
    e.target.value = ''; // bir xil faylni qayta tanlash mumkin bo'lsin
    if (!file) return;
    if (typeof XLSX === 'undefined') { showToast('XLSX kutubxonasi yuklanmadi'); return; }
    setImporting(true);
    try {
      const buf = await file.arrayBuffer();
      const wb = XLSX.read(buf, { type: 'array' });
      const ws = wb.Sheets[wb.SheetNames[0]];
      const rows = XLSX.utils.sheet_to_json(ws, { defval: '' });
      if (!rows.length) { showToast('Faylda qatorlar topilmadi'); setImporting(false); return; }
      const res = await API.importProducts(rows);
      (res.created || []).forEach(p => { DB.PRODUCTS.push(p); DB.PRODUCT_BY_ID[p.id] = p; });
      if (res.errorCount > 0) {
        const first = res.errors && res.errors[0];
        showToast(`${res.createdCount} ta qo'shildi · ${res.errorCount} ta xato` + (first ? ` (${first.row}-qator: ${first.message})` : ''));
      } else {
        showToast(`${res.createdCount} ta mahsulot import qilindi`);
      }
      refresh();
    } catch (ex) {
      showToast(ex.message || 'Import xatosi');
    }
    setImporting(false);
  }

  async function save(data) {
    try {
      if (modal.id) {
        const { product } = await API.updateProduct(modal.id, data);
        const p = DB.PRODUCT_BY_ID[modal.id]; if (p) Object.assign(p, product);
        showToast('Mahsulot yangilandi');
      } else {
        const { product } = await API.createProduct(data);
        DB.PRODUCTS.push(product); DB.PRODUCT_BY_ID[product.id] = product;
        showToast('Mahsulot qo\u02bcshildi');
      }
      setModal(null); refresh();
    } catch (ex) { showToast(ex.message || 'Saqlashda xatolik'); }
  }
  async function del(id) {
    try {
      await API.deleteProduct(id);
      const i = DB.PRODUCTS.findIndex(x => x.id === id); if (i >= 0) DB.PRODUCTS.splice(i, 1);
      delete DB.PRODUCT_BY_ID[id];
      showToast('Mahsulot o\u02bcchirildi'); refresh();
    } catch (ex) { showToast(ex.message || 'O\u02bcchirishda xatolik'); }
  }
  return (
    <>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 14, gap: 10, flexWrap: 'wrap' }}>
        <span style={{ fontWeight: 700, fontSize: 14.5 }}>Mahsulotlar</span>
        <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
          <input ref={fileRef} type="file" accept=".xls,.xlsx,.csv" style={{ display: 'none' }} onChange={onFile} />
          <button className="btn btn--ghost btn--sm" disabled={!DB.PRODUCTS.length} onClick={downloadAll}><Icon name="download" size={15} stroke={2.1} /> Ro'yxatni yuklab olish</button>
          <button className="btn btn--ghost btn--sm" onClick={downloadSample}><Icon name="download" size={15} stroke={2.1} /> Namuna (xls)</button>
          <button className="btn btn--ghost btn--sm" disabled={importing} onClick={() => fileRef.current && fileRef.current.click()}>
            <Icon name="upload" size={15} stroke={2.1} /> {importing ? 'Import...' : 'Import (xls)'}
          </button>
          <button className="btn btn--ghost btn--sm" onClick={() => setBrandModal({ name: '', color: BRAND_COLORS[DB.BRANDS.length % BRAND_COLORS.length] })}><Icon name="plus" size={15} stroke={2.4} /> Brend qo'shish</button>
          <button className="btn btn--primary btn--sm" disabled={!DB.CATEGORIES.length} onClick={() => setModal({ name: '', cat: DB.CATEGORIES[0].id, sku: '', price: 0, unit: 'blok' })}><Icon name="plus" size={15} stroke={2.4} /> Mahsulot qo'shish</button>
        </div>
      </div>
      {!DB.BRANDS.length && (
        <Card><Row last><span style={{ color: 'var(--ink-4)', fontSize: 12.5 }}>Hali brend yo'q. Avval «Brend qo'shish» orqali brend yarating, so'ng unga kategoriya va mahsulotlar qo'shing.</span></Row></Card>
      )}
      {DB.BRANDS.map(b => {
        const cats = DB.CATEGORIES.filter(c => c.brand === b.id);
        return (
          <div key={b.id} style={{ marginBottom: 18 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 9, margin: '0 2px 9px' }}>
              <BrandTag brandId={b.id} size="lg" />
              <span style={{ fontSize: 12, color: 'var(--ink-4)', fontWeight: 600 }}>{DB.PRODUCTS.filter(p => cats.some(c => c.id === p.cat)).length} ta mahsulot</span>
              <button className="btn btn--icon btn--ghost" style={{ padding: 4, border: 'none', color: 'var(--ink-4)' }}
                onClick={() => setBrandModal({ id: b.id, name: b.name, color: b.color })} aria-label="Brendni tahrirlash"><Icon name="edit" size={13} /></button>
              <button className="btn btn--icon btn--ghost" style={{ padding: 4, border: 'none', color: 'var(--ink-4)' }}
                onClick={() => delBrand(b.id)} aria-label="Brendni o'chirish"><Icon name="trash" size={13} /></button>
            </div>
            {/* Kategoriyalar — tahrirlanadigan */}
            <div style={{ display: 'flex', alignItems: 'center', gap: 7, flexWrap: 'wrap', margin: '0 2px 11px' }}>
              {cats.map(c => (
                <span key={c.id} style={{ display: 'inline-flex', alignItems: 'center', gap: 4, padding: '4px 6px 4px 11px',
                                          borderRadius: 100, background: 'var(--bg-2)', border: '1px solid var(--border)', fontSize: 12, fontWeight: 700 }}>
                  {c.name}
                  <button className="btn btn--icon btn--ghost" style={{ padding: 4, border: 'none', color: 'var(--ink-4)' }}
                    onClick={() => setCatModal({ id: c.id, name: c.name, brand: c.brand })} aria-label="Tahrirlash"><Icon name="edit" size={13} /></button>
                  <button className="btn btn--icon btn--ghost" style={{ padding: 4, border: 'none', color: 'var(--ink-4)' }}
                    onClick={() => delCat(c.id)} aria-label="O'chirish"><Icon name="trash" size={13} /></button>
                </span>
              ))}
              <button className="btn btn--ghost btn--sm" style={{ borderStyle: 'dashed' }}
                onClick={() => setCatModal({ name: '', brand: b.id })}><Icon name="plus" size={14} stroke={2.4} /> Kategoriya</button>
            </div>
            <Card>
              {(() => {
                const prods = DB.PRODUCTS.filter(p => cats.some(c => c.id === p.cat));
                if (prods.length === 0) return <Row last><span style={{ color: 'var(--ink-4)', fontSize: 12.5 }}>Mahsulot yo'q</span></Row>;
                return prods.map((p, i) => {
                  const cat = DB.CATEGORIES.find(c => c.id === p.cat);
                  return (
                    <Row key={p.id} last={i === prods.length - 1}>
                      <div style={{ flex: 1 }}>
                        <div style={{ fontWeight: 700, fontSize: 13.5 }}>{p.name}</div>
                        <div style={{ fontSize: 11.5, color: 'var(--ink-4)', marginTop: 2 }}>{cat ? cat.name : ''}</div>
                      </div>
                      <span className="chip" style={{ textTransform: 'capitalize' }}>{p.unit}</span>
                      <span className="tnum" style={{ fontWeight: 700, fontSize: 13.5, width: 110, textAlign: 'right' }}>{DB.fmtSum(p.price)} so'm</span>
                      <RowActions onEdit={() => setModal({ id: p.id, name: p.name, cat: p.cat, sku: p.sku, price: p.price, unit: p.unit })} onDelete={() => del(p.id)} />
                    </Row>
                  );
                });
              })()}
            </Card>
          </div>
        );
      })}
      {/* ---------- Erkin guruhlar (kolleksiyalar) ---------- */}
      <div style={{ marginTop: 26, paddingTop: 20, borderTop: '1px solid var(--border)' }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 6, gap: 10, flexWrap: 'wrap' }}>
          <span style={{ fontWeight: 700, fontSize: 14.5 }}>Guruhlar</span>
          <button className="btn btn--primary btn--sm" disabled={!DB.PRODUCTS.length}
            onClick={() => setGroupModal({ name: '', productIds: [] })}><Icon name="plus" size={15} stroke={2.4} /> Guruh qo'shish</button>
        </div>
        <div style={{ fontSize: 12, color: 'var(--ink-4)', marginBottom: 12 }}>
          Brend va kategoriyadan mustaqil — ixtiyoriy mahsulotlarni bitta nom ostida birlashtiring (masalan: «Yaxshi sotiladigan mahsulotlar»).
        </div>
        {DB.PRODUCT_GROUPS.length === 0 ? (
          <Card><Row last><span style={{ color: 'var(--ink-4)', fontSize: 12.5 }}>Hozircha guruh yo'q</span></Row></Card>
        ) : DB.PRODUCT_GROUPS.map(g => {
          const prods = (g.productIds || []).map(id => DB.PRODUCT_BY_ID[id]).filter(Boolean);
          return (
            <div key={g.id} style={{ marginBottom: 14 }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8, margin: '0 2px 8px' }}>
                <span style={{ fontWeight: 700, fontSize: 13.5 }}>{g.name}</span>
                <span style={{ fontSize: 12, color: 'var(--ink-4)', fontWeight: 600 }}>{prods.length} ta mahsulot</span>
                <div style={{ flex: 1 }} />
                <button className="btn btn--icon btn--ghost" style={{ padding: 5, border: 'none', color: 'var(--ink-4)' }}
                  onClick={() => setGroupModal({ id: g.id, name: g.name, productIds: [...(g.productIds || [])] })} aria-label="Tahrirlash"><Icon name="edit" size={14} /></button>
                <button className="btn btn--icon btn--ghost" style={{ padding: 5, border: 'none', color: 'var(--ink-4)' }}
                  onClick={() => delGroup(g.id)} aria-label="O'chirish"><Icon name="trash" size={14} /></button>
              </div>
              <Card>
                {prods.length === 0 ? <Row last><span style={{ color: 'var(--ink-4)', fontSize: 12.5 }}>Mahsulot biriktirilmagan</span></Row>
                  : prods.map((p, i) => {
                    const brand = DB.brandOfProduct(p.id);
                    return (
                      <Row key={p.id} last={i === prods.length - 1}>
                        <div style={{ flex: 1 }}>
                          <div style={{ fontWeight: 700, fontSize: 13.5 }}>{p.name}</div>
                          <div style={{ fontSize: 11.5, color: 'var(--ink-4)', marginTop: 2 }}>{brand ? brand.name : ''}</div>
                        </div>
                        <span className="tnum" style={{ fontWeight: 700, fontSize: 13.5, width: 110, textAlign: 'right' }}>{DB.fmtSum(p.price)} so'm</span>
                      </Row>
                    );
                  })}
              </Card>
            </div>
          );
        })}
      </div>
      {modal && <ProductModal initial={modal} onClose={() => setModal(null)} onSave={save} />}
      {catModal && <CategoryModal initial={catModal} onClose={() => setCatModal(null)} onSave={saveCat} />}
      {brandModal && <BrandModal initial={brandModal} onClose={() => setBrandModal(null)} onSave={saveBrand} />}
      {groupModal && <ProductGroupModal initial={groupModal} onClose={() => setGroupModal(null)} onSave={saveGroup} />}
    </>
  );
}

/* ---------- Foydalanuvchilar (login akkauntlar) — faqat super admin ---------- */
function UsersPanel({ refresh, showToast, currentUser }) {
  const [modal, setModal] = useState(null);
  async function save(data) {
    try {
      if (modal.id) {
        const { user } = await API.updateUser(modal.id, data);
        const u = DB.USERS.find(x => x.id === modal.id); if (u) Object.assign(u, user);
        showToast('Foydalanuvchi yangilandi');
      } else {
        const { user } = await API.createUser(data);
        DB.USERS.push(user);
        showToast('Foydalanuvchi qoʼshildi');
      }
      setModal(null); refresh();
    } catch (ex) { showToast(ex.message || 'Saqlashda xatolik'); }
  }
  async function del(id) {
    try {
      await API.deleteUser(id);
      const i = DB.USERS.findIndex(x => x.id === id); if (i >= 0) DB.USERS.splice(i, 1);
      showToast('Foydalanuvchi oʼchirildi'); refresh();
    } catch (ex) { showToast(ex.message || 'Oʼchirishda xatolik'); }
  }
  return (
    <>
      <PanelHead title="Foydalanuvchilar (login akkauntlar)" addLabel="Foydalanuvchi qo'shish"
        onAdd={() => setModal({ username: '', name: '', role: 'regional', regionIds: [], brandIds: [], password: '' })} />
      <Card>
        {DB.USERS.length === 0 && <Row last><span style={{ color: 'var(--ink-4)', fontSize: 13 }}>Hozircha foydalanuvchilar yo'q</span></Row>}
        {DB.USERS.map((u, i) => {
          const role = DB.ROLES[u.role];
          const isSelf = currentUser && u.id === currentUser.id;
          const regionIds = u.regions || [];
          const brandIds = u.brands || [];
          const regionsText = regionIds.map(id => DB.regionName(id)).join(', ');
          const brandsText = brandIds.map(id => DB.brandName(id)).join(', ');
          const rScoped = !!(role && role.perms && role.perms.regionScoped) && !(role && role.super);
          const bScoped = !!(role && role.perms && role.perms.brandScoped) && !(role && role.super);
          const regionSuffix = rScoped
            ? ' · ' + (regionsText || 'viloyat biriktirilmagan')
            : (role && role.super && regionsText) ? ' · ' + regionsText : '';
          const brandSuffix = bScoped
            ? ' · ' + (brandsText || 'brend biriktirilmagan')
            : (role && role.super && brandsText) ? ' · ' + brandsText : '';
          return (
            <Row key={u.id} last={i === DB.USERS.length - 1}>
              <span style={{ width: 30, height: 30, borderRadius: 8, background: 'var(--brand-tint)', color: 'var(--brand-700)', display: 'grid', placeItems: 'center' }}><Icon name="user" size={15} /></span>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontWeight: 700, fontSize: 13.5 }}>{u.name} <span style={{ color: 'var(--ink-4)', fontWeight: 500 }}>@{u.username}</span></div>
                <div style={{ fontSize: 11.5, color: 'var(--ink-4)', marginTop: 2 }}>
                  {role ? role.label : u.role}{regionSuffix}{brandSuffix}
                </div>
              </div>
              {role && role.super && <span className="chip" style={{ background: 'var(--brand-tint)', color: 'var(--brand-700)' }}>super</span>}
              <RowActions onEdit={() => setModal({ id: u.id, username: u.username, name: u.name, role: u.role, regionIds, brandIds, password: '' })}
                onDelete={() => isSelf ? showToast('Oʼzingizni oʼchira olmaysiz') : del(u.id)} />
            </Row>
          );
        })}
      </Card>
      {modal && <UserModal initial={modal} onClose={() => setModal(null)} onSave={save} />}
    </>
  );
}

/* ---------- Kichik modallar ---------- */
function RegionModal({ initial, onClose, onSave }) {
  const [name, setName] = useState(initial.name || '');
  return (
    <Modal onClose={onClose} width={430}>
      <ModalHeader title={initial.id ? 'Viloyatni tahrirlash' : 'Yangi viloyat'} onClose={onClose} />
      <div style={{ padding: '20px 22px', display: 'grid', gap: 14 }}>
        <div><label className="field-label">Viloyat nomi</label><input className="input" value={name} autoFocus onChange={e => setName(e.target.value)} onKeyDown={e => { if (e.key === 'Enter' && name.trim()) onSave({ name: name.trim() }); }} /></div>
        <div style={{ fontSize: 12, color: 'var(--ink-4)', lineHeight: 1.5, background: 'var(--bg-2)', padding: '10px 12px', borderRadius: 8 }}>
          <Icon name="info" size={13} style={{ verticalAlign: '-2px', marginRight: 5 }} />
          Regional menejer <b>Foydalanuvchilar</b> bo'limida yaratiladi va shu viloyatga biriktiriladi.
        </div>
      </div>
      <ModalFooter onClose={onClose} onSave={() => name.trim() && onSave({ name: name.trim() })} disabled={!name.trim()} />
    </Modal>
  );
}
function NameModal({ title, label, initial, onClose, onSave }) {
  const [v, setV] = useState(initial || '');
  return (
    <Modal onClose={onClose} width={400}>
      <ModalHeader title={title} onClose={onClose} />
      <div style={{ padding: '20px 22px' }}>
        <label className="field-label">{label}</label>
        <input className="input" value={v} autoFocus onChange={e => setV(e.target.value)} onKeyDown={e => { if (e.key === 'Enter' && v.trim()) onSave(v.trim()); }} />
      </div>
      <ModalFooter onClose={onClose} onSave={() => v.trim() && onSave(v.trim())} disabled={!v.trim()} />
    </Modal>
  );
}
function DistModal({ initial, onClose, onSave }) {
  const [name, setName] = useState(initial.name || '');
  const [region, setRegion] = useState(initial.region);
  return (
    <Modal onClose={onClose} width={420}>
      <ModalHeader title={initial.id ? 'Dillerni tahrirlash' : 'Yangi diller'} onClose={onClose} />
      <div style={{ padding: '20px 22px', display: 'grid', gap: 14 }}>
        <div><label className="field-label">Diller nomi</label><input className="input" value={name} autoFocus onChange={e => setName(e.target.value)} /></div>
        <div><label className="field-label">Viloyat</label>
          <select className="select" value={region} onChange={e => setRegion(e.target.value)}>
            {DB.REGIONS.filter(r => r.active !== false || r.id === region).map(r => <option key={r.id} value={r.id}>{r.name}</option>)}
          </select>
        </div>
      </div>
      <ModalFooter onClose={onClose} onSave={() => name.trim() && onSave({ name: name.trim(), region })} disabled={!name.trim()} />
    </Modal>
  );
}
const BRAND_COLORS = ['#EC7A55', '#2B2927', '#3DBE9C', '#E9B949', '#5A9FD4', '#8E74FF', '#D9708F', '#C9A27E'];
function BrandModal({ initial, onClose, onSave }) {
  const [name, setName] = useState(initial.name || '');
  const [color, setColor] = useState(initial.color && initial.color.startsWith('#') ? initial.color : BRAND_COLORS[0]);
  return (
    <Modal onClose={onClose} width={420}>
      <ModalHeader title={initial.id ? 'Brendni tahrirlash' : 'Yangi brend'} onClose={onClose} />
      <div style={{ padding: '20px 22px', display: 'grid', gap: 14 }}>
        <div><label className="field-label">Brend nomi</label><input className="input" value={name} autoFocus placeholder="masalan: Moxito" onChange={e => setName(e.target.value)} /></div>
        <div><label className="field-label">Rang</label>
          <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
            {BRAND_COLORS.map(c => (
              <button key={c} type="button" onClick={() => setColor(c)} aria-label={c}
                style={{ width: 30, height: 30, borderRadius: '50%', background: c, cursor: 'pointer',
                         border: color === c ? '3px solid var(--surface-solid)' : '3px solid transparent',
                         boxShadow: color === c ? '0 0 0 2px ' + c : 'none' }} />
            ))}
          </div>
        </div>
      </div>
      <ModalFooter onClose={onClose} onSave={() => name.trim() && onSave({ name: name.trim(), color })} disabled={!name.trim()} />
    </Modal>
  );
}
function CategoryModal({ initial, onClose, onSave }) {
  const [name, setName] = useState(initial.name || '');
  const [brand, setBrand] = useState(initial.brand || (DB.BRANDS[0] && DB.BRANDS[0].id));
  return (
    <Modal onClose={onClose} width={420}>
      <ModalHeader title={initial.id ? 'Kategoriyani tahrirlash' : 'Yangi kategoriya'} onClose={onClose} />
      <div style={{ padding: '20px 22px', display: 'grid', gap: 14 }}>
        <div><label className="field-label">Kategoriya nomi</label><input className="input" value={name} autoFocus onChange={e => setName(e.target.value)} /></div>
        <div><label className="field-label">Brend</label>
          <select className="select" value={brand} onChange={e => setBrand(e.target.value)}>
            {DB.BRANDS.map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
          </select>
        </div>
      </div>
      <ModalFooter onClose={onClose} onSave={() => name.trim() && onSave({ name: name.trim(), brand })} disabled={!name.trim()} />
    </Modal>
  );
}
function ProductModal({ initial, onClose, onSave }) {
  const [name, setName] = useState(initial.name || '');
  const [cat, setCat] = useState(initial.cat);
  const [sku, setSku] = useState(initial.sku || '');
  const [price, setPrice] = useState(initial.price || 0);
  const [unit, setUnit] = useState(initial.unit || 'blok');
  return (
    <Modal onClose={onClose} width={460}>
      <ModalHeader title={initial.id ? 'Mahsulotni tahrirlash' : 'Yangi mahsulot'} onClose={onClose} />
      <div style={{ padding: '20px 22px', display: 'grid', gap: 14 }}>
        <div><label className="field-label">SKU nomi</label><input className="input" value={name} autoFocus onChange={e => setName(e.target.value)} /></div>
        <div><label className="field-label">Brend va kategoriya</label>
          <select className="select" value={cat} onChange={e => setCat(e.target.value)}>
            {DB.BRANDS.map(b => (
              <optgroup key={b.id} label={b.name}>
                {DB.CATEGORIES.filter(c => c.brand === b.id).map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
              </optgroup>
            ))}
          </select>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <div><label className="field-label">Narx (so'm)</label><input className="input tnum" value={price} onChange={e => setPrice(parseInt(e.target.value.replace(/\D/g, '') || '0', 10))} /></div>
          <div><label className="field-label">Birlik</label>
            <select className="select" value={unit} onChange={e => setUnit(e.target.value)}><option value="blok">blok</option><option value="karobka">karobka</option></select>
          </div>
        </div>
      </div>
      <ModalFooter onClose={onClose} onSave={() => name.trim() && onSave({ name: name.trim(), cat, sku, price, unit })} disabled={!name.trim() || price <= 0} />
    </Modal>
  );
}
function ProductGroupModal({ initial, onClose, onSave }) {
  const [name, setName] = useState(initial.name || '');
  const [ids, setIds] = useState(initial.productIds || []);
  const [q, setQ] = useState('');
  const idSet = new Set(ids);
  const ql = q.trim().toLowerCase();
  const list = DB.PRODUCTS.filter(p => {
    if (!ql) return true;
    const brand = DB.brandOfProduct(p.id);
    return p.name.toLowerCase().includes(ql) || (brand && brand.name.toLowerCase().includes(ql));
  });
  function toggle(id) { setIds(prev => prev.includes(id) ? prev.filter(x => x !== id) : [...prev, id]); }
  return (
    <Modal onClose={onClose} width={520}>
      <ModalHeader title={initial.id ? 'Guruhni tahrirlash' : 'Yangi guruh'} onClose={onClose} />
      <div style={{ padding: '20px 22px', display: 'grid', gap: 14 }}>
        <div><label className="field-label">Guruh nomi</label>
          <input className="input" value={name} autoFocus placeholder="masalan: Yaxshi sotiladigan mahsulotlar" onChange={e => setName(e.target.value)} /></div>
        <div>
          <label className="field-label">Mahsulotlar <span style={{ color: 'var(--ink-4)', fontWeight: 400 }}>({ids.length} ta tanlandi)</span></label>
          <input className="input" value={q} placeholder="Qidirish..." onChange={e => setQ(e.target.value)} style={{ marginBottom: 8 }} />
          {DB.PRODUCTS.length ? (
            <div style={{ display: 'grid', gap: 4, maxHeight: 280, overflowY: 'auto', border: '1px solid var(--border)', borderRadius: 8, padding: 8 }}>
              {list.length === 0 && <div style={{ fontSize: 12, color: 'var(--ink-4)', padding: '6px 4px' }}>Topilmadi</div>}
              {list.map(p => {
                const on = idSet.has(p.id);
                const brand = DB.brandOfProduct(p.id);
                return (
                  <label key={p.id} style={{ display: 'flex', alignItems: 'center', gap: 9, fontSize: 13, cursor: 'pointer',
                                             padding: '7px 9px', borderRadius: 6, background: on ? 'var(--brand-tint)' : 'transparent',
                                             color: on ? 'var(--brand-700)' : 'var(--ink-2)', fontWeight: on ? 700 : 500 }}>
                    <input type="checkbox" checked={on} onChange={() => toggle(p.id)} style={{ accentColor: 'var(--brand)' }} />
                    <span style={{ flex: 1 }}>{p.name}</span>
                    {brand && <span style={{ fontSize: 11, color: 'var(--ink-4)', fontWeight: 600 }}>{brand.name}</span>}
                  </label>
                );
              })}
            </div>
          ) : <div style={{ fontSize: 12, color: 'var(--st-loading)', padding: '9px 0' }}>Avval mahsulot qo'shing</div>}
        </div>
      </div>
      <ModalFooter onClose={onClose} onSave={() => name.trim() && onSave({ name: name.trim(), productIds: ids })} disabled={!name.trim()} />
    </Modal>
  );
}
function UserModal({ initial, onClose, onSave }) {
  const [username, setUsername] = useState(initial.username || '');
  const [name, setName] = useState(initial.name || '');
  const [role, setRole] = useState(initial.role || 'regional');
  // Viloyat+brend "uyalari": [{regionId, brandId}]. Eski yozuvlar (faqat regionIds/brandIds)
  // bo'lsa — ularning to'g'ri ko'paytmasidan boshlang'ich uyalar tuziladi (migratsiya).
  const [assignments, setAssignments] = useState(() => {
    if (Array.isArray(initial.assignments) && initial.assignments.length) {
      return initial.assignments.map(a => ({ regionId: a.regionId, brandId: a.brandId }));
    }
    const rs = initial.regionIds || [], bs = initial.brandIds || [];
    const out = [];
    rs.forEach(r => bs.forEach(b => out.push({ regionId: r, brandId: b })));
    return out;
  });
  const [password, setPassword] = useState('');
  const editing = !!initial.id;
  // Viloyat/brend biriktirish: hudud/brendga bog'langan rol uchun MAJBURIY,
  // super rol (boshliq/general) uchun IXTIYORIY. Boshqalar uchun ko'rinmaydi.
  const roleObj = DB.ROLES[role] || {};
  const scopedRole = !!(roleObj.perms && (roleObj.perms.regionScoped || roleObj.perms.brandScoped)) && !roleObj.super;
  const canAssign = scopedRole || !!roleObj.super;
  const assignRequired = false; // viloyat/brend biriktirish IXTIYORIY (keyin biriktirish mumkin)
  // Boshqa menejerlarga (joriy userdan tashqari) band uyalar — eksklyuzivlik uchun.
  const takenSlots = useMemo(() => {
    const m = {}; // "regionId|brandId" -> egasining ismi
    DB.USERS.forEach(u => {
      if (initial.id && u.id === initial.id) return;
      (Array.isArray(u.assignments) ? u.assignments : []).forEach(a => {
        if (a && a.regionId && a.brandId) m[`${a.regionId}|${a.brandId}`] = u.name;
      });
    });
    return m;
  }, [initial.id]);
  const hasSlot = (regionId, brandId) => assignments.some(a => a.regionId === regionId && a.brandId === brandId);
  function toggleSlot(regionId, brandId) {
    if (takenSlots[`${regionId}|${brandId}`]) return; // boshqaga band — tegmaymiz
    setAssignments(prev => hasSlot(regionId, brandId)
      ? prev.filter(a => !(a.regionId === regionId && a.brandId === brandId))
      : [...prev, { regionId, brandId }]);
  }
  const validUname = /^[a-z0-9_]{3,}$/.test(username.trim().toLowerCase());
  const valid = validUname && name.trim() && (editing || password.length >= 4) &&
    (!assignRequired || assignments.length > 0);

  function submit() {
    if (!valid) return;
    const data = {
      username: username.trim().toLowerCase(),
      name: name.trim(),
      role,
      assignments: canAssign ? assignments : [],
    };
    if (password) data.password = password;
    onSave(data);
  }
  return (
    <Modal onClose={onClose} width={480}>
      <ModalHeader title={editing ? 'Foydalanuvchini tahrirlash' : 'Yangi foydalanuvchi'} onClose={onClose} />
      <div style={{ padding: '20px 22px', display: 'grid', gap: 14, minWidth: 0, flex: 1, minHeight: 0, overflowY: 'auto' }}>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <div><label className="field-label">Login (username)</label>
            <input className="input" value={username} autoFocus placeholder="masalan: toshkent_reg"
              onChange={e => setUsername(e.target.value.toLowerCase().replace(/[^a-z0-9_]/g, ''))} />
            {username && !validUname && <div style={{ fontSize: 11, color: 'var(--st-loading)', marginTop: 4 }}>Kamida 3 ta: kichik harf, raqam, _ (@ va bo'shliq shart emas)</div>}
          </div>
          <div><label className="field-label">Ism familiya</label><input className="input" value={name} onChange={e => setName(e.target.value)} /></div>
        </div>
        <div><label className="field-label">Rol</label>
          <select className="select" value={role} onChange={e => setRole(e.target.value)}>
            {Object.keys(DB.ROLES).map(k => <option key={k} value={k}>{DB.ROLES[k].label}</option>)}
          </select>
        </div>
        {canAssign && (
          <div>
            <label className="field-label">Viloyat + brend uyalari <span style={{ color: 'var(--ink-4)', fontWeight: 400 }}>{assignRequired ? '(kamida bitta uya belgilang)' : '(ixtiyoriy — super menejer uchun)'}</span></label>
            {(DB.REGIONS.length && DB.BRANDS.length) ? (
              <div style={{ maxHeight: 230, overflowY: 'auto', overflowX: 'hidden', border: '1px solid var(--border)', borderRadius: 8, padding: 10, display: 'grid', gap: 10 }}>
                {DB.REGIONS.filter(r => r.active !== false || DB.BRANDS.some(b => hasSlot(r.id, b.id))).map(r => (
                  <div key={r.id} style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap', minWidth: 0 }}>
                    <div style={{ flex: '1 1 110px', minWidth: 0, fontSize: 13, fontWeight: 600, color: 'var(--ink-2)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{r.name}</div>
                    <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', minWidth: 0 }}>
                      {DB.BRANDS.map(b => {
                        const on = hasSlot(r.id, b.id);
                        const owner = takenSlots[`${r.id}|${b.id}`];
                        const disabled = !!owner;
                        return (
                          <button key={b.id} type="button" disabled={disabled}
                            onClick={() => toggleSlot(r.id, b.id)}
                            title={disabled ? `Band: ${owner}` : (on ? 'Bekor qilish' : `${b.name} biriktirish`)}
                            style={{ padding: '5px 10px', borderRadius: 7, fontSize: 12, fontWeight: 700, maxWidth: '100%',
                                     display: 'inline-flex', alignItems: 'center', gap: 4, minWidth: 0,
                                     border: '1px solid ' + (on ? 'var(--brand)' : 'var(--border)'),
                                     background: on ? 'var(--brand)' : (disabled ? 'var(--bg-2)' : 'var(--surface)'),
                                     color: on ? '#fff' : (disabled ? 'var(--ink-4)' : 'var(--ink-2)'),
                                     cursor: disabled ? 'not-allowed' : 'pointer', opacity: disabled ? 0.6 : 1 }}>
                            <span style={{ flex: 'none' }}>{b.name}</span>
                            {disabled && <span style={{ minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', fontWeight: 600, opacity: .85 }}>· {owner}</span>}
                          </button>
                        );
                      })}
                    </div>
                  </div>
                ))}
              </div>
            ) : <div style={{ fontSize: 12, color: 'var(--st-loading)', padding: '9px 0' }}>Avval viloyat va brend qo'shing</div>}
            <div style={{ fontSize: 11, color: 'var(--ink-4)', marginTop: 5 }}>
              Bitta viloyatni bir nechta menejerga (har biriga boshqa brend) berish mumkin. Boshqa menejerга band uyalar kulrang.
            </div>
            {assignRequired && DB.REGIONS.length > 0 && assignments.length === 0 &&
              <div style={{ fontSize: 11, color: 'var(--st-loading)', marginTop: 5 }}>Kamida bitta viloyat+brend uyasini tanlang</div>}
          </div>
        )}
        <div><label className="field-label">Parol {editing && <span style={{ color: 'var(--ink-4)', fontWeight: 400 }}>(o'zgartirmaslik uchun bo'sh qoldiring)</span>}</label>
          <input className="input" type="password" value={password} placeholder={editing ? '••••' : 'kamida 4 belgi'} onChange={e => setPassword(e.target.value)} />
        </div>
      </div>
      <ModalFooter onClose={onClose} onSave={submit} disabled={!valid} />
    </Modal>
  );
}
function ModalFooter({ onClose, onSave, disabled }) {
  return (
    <div style={{ padding: '14px 22px', borderTop: '1px solid var(--border)', display: 'flex', gap: 10, justifyContent: 'flex-end' }}>
      <button className="btn btn--ghost" onClick={onClose}>Bekor qilish</button>
      <button className="btn btn--primary" disabled={disabled} onClick={onSave}><Icon name="check" size={16} stroke={2.4} /> Saqlash</button>
    </div>
  );
}

/* ---------- Zavod quvvati ---------- */
// Oylar: Iyul(7)..Dekabr(12)
const FC_MONTHS = [
  { n: 7, label: 'Iyul' }, { n: 8, label: 'Avgust' }, { n: 9, label: 'Sentyabr' },
  { n: 10, label: 'Oktyabr' }, { n: 11, label: 'Noyabr' }, { n: 12, label: 'Dekabr' },
];
function fcRowTotal(row) {
  return FC_MONTHS.reduce((s, m) => {
    const arr = (row.months && row.months[String(m.n)]) || [];
    return s + arr.reduce((a, v) => a + (Number(v) || 0), 0);
  }, 0);
}
function FactoryPanel({ refresh, showToast }) {
  const [modal, setModal] = useState(null);
  const [loading, setLoading] = useState(false);
  async function save(data) {
    try {
      if (modal.id) {
        const { factoryCapacity } = await API.updateFactoryCapacity(modal.id, data);
        const f = DB.FACTORY_CAPACITY.find(x => x.id === modal.id); if (f) Object.assign(f, factoryCapacity);
        showToast('Pozitsiya yangilandi');
      } else {
        const { factoryCapacity } = await API.createFactoryCapacity(data);
        DB.FACTORY_CAPACITY.push(factoryCapacity);
        showToast('Pozitsiya qoʼshildi');
      }
      setModal(null); refresh();
    } catch (ex) { showToast(ex.message || 'Saqlashda xatolik'); }
  }
  async function del(id) {
    if (!confirm('Pozitsiyani oʼchirishni tasdiqlaysizmi?')) return;
    try {
      await API.deleteFactoryCapacity(id);
      const i = DB.FACTORY_CAPACITY.findIndex(x => x.id === id); if (i >= 0) DB.FACTORY_CAPACITY.splice(i, 1);
      showToast('Pozitsiya oʼchirildi'); refresh();
    } catch (ex) { showToast(ex.message || 'Oʼchirishda xatolik'); }
  }
  const fmt = (n) => Number(n || 0).toLocaleString('ru-RU').replace(/,/g, ' ');
  return (
    <>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 14, gap: 10, flexWrap: 'wrap' }}>
        <span style={{ fontWeight: 700, fontSize: 14.5 }}>Zavod quvvati (oylik ishlab chiqarish)</span>
        <div style={{ display: 'flex', gap: 8 }}>
          <button className="btn btn--primary btn--sm" onClick={() => setModal({ name: '', productIds: [], months: {} })}>
            <Icon name="plus" size={15} stroke={2.4} /> Pozitsiya qo'shish
          </button>
        </div>
      </div>
      <p style={{ fontSize: 12, color: 'var(--ink-4)', margin: '-4px 0 14px' }}>
        O'lchov birligi — karobka. Har pozitsiyani mahsulotga biriktiring; summa avtomatik = karobka × mahsulot narxi.
      </p>
      {DB.FACTORY_CAPACITY.length === 0 ? (
        <Card><div style={{ padding: '28px 16px', textAlign: 'center', color: 'var(--ink-4)', fontSize: 13 }}>
          Hozircha pozitsiya yo'q. «Pozitsiya qo'shish» tugmasi orqali birinchi pozitsiyani kiriting.
        </div></Card>
      ) : (
        <Card>
          {DB.FACTORY_CAPACITY.map((f, i) => {
            const prodIds = (f.productIds && f.productIds.length) ? f.productIds : (f.productId ? [f.productId] : []);
            const products = prodIds.map((id) => DB.PRODUCT_BY_ID[id]).filter(Boolean);
            const prices = products.map((p) => Number(p.price || 0));
            const avgPrice = prices.length ? Math.round(prices.reduce((a, b) => a + b, 0) / prices.length) : 0;
            const total = fcRowTotal(f);
            const multi = products.length > 1;
            return (
              <Row key={f.id} last={i === DB.FACTORY_CAPACITY.length - 1}>
                <span style={{ width: 30, height: 30, borderRadius: 8, background: 'var(--brand-tint)', color: 'var(--brand-700)', display: 'grid', placeItems: 'center' }}><Icon name="box" size={15} /></span>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontWeight: 700, fontSize: 13.5 }}>{f.name}</div>
                  <div style={{ fontSize: 11.5, color: products.length ? 'var(--ink-4)' : '#C2453A', marginTop: 2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                    {products.length
                      ? ((multi ? 'Mahsulotlar: ' : 'Mahsulot: ') + products.map((p) => p.name).join(', ') + (avgPrice ? ' · ' + (multi ? "o'rtacha narx " : 'narx ') + fmt(avgPrice) : ''))
                      : 'Mahsulot biriktirilmagan'}
                  </div>
                </div>
                <span className="chip" title="Yarim yillik jami (Iyul–Dekabr)">{fmt(total)} krb</span>
                <RowActions onEdit={() => setModal({ id: f.id, name: f.name, productIds: prodIds, months: f.months || {} })} onDelete={() => del(f.id)} />
              </Row>
            );
          })}
        </Card>
      )}
      {modal && <FactoryModal initial={modal} onClose={() => setModal(null)} onSave={save} />}
    </>
  );
}
function FactoryModal({ initial, onClose, onSave }) {
  const [name, setName] = useState(initial.name || '');
  const [productIds, setProductIds] = useState(() => {
    if (Array.isArray(initial.productIds) && initial.productIds.length) return initial.productIds.slice();
    return initial.productId ? [initial.productId] : [];
  });
  function addProduct(id) { if (id && !productIds.includes(id)) setProductIds((a) => [...a, id]); }
  function removeProduct(id) { setProductIds((a) => a.filter((x) => x !== id)); }
  const [pickOpen, setPickOpen] = useState(false);
  // months state: { "7": [w1,w2,w3,w4], ... } — har doim 4 hafta
  const [months, setMonths] = useState(() => {
    const out = {};
    FC_MONTHS.forEach(m => {
      const arr = (initial.months && initial.months[String(m.n)]) || [];
      out[m.n] = [0, 1, 2, 3].map(i => Number(arr[i] || 0));
    });
    return out;
  });
  function setWeek(n, wi, val) {
    const v = Math.max(0, Math.floor(Number(val) || 0));
    setMonths(prev => {
      const next = Object.assign({}, prev);
      const arr = next[n].slice(); arr[wi] = v; next[n] = arr;
      return next;
    });
  }
  const selProducts = productIds.map((id) => DB.PRODUCT_BY_ID[id]).filter(Boolean);
  const selPrices = selProducts.map((p) => Number(p.price || 0));
  const price = selPrices.length ? Math.round(selPrices.reduce((a, b) => a + b, 0) / selPrices.length) : 0;
  const multi = selProducts.length > 1;
  const monthTotal = (n) => months[n].reduce((s, v) => s + v, 0);
  const grand = FC_MONTHS.reduce((s, m) => s + monthTotal(m.n), 0);
  const fmt = (n) => Number(n || 0).toLocaleString('ru-RU').replace(/,/g, ' ');
  function submit() {
    if (!name.trim()) return;
    // bo'sh oylarni ham yuboramiz (4 hafta massiv); backend monthsJson saqlaydi
    const out = {};
    FC_MONTHS.forEach(m => { out[m.n] = months[m.n]; });
    onSave({ name: name.trim(), productIds: productIds.slice(), months: out });
  }
  return (
    <Modal onClose={onClose} width={640}>
      <ModalHeader title={initial.id ? 'Pozitsiyani tahrirlash' : 'Yangi pozitsiya'} onClose={onClose} />
      <div style={{ padding: '20px 22px', display: 'grid', gap: 14, maxHeight: '70vh', overflowY: 'auto' }}>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <div><label className="field-label">Nomi</label>
            <input className="input" value={name} autoFocus placeholder="masalan: Mahsulot 150 g" onChange={e => setName(e.target.value)} /></div>
          <div><label className="field-label">Mahsulotlar (narx uchun)</label>
            <div style={{ position: 'relative' }}>
              <button type="button" className="select" onClick={() => setPickOpen(o => !o)}
                style={{ width: '100%', textAlign: 'left', display: 'flex', alignItems: 'center', justifyContent: 'space-between', cursor: 'pointer' }}>
                <span style={{ color: 'var(--ink-4)' }}>+ mahsulot qo'shish…</span>
                <Icon name="chevD" size={15} style={{ color: 'var(--ink-4)' }} />
              </button>
              {pickOpen && (
                <>
                  <div onClick={() => setPickOpen(false)} style={{ position: 'fixed', inset: 0, zIndex: 60 }} />
                  <div style={{ position: 'absolute', top: 'calc(100% + 4px)', left: 0, right: 0, zIndex: 61, maxHeight: 280, overflowY: 'auto', background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 10, boxShadow: '0 10px 30px rgba(0,0,0,.16)' }}>
                    {(() => {
                      const avail = DB.PRODUCTS.filter(p => !productIds.includes(p.id));
                      if (!avail.length) return <div style={{ padding: 12, fontSize: 12, color: 'var(--ink-4)' }}>Hammasi qo'shilgan</div>;
                      return avail.map(p => {
                        const cn = DB.categoryName(p.cat);
                        const bn = (DB.brandOfProduct(p.id) || {}).name || '';
                        const sub = [bn, cn].filter(Boolean).join(' · ');
                        return (
                          <button key={p.id} type="button" onClick={() => { addProduct(p.id); setPickOpen(false); }}
                            style={{ display: 'block', width: '100%', textAlign: 'left', padding: '8px 12px', border: 'none', borderBottom: '1px solid var(--border)', background: 'transparent', cursor: 'pointer' }}>
                            <div style={{ fontWeight: 700, fontSize: 13, color: 'var(--ink)' }}>{p.name}</div>
                            {sub && <div style={{ fontSize: 11, color: 'var(--ink-4)', textTransform: 'uppercase', letterSpacing: 0.4, marginTop: 1 }}>{sub}</div>}
                          </button>
                        );
                      });
                    })()}
                  </div>
                </>
              )}
            </div>
            {selProducts.length > 0 && (
              <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginTop: 8 }}>
                {selProducts.map(p => {
                  const cn = DB.categoryName(p.cat);
                  const bn = (DB.brandOfProduct(p.id) || {}).name || '';
                  const sub = [bn, cn].filter(Boolean).join(' · ');
                  return (
                  <span key={p.id} style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 12, padding: '4px 8px 4px 10px', borderRadius: 999, background: 'var(--brand-tint)', color: 'var(--brand-700)', fontWeight: 600 }}>
                    {p.name}{sub ? ' · ' + sub : ''}
                    <button type="button" onClick={() => removeProduct(p.id)} title="Olib tashlash" style={{ display: 'inline-flex', border: 'none', background: 'transparent', color: 'inherit', cursor: 'pointer', padding: 0, lineHeight: 1 }}><Icon name="x" size={13} /></button>
                  </span>
                  );
                })}
              </div>
            )}
            {selProducts.length > 0 && <div style={{ fontSize: 11, color: 'var(--ink-4)', marginTop: 6 }}>{multi ? "O'rtacha narx" : 'Narx'}: {fmt(price)} so'm{multi ? ' · ' + selProducts.length + ' ta mahsulot' : ''}</div>}
          </div>
        </div>
        <div>
          <label className="field-label">Haftalik ishlab chiqarish (karobka)</label>
          <div style={{ overflowX: 'auto', border: '1px solid var(--border)', borderRadius: 8 }}>
            <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12.5, minWidth: 560 }}>
              <thead>
                <tr style={{ color: 'var(--ink-4)', fontSize: 11, textTransform: 'uppercase' }}>
                  <th style={{ textAlign: 'left', padding: '8px 12px', fontWeight: 600 }}>Oy</th>
                  <th style={{ padding: '8px 6px', fontWeight: 600 }}>1-h.</th>
                  <th style={{ padding: '8px 6px', fontWeight: 600 }}>2-h.</th>
                  <th style={{ padding: '8px 6px', fontWeight: 600 }}>3-h.</th>
                  <th style={{ padding: '8px 6px', fontWeight: 600 }}>4-h.</th>
                  <th style={{ padding: '8px 12px', fontWeight: 600, textAlign: 'right' }}>Oylik</th>
                  <th style={{ padding: '8px 12px', fontWeight: 600, textAlign: 'right' }}>Summa</th>
                </tr>
              </thead>
              <tbody>
                {FC_MONTHS.map(m => (
                  <tr key={m.n} style={{ borderTop: '1px solid var(--border)' }}>
                    <td style={{ padding: '6px 12px', fontWeight: 600 }}>{m.label}</td>
                    {[0, 1, 2, 3].map(wi => (
                      <td key={wi} style={{ padding: '4px 6px' }}>
                        <input className="input" type="number" min="0" value={months[m.n][wi]}
                          onChange={e => setWeek(m.n, wi, e.target.value)}
                          style={{ width: 70, padding: '6px 8px', textAlign: 'right' }} />
                      </td>
                    ))}
                    <td className="tnum" style={{ padding: '6px 12px', textAlign: 'right', fontWeight: 700 }}>{fmt(monthTotal(m.n))}</td>
                    <td className="tnum" style={{ padding: '6px 12px', textAlign: 'right', color: 'var(--brand-700)' }}>{price ? fmt(monthTotal(m.n) * price) : '—'}</td>
                  </tr>
                ))}
              </tbody>
              <tfoot>
                <tr style={{ borderTop: '2px solid var(--border)' }}>
                  <td style={{ padding: '8px 12px', fontWeight: 700 }}>Jami</td>
                  <td colSpan={4}></td>
                  <td className="tnum" style={{ padding: '8px 12px', textAlign: 'right', fontWeight: 700 }}>{fmt(grand)}</td>
                  <td className="tnum" style={{ padding: '8px 12px', textAlign: 'right', fontWeight: 700, color: 'var(--brand-700)' }}>{price ? fmt(grand * price) : '—'}</td>
                </tr>
              </tfoot>
            </table>
          </div>
        </div>
      </div>
      <ModalFooter onClose={onClose} onSave={submit} disabled={!name.trim()} />
    </Modal>
  );
}

/* ============================================================
   Sell-Out admin paneli (Iyul 2026+)
   — Oy sozlamalari (ish kunlari)
   — SKU katalogi (narxlar, birlik)
   — Hududlar va distributorlar (plan, prognoz)
   ============================================================ */
const SO_MONTH_OPTS = [
  { key: '2026-07', label: 'Iyul 2026' },
  { key: '2026-08', label: 'Avgust 2026' },
  { key: '2026-09', label: 'Sentyabr 2026' },
  { key: '2026-10', label: 'Oktyabr 2026' },
  { key: '2026-11', label: 'Noyabr 2026' },
  { key: '2026-12', label: 'Dekabr 2026' },
];

function SelloutPanel({ showToast }) {
  const [month, setMonth]         = useState('2026-07');
  const [settings, setSettings]   = useState(null);
  const [skus, setSkus]           = useState([]);
  const [regions, setRegions]     = useState([]);
  const [tw, setTw]               = useState('');
  const [pw, setPw]               = useState('');
  const [saving, setSaving]       = useState(false);
  const [loading, setLoading]     = useState(true);

  async function load(m) {
    setLoading(true);
    try {
      const [s, sk, reg] = await Promise.all([
        API.soSettings(m),
        API.soSkus(),
        API.soRegions(),
      ]);
      setSettings(s.settings);
      setTw(String(s.settings.totalWorkdays));
      setPw(String(s.settings.passedWorkdays));
      setSkus(sk.skus || []);
      setRegions(reg.regions || []);
    } catch (e) { showToast(e.message || 'Yuklab bo\'lmadi'); }
    finally { setLoading(false); }
  }

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

  async function saveSettings() {
    setSaving(true);
    try {
      await API.soUpdateSettings({ month, totalWorkdays: parseInt(tw), passedWorkdays: parseInt(pw) });
      showToast('Sozlamalar saqlandi');
      load(month);
    } catch (e) { showToast(e.message || 'Xatolik'); }
    finally { setSaving(false); }
  }

  const fmtSom = (v) => Number(v || 0).toLocaleString('ru-RU').replace(/,/g, ' ');

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>
      {/* Oy tanlash */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>
        <span style={{ fontWeight: 700, fontSize: 14 }}>Sell-Out (Iyul 2026+)</span>
        <select className="select" value={month} onChange={(e) => setMonth(e.target.value)} style={{ height: 36, width: 160 }}>
          {SO_MONTH_OPTS.map((m) => <option key={m.key} value={m.key}>{m.label}</option>)}
        </select>
      </div>

      {loading && <div style={{ color: 'var(--ink-4)', fontSize: 13 }}>Yuklanmoqda…</div>}

      {!loading && (
        <>
          {/* Oy sozlamalari */}
          <div style={{ background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 'var(--r-lg)', padding: 18 }}>
            <div style={{ fontWeight: 700, fontSize: 13.5, marginBottom: 14 }}>Ish kunlari</div>
            <div style={{ display: 'flex', gap: 16, flexWrap: 'wrap', alignItems: 'flex-end' }}>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 5 }}>
                <label style={{ fontSize: 11.5, color: 'var(--ink-4)', fontWeight: 600 }}>JAMI ISH KUNLARI</label>
                <input className="input tnum" type="number" min="1" max="31" value={tw} onChange={(e) => setTw(e.target.value)}
                  style={{ width: 100, height: 36, textAlign: 'center' }} />
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 5 }}>
                <label style={{ fontSize: 11.5, color: 'var(--ink-4)', fontWeight: 600 }}>O'TGAN ISH KUNLARI</label>
                <input className="input tnum" type="number" min="0" value={pw} onChange={(e) => setPw(e.target.value)}
                  style={{ width: 100, height: 36, textAlign: 'center' }} />
              </div>
              <button className="btn btn--primary" style={{ height: 36 }} disabled={saving} onClick={saveSettings}>
                {saving ? 'Saqlanmoqda…' : 'Saqlash'}
              </button>
            </div>
            {settings && (
              <div style={{ marginTop: 10, fontSize: 12, color: 'var(--ink-4)' }}>
                Qolgan ish kunlari: <b>{settings.totalWorkdays - settings.passedWorkdays}</b>
              </div>
            )}
          </div>

          {/* SKU katalogi */}
          <div style={{ background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 'var(--r-lg)', padding: 18 }}>
            <div style={{ fontWeight: 700, fontSize: 13.5, marginBottom: 14 }}>SKU katalogi (narxlar)</div>
            <div style={{ overflowX: 'auto' }}>
              <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12.5 }}>
                <thead>
                  <tr style={{ borderBottom: '1px solid var(--border)', color: 'var(--ink-4)', fontSize: 11, textTransform: 'uppercase' }}>
                    <th style={{ textAlign: 'left', padding: '6px 10px' }}>Brend</th>
                    <th style={{ textAlign: 'left', padding: '6px 10px' }}>SKU</th>
                    <th style={{ textAlign: 'center', padding: '6px 10px' }}>Birlik</th>
                    <th style={{ textAlign: 'right', padding: '6px 10px' }}>1 karobkada</th>
                    <th style={{ textAlign: 'right', padding: '6px 10px' }}>Karobka narxi</th>
                    <th style={{ textAlign: 'right', padding: '6px 10px' }}>Birlik narxi</th>
                  </tr>
                </thead>
                <tbody>
                  {skus.map((s) => (
                    <tr key={s.id} style={{ borderBottom: '1px solid var(--border)' }}>
                      <td style={{ padding: '8px 10px' }}>
                        <span style={{ color: (DB.brandByTag(s.brand) && DB.brandByTag(s.brand).color) || 'var(--ink-3)', fontWeight: 700, fontSize: 11 }}>{s.brand}</span>
                      </td>
                      <td style={{ padding: '8px 10px', fontWeight: 600 }}>{s.name}</td>
                      <td style={{ padding: '8px 10px', textAlign: 'center', color: 'var(--ink-3)' }}>{s.inputUnit}</td>
                      <td className="tnum" style={{ padding: '8px 10px', textAlign: 'right' }}>{s.unitsPerCarton}</td>
                      <td className="tnum" style={{ padding: '8px 10px', textAlign: 'right' }}>{fmtSom(s.cartonPrice)}</td>
                      <td className="tnum" style={{ padding: '8px 10px', textAlign: 'right', color: 'var(--ink-3)' }}>{fmtSom(s.unitPrice)}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </div>

          {/* Hududlar va distributorlar */}
          <div style={{ background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 'var(--r-lg)', padding: 18 }}>
            <div style={{ fontWeight: 700, fontSize: 13.5, marginBottom: 14 }}>
              Hududlar va distributorlar
              <span style={{ marginLeft: 8, fontSize: 11.5, fontWeight: 400, color: 'var(--ink-4)' }}>
                {regions.length} hudud · {regions.reduce((s, r) => s + (r.distributors || []).length, 0)} distributor
              </span>
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              {regions.map((reg) => (
                <div key={reg.id} style={{ border: '1px solid var(--border)', borderRadius: 10, overflow: 'hidden' }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '10px 14px', background: 'var(--bg-2,rgba(0,0,0,.03))', fontWeight: 700, fontSize: 13 }}>
                    <span style={{ color: 'var(--ink-4)', fontSize: 11, minWidth: 20 }}>#{reg.sortOrder}</span>
                    {reg.name}
                    <span style={{ marginLeft: 'auto', fontSize: 11.5, fontWeight: 400, color: 'var(--ink-4)' }}>
                      Jami plan: {fmtSom(reg.distributors.reduce((s, d) => s + (d.planSom || 0), 0))} so'm
                    </span>
                  </div>
                  {(reg.distributors || []).map((d) => (
                    <div key={d.id} style={{ display: 'flex', alignItems: 'center', gap: 14, padding: '8px 14px 8px 44px', borderTop: '1px solid var(--border)', fontSize: 12.5 }}>
                      <span style={{ flex: 1 }}>{d.name}</span>
                      <span className="tnum" style={{ color: 'var(--ink-3)' }}>Plan: {fmtSom(d.planSom)} so'm</span>
                    </div>
                  ))}
                </div>
              ))}
            </div>
          </div>
        </>
      )}
    </div>
  );
}

window.Settings = Settings;
