/* ============================================================
   Asosiy ilova — navigatsiya, rollar, holat
   ============================================================ */
/* ---------- Navigatsiya bo'limlari (rail + pastki tablar uchun umumiy) ---------- */
function buildNavItems({ user, perms, isSuper }) {
  // Storecheck — super admin yoki viloyatga biriktirilgan regional menejer
  const canStorecheck = isSuper || (DB.userRegionIds ? (DB.userRegionIds(user.id) || []).length > 0 : false);
  // Menyudan VAQTINCHA yashiringan bo'limlar (o'chmaydi — kod/route/ma'lumot saqlanadi).
  // Qayta chiqarish: shu ro'yxatdan kalitni olib tashlash kifoya.
  const HIDDEN_NAV = ['distributors', 'targets', 'outlets'];
  return [
    ...(perms.viewDashboard !== false ? [{ key: 'dashboard', label: 'Dashboard', icon: 'chart' }] : []),
    ...(perms.viewAi !== false ? [{ key: 'ai', label: 'AI Insights', icon: 'sparkle' }] : []),
    ...(perms.viewPlanfakt !== false ? [{ key: 'planfakt', label: 'SELL IN', icon: 'grid' }] : []),
    ...(perms.viewRegion !== false ? [{ key: 'region', label: 'SELL OUT', icon: 'trendUp' }] : []),
    { key: 'distributors', label: 'Distributorlar', icon: 'user' },
    { key: 'targets', label: 'Reja', icon: 'coin' },
    { key: 'outlets', label: "Do'konlar", icon: 'pin' },
    ...(perms.viewBoard !== false ? [{ key: 'board', label: 'Zakazlar', icon: 'board' }] : []),
    ...(perms.taskView ? [{ key: 'tasks', label: 'Tasklar', icon: 'tasks' }] : []),
    ...(perms.viewSalesdoc !== false ? [{ key: 'salesdoc', label: 'Distributsiya', icon: 'chart' }] : []),
    ...(perms.viewChecklist !== false ? [{ key: 'checklist', label: 'Cheklist', icon: 'check' }] : []),
    ...(perms.viewFactory !== false ? [{ key: 'factory', label: 'Zavod quvvati', icon: 'box' }] : []),
    ...(canStorecheck && perms.viewStorecheck !== false ? [{ key: 'storecheck', label: 'Storecheck', icon: 'pin' }] : []),
    ...(isSuper && perms.viewMaosh !== false ? [{ key: 'maosh', label: 'Maosh', icon: 'coin' }] : []),
    ...(isSuper && perms.viewRecruiting !== false ? [{ key: 'recruiting', label: 'Ishga olish', icon: 'users' }] : []),
    ...(isSuper && perms.viewHr !== false ? [{ key: 'hr', label: 'Davomat', icon: 'clock' }] : []),
    ...(isSuper && perms.viewLog !== false ? [{ key: 'log', label: 'Tarix', icon: 'clock' }] : []),
    { key: 'settings', label: 'Sozlamalar', icon: 'gear' },
  ].filter((t) => !HIDDEN_NAV.includes(t.key));
}

/* ---------- Chap suzuvchi ikonka paneli (Glassy rail) ---------- */
function GlassRail({ items, view, pick, drawer }) {
  const [tip, setTip] = useState(null);
  const show = (e, label) => {
    if (drawer) return;
    const r = e.currentTarget.getBoundingClientRect();
    setTip({ label, x: r.right + 10, y: r.top + r.height / 2 });
  };
  const main = items.filter(t => t.key !== 'settings');
  const settings = items.find(t => t.key === 'settings');
  const railRef = useRef(null);
  const box = useSlider(railRef, view, 'y');
  const btn = (t) => (
    <button key={t.key} data-k={t.key} className={'gx-rail__btn' + (view === t.key ? ' on' : '')} aria-label={t.label}
      onClick={() => { setTip(null); pick(t.key); }} onMouseEnter={(e) => show(e, t.label)} onMouseLeave={() => setTip(null)}>
      <Icon name={t.icon} size={drawer ? 17 : 18} stroke={1.9} />
      {drawer && <span>{t.label}</span>}
    </button>
  );
  return (
    <>
      <nav ref={railRef} className={'gx-rail glass' + (drawer ? ' gx-rail--drawer' : '')}>
        {box && <span className="gx-slide gx-slide--rail" style={{ transform: 'translate(' + box.x + 'px,' + box.y + 'px)', width: box.w, height: box.h }} />}
        {main.map(btn)}
        {settings && <div className="gx-rail__sep" />}
        {settings && btn(settings)}
      </nav>
      {tip && <div className="gx-tip" style={{ left: tip.x, top: tip.y }}>{tip.label}</div>}
    </>
  );
}

/* ---------- Tepadagi shisha panel ---------- */
function GlassTopBar({ user, role, isMobile, onMenu, onProfile, onAsk, canAsk, onLogout }) {
  const [dark, setDark] = useState(() => document.documentElement.getAttribute('data-theme') === 'dark');
  const toggleTheme = () => {
    window.Theme.set({ mode: dark ? 'light' : 'dark' });
    setDark(!dark);
  };
  const first = String(user.name || '').split(' ')[0];
  return (
    <header className="gx-top glass">
      {isMobile && (
        <button className="gx-round gx-round--ghost" onClick={onMenu} aria-label="Menyu"><Icon name="menu" size={18} /></button>
      )}
      <div className="gx-top__hello">
        <button onClick={onProfile} aria-label="Profil" title="Profil"
          style={{ border: 'none', background: 'transparent', padding: 0, cursor: 'pointer', flex: 'none', borderRadius: '50%' }}>
          <Avatar src={user.avatar} name={user.name} size={34} radius={17} accent={role && role.super} />
        </button>
        <span>Xush kelibsiz, {first}</span>
      </div>
      {canAsk && !isMobile ? (
        <button className="gx-ask" onClick={onAsk}>
          <span className="gx-orb" />
          <span style={{ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}><Typewriter text="AI'dan so'rang: qaysi hudud rejadan orqada qolyapti?" /></span>
        </button>
      ) : <div style={{ flex: 1 }} />}
      <button className="gx-round gx-round--ghost" onClick={toggleTheme} title={dark ? "Yorug' rejim" : "Qorong'i rejim"} aria-label="Rejim">
        <Icon name={dark ? 'sun' : 'moon'} size={17} />
      </button>
      <button className="gx-round" onClick={onLogout} title="Chiqish" aria-label="Chiqish"><Icon name="logout" size={16} /></button>
    </header>
  );
}

/* ---------- Pastki pill tab bar ---------- */
/* Faol elementga sirpanib boruvchi indikator (tab bar va rail uchun umumiy) */
function useSlider(containerRef, activeKey, axis) {
  const [box, setBox] = useState(null);
  useLayoutEffect(() => {
    const measure = () => {
      const c = containerRef.current; if (!c) return;
      const el = c.querySelector('[data-k="' + activeKey + '"]');
      if (!el) { setBox(null); return; }
      setBox({ x: el.offsetLeft, y: el.offsetTop, w: el.offsetWidth, h: el.offsetHeight });
    };
    measure();
    window.addEventListener('resize', measure);
    return () => window.removeEventListener('resize', measure);
  }, [activeKey, axis]);
  return box;
}

function GlassTabs({ items, view, pick, onAdd }) {
  const PRIMARY = ['dashboard', 'board', 'tasks', 'planfakt', 'region', 'salesdoc', 'ai'];
  const tabs = PRIMARY.map(k => items.find(t => t.key === k)).filter(Boolean);
  const ref = useRef(null);
  const box = useSlider(ref, view, 'x');
  if (!tabs.length && !onAdd) return null;
  return (
    <div className="gx-tabs-wrap">
      <div className="gx-tabs glass" ref={ref}>
        {box && <span className="gx-slide gx-slide--tab" style={{ transform: 'translate(' + box.x + 'px,' + box.y + 'px)', width: box.w, height: box.h }} />}
        {tabs.map(t => (
          <button key={t.key} data-k={t.key} className={'gx-tab' + (view === t.key ? ' on' : '')} onClick={() => pick(t.key)}>{t.label}</button>
        ))}
        {onAdd && (
          <button className="gx-round" onClick={onAdd} title="Yangi zakaz" aria-label="Yangi zakaz"><Icon name="plus" size={16} stroke={2.4} /></button>
        )}
      </div>
    </div>
  );
}

function greetingWord() {
  const h = new Date().getHours();
  if (h < 5) return 'Xayrli tun';
  if (h < 12) return 'Xayrli tong';
  if (h < 18) return 'Xayrli kun';
  return 'Xayrli kech';
}

function BoardToolbar({ search, setSearch, regionFilter, setRegionFilter, sortBy, setSortBy, count, perms, onAdd, user }) {
  // Regional menejer faqat o'z viloyatlarini ko'radi
  const myRegions = (user && user.regions) || [];
  // Faqat AKTIV (joriy oy) hududlar — tanlangan filtr arxiv bo'lsa ham qoladi.
  const regionBase = myRegions.length ? DB.REGIONS.filter(r => myRegions.includes(r.id)) : DB.REGIONS;
  const regionOpts = regionBase.filter(r => r.active !== false || r.id === regionFilter);
  return (
    <div className="board-toolbar" style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '14px 22px 12px' }}>
      <div>
        <h2 style={{ fontSize: 18, fontWeight: 800, letterSpacing: '-.02em', margin: 0 }}>Zakazlar doskasi</h2>
        <div style={{ fontSize: 12, color: 'var(--ink-4)', marginTop: 2 }}>{count} ta faol zakaz</div>
      </div>
      <div style={{ flex: 1 }} />
      <div className="bt-search" style={{ position: 'relative' }}>
        <span style={{ position: 'absolute', left: 11, top: '50%', transform: 'translateY(-50%)', color: 'var(--ink-4)' }}><Icon name="search" size={15} /></span>
        <input className="input" style={{ paddingLeft: 33, width: 230, height: 38 }} placeholder="Diller yoki kod bo'yicha…" value={search} onChange={e => setSearch(e.target.value)} />
      </div>
      <select className="select bt-region" value={regionFilter} onChange={e => setRegionFilter(e.target.value)} style={{ width: 180, height: 38 }}>
        <option value="all">{myRegions.length ? 'Barcha viloyatlarim' : 'Barcha viloyatlar'}</option>
        {regionOpts.map(r => <option key={r.id} value={r.id}>{r.name}</option>)}
      </select>
      {setSortBy && (
        <select className="select bt-sort" value={sortBy} onChange={e => setSortBy(e.target.value)} style={{ width: 150, height: 38 }}
          title="Saralash (Rejalangan ustunga ta'sir qilmaydi)">
          <option value="az">Nomi: A–Z</option>
          <option value="za">Nomi: Z–A</option>
          <option value="date">Sana bo'yicha</option>
        </select>
      )}
      {perms.addOrder && (
        <button className="btn btn--primary bt-add" style={{ height: 38 }} onClick={onAdd}><Icon name="plus" size={16} stroke={2.4} /> Yangi zakaz</button>
      )}
    </div>
  );
}

/* ---------- Profil (har bir user o'z rasmini yangilaydi) ---------- */
function ProfileModal({ user, onClose, onSaved, showToast }) {
  const role = DB.ROLES[user.role];
  const [avatar, setAvatar] = useState(user.avatar || 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 { setAvatar(await fileToDataURL(file, 256, 'image/jpeg', 0.85)); }
    catch (ex) { showToast(ex.message || 'Rasmni yuklab boʻlmadi'); }
  }
  async function save() {
    setBusy(true);
    try {
      const { user: u } = await API.updateMyAvatar(avatar);
      onSaved(u);
      showToast('Rasm yangilandi');
      onClose();
    } catch (ex) { showToast(ex.message || 'Saqlashda xatolik'); }
    finally { setBusy(false); }
  }

  const unchanged = (avatar || null) === (user.avatar || null);
  return (
    <Modal onClose={onClose} width={420}>
      <ModalHeader title="Mening profilim" subtitle={user.name + ' · ' + role.label} onClose={onClose} />
      <div style={{ padding: '24px 22px', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 16 }}>
        <Avatar src={avatar} name={user.name} size={112} radius={22} accent={role.super} />
        <input ref={fileRef} type="file" accept="image/*" style={{ display: 'none' }} onChange={pick} />
        <div style={{ display: 'flex', gap: 10 }}>
          <button className="btn btn--ghost" onClick={() => fileRef.current && fileRef.current.click()}>
            <Icon name="upload" size={15} /> Rasm tanlash
          </button>
          {avatar && (
            <button className="btn btn--ghost" style={{ color: '#C2453A' }} onClick={() => setAvatar(null)}>
              <Icon name="trash" size={15} /> O'chirish
            </button>
          )}
        </div>
        <div style={{ fontSize: 11.5, color: 'var(--ink-4)', textAlign: 'center' }}>JPG yoki PNG · kvadrat rasm tavsiya etiladi</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={busy || unchanged} onClick={save}>
          <Icon name="check" size={16} stroke={2.4} /> Saqlash
        </button>
      </div>
    </Modal>
  );
}

/* ---------- Klient routing (har bo'limga alohida URL) ---------- */
const ROUTE_VIEWS = ['dashboard', 'board', 'tasks', 'distributors', 'targets', 'outlets', 'storecheck', 'maosh', 'recruiting', 'hr', 'log', 'settings', 'checklist', 'salesdoc', 'region', 'planfakt', 'ai', 'factory'];
function pathToView(pathname) {
  const seg = (pathname || '/').replace(/^\/+|\/+$/g, '').split('/')[0];
  return ROUTE_VIEWS.includes(seg) ? seg : 'board';
}

function App() {
  const [user, setUser] = useState(null);
  const [booting, setBooting] = useState(true); // sessiyani tiklash tugaguncha
  const [view, setViewState] = useState(() => pathToView(typeof window !== 'undefined' ? window.location.pathname : '/'));
  const navigate = useCallback((key) => {
    setViewState(key);
    const target = '/' + key;
    if (window.location.pathname !== target) window.history.pushState({ view: key }, '', target);
  }, []);
  const setView = navigate; // bolalar komponentlari setView chaqirsa ham URL yangilanadi
  const isMobile = useIsMobile();
  const [navOpen, setNavOpen] = useState(true);
  const [orders, setOrders] = useState([]);
  const [taskLists, setTaskLists] = useState([]);
  const [tasks, setTasks] = useState([]);
  const [toast, setToast] = useState(null);
  const [form, setForm] = useState(null); // {initial} | {} for new
  const [profileOpen, setProfileOpen] = useState(false);
  const [search, setSearch] = useState('');
  const [regionFilter, setRegionFilter] = useState('all');
  const [sortBy, setSortBy] = useState('az'); // az | za | date — Rejalangan ustunga ta'sir qilmaydi
  const [log, setLog] = useState([]);

  const perms = user ? DB.ROLES[user.role].perms : {};
  const role = user ? DB.ROLES[user.role] : null;
  const showToast = useCallback((msg) => setToast({ msg, k: Date.now() }), []);

  // Joriy bo'lim ruxsati o'chirilgan bo'lsa — birinchi ochiq bo'limga o'tamiz
  useEffect(() => {
    if (!user || !role) return;
    const sup = !!role.super;
    const allowed = {
      dashboard: perms.viewDashboard !== false,
      ai: perms.viewAi !== false,
      planfakt: perms.viewPlanfakt !== false,
      region: perms.viewRegion !== false,
      board: perms.viewBoard !== false,
      tasks: !!perms.taskView,
      salesdoc: perms.viewSalesdoc !== false,
      checklist: perms.viewChecklist !== false,
      factory: perms.viewFactory !== false,
      storecheck: perms.viewStorecheck !== false,
      maosh: sup && perms.viewMaosh !== false,
      recruiting: sup && perms.viewRecruiting !== false,
      hr: sup && perms.viewHr !== false,
      log: sup && perms.viewLog !== false,
    };
    if (allowed[view] === false) {
      const first = ['board', 'dashboard', 'tasks', 'salesdoc', 'checklist', 'settings']
        .find((k) => allowed[k] !== false);
      setView(first || 'settings');
    }
  }, [user, role, view, perms]);

  // Prefetch: login'da va har 10 daqiqada barcha bo'lim ma'lumotlarini oldindan yuklaydi.
  // Shunda foydalanuvchi bo'limga o'tsa — ma'lumot allaqachon keshda, "yuklanmoqda" ko'rinmaydi.
  useEffect(() => {
    if (!user || !role) return;
    const sup = !!role.super;
    API.prefetchAll({ super: sup }).catch(() => {});
    const id = setInterval(() => API.prefetchAll({ super: sup }).catch(() => {}), 10 * 60 * 1000);
    return () => clearInterval(id);
  }, [user, role]);

  // Dashboard raqamlari foydalanuvchiga moslanadi: super bo'lmagan (regional) menejer
  // faqat o'zi boshqaradigan viloyat(lar) zakazlarini ko'radi. Tasklar va Zakazlar
  // (doska) esa hamma uchun to'liq qoladi.
  const myRegionIds = useMemo(
    () => (user && role && !role.super ? DB.userRegionIds(user.id) : []),
    [user, role]
  );
  const dashScoped = !!(user && role && !role.super && myRegionIds.length);
  const dashOrders = useMemo(
    () => (dashScoped ? orders.filter(o => myRegionIds.includes(o.region)) : orders),
    [orders, dashScoped, myRegionIds]
  );
  const dashScopeLabel = dashScoped ? myRegionIds.map(id => DB.regionName(id)).join(', ') : null;

  // Token o'rnatilgan holatda DB'ni to'ldirib, foydalanuvchini tizimga kiritamiz.
  // Ham login formasidan, ham refresh'dan keyingi avtomatik tiklashda ishlatiladi.
  // Bootstrap payload'ni (kesh yoki yangi) UI'ga qo'llaydi.
  function applyBoot(userObj, boot) {
    DB.hydrate(boot);
    setOrders((boot.orders || []).map(o => ({ ...o })));
    setTaskLists((boot.taskLists || []).map(l => ({ ...l })));
    setTasks((boot.tasks || []).map(t => ({ ...t })));
    setUser(userObj);
    const ur = userObj.regions || [];
    setRegionFilter(ur.length === 1 ? ur[0] : 'all');
  }

  async function hydrateSession(userObj) {
    // Bootstrap endi SWR keshdan CHIQARILGAN → doim yangi (zakaz + vazifa statuslari
    // eskirmaydi, ko'chirilgan karta refresh'dan keyin joyiga qaytmaydi).
    const boot = await API.bootstrap();
    applyBoot(userObj, boot);
    try { if (window.PageCache) window.PageCache.set('boot', { me: userObj, boot }); } catch (_) {}
    if (DB.ROLES[userObj.role] && DB.ROLES[userObj.role].super) {
      try { const a = await API.audit(); setLog(a.logs || []); } catch (_) {}
    }
  }

  // Login formasidan keyin
  async function login(data) {
    setView('board');
    await hydrateSession(data.user); // {token, user, perms}
  }

  // Sahifa ochilganda/refresh'da: token saqlangan bo'lsa — qayta login so'ramaymiz.
  // Kesh bo'lsa — DARHOL ko'rsatamiz ("yuklanmoqda" ekrani ko'rinmaydi), so'ng fonda yangilaymiz.
  useEffect(() => {
    let alive = true;
    (async () => {
      if (API.isAuthed()) {
        // 1) Keshdagi seansni darhol tiklaymiz
        const cached = window.PageCache ? window.PageCache.get('boot') : null;
        if (cached && cached.me && cached.boot) {
          try { applyBoot(cached.me, cached.boot); setBooting(false); } catch (_) {}
        }
        // 2) Fonda serverdan tekshirib yangilaymiz
        try {
          const { user: me } = await API.me();
          if (alive && me) { await hydrateSession(me); }
        } catch (e) {
          // Faqat token yaroqsiz (401) bo'lsa chiqaramiz; tarmoq xatosida keshdagi qoladi
          if (e && e.status === 401) { API.logout(); if (alive) setUser(null); }
        }
      }
      if (alive) setBooting(false);
    })();
    return () => { alive = false; };
  }, []);

  function logout() { API.logout(); setUser(null); setOrders([]); setTasks([]); setTaskLists([]); setLog([]); setSearch(''); setRegionFilter('all'); setSortBy('az'); setView('board'); }

  // Profil rasmi yangilandi — joriy user + DB.USERS ni sinxron tutamiz
  function applyMyAvatar(u) {
    setUser(u);
    DB.USERS = DB.USERS.map(x => (x.id === u.id ? { ...x, avatar: u.avatar } : x));
  }

  const reloadOrders = useCallback(async () => {
    try { const res = await API.listOrders(); setOrders(res.orders); } catch (_) {}
  }, []);

  const reloadTasks = useCallback(async () => {
    try {
      const [tl, tk] = await Promise.all([API.listTaskLists(), API.listTasks()]);
      DB.TASK_LISTS = tl.taskLists; setTaskLists(tl.taskLists);
      setTasks(tk.tasks);
    } catch (_) {}
  }, []);

  // Tarix ko'rinishiga o'tganda audit'ni serverdan yangilash
  useEffect(() => {
    if (view === 'log' && role && role.super) {
      API.audit().then(a => setLog(a.logs || [])).catch(() => {});
    }
  }, [view]);

  // DB.TASK_LISTS ni React holati bilan sinxron tutamiz (taskCategory/taskListById shundan o'qiydi)
  useEffect(() => { DB.TASK_LISTS = taskLists; }, [taskLists]);

  // Ekran o'lchamiga qarab menyu holatini moslaymiz: telefonда yopiq, desktopда ochiq
  useEffect(() => { setNavOpen(!isMobile); }, [isMobile]);

  // Bo'lim almashganда telefon drawer'ini yopamiz
  useEffect(() => { if (isMobile) setNavOpen(false); }, [view, isMobile]);

  // Brauzer orqaga/oldinga tugmalari — URL bilan ko'rinishni sinxron tutamiz
  useEffect(() => {
    const h = () => setViewState(pathToView(window.location.pathname));
    window.addEventListener('popstate', h);
    return () => window.removeEventListener('popstate', h);
  }, []);

  // URL ruxsat etilmagan bo'limga ishora qilsa — Zakazlar doskasiga qaytaramiz
  useEffect(() => {
    if (!user) return;
    const allowed = {
      dashboard: true,
      region: perms.viewRegion !== false,
      planfakt: perms.viewPlanfakt !== false,
      distributors: true,
      targets: true,
      outlets: true,
      factory: perms.viewFactory !== false,
      ai: perms.viewAi !== false,
      board: true,
      tasks: !!perms.taskView,
      storecheck: !!(role && (role.super || DB.userRegionIds(user.id).length)) && perms.viewStorecheck !== false,
      maosh: !!(role && role.super) && perms.viewMaosh !== false,
      recruiting: !!(role && role.super) && perms.viewRecruiting !== false,
      hr: !!(role && role.super) && perms.viewHr !== false,
      log: !!(role && role.super),
      checklist: perms.viewChecklist !== false,
      salesdoc: perms.viewSalesdoc !== false,
      settings: true, // Sozlamalar hammaga ochiq — ichidagi tablar rol bo'yicha filtrlanadi (Telegram/Ko'rinish har kimga)
    };
    if (!allowed[view]) navigate('board');
  }, [user, view, perms, role, navigate]);

  // Logo o'zgarsa (sozlamalardan) — darhol qayta render qilamiz
  const [, forceBrand] = useState(0);
  useEffect(() => {
    const h = () => forceBrand(n => n + 1);
    window.addEventListener('branding-changed', h);
    return () => window.removeEventListener('branding-changed', h);
  }, []);

  async function saveOrder(data, editing) {
    const payload = {
      distributorId: data.distributorId,
      note: data.note || '',
      // Javobgar menejer (reyting puli shunga yoziladi). undefined bo'lsa yubormaymiz.
      responsibleId: data.responsibleId !== undefined ? data.responsibleId : undefined,
      // Sell In limitini e'tiborsiz qoldirish (faqat super rol). undefined bo'lsa yubormaymiz.
      ignoreLimit: data.ignoreLimit === true ? true : undefined,
      // Zakaz sanasi (faqat super rol tahrirlaydi). undefined bo'lsa yubormaymiz.
      createdAt: data.createdAt || undefined,
      lines: data.lines.map(l => ({ productId: l.productId, qty: l.qty, unit: l.unit })),
    };
    try {
      if (editing) {
        const { order } = await API.updateOrder(data.id, payload);
        setOrders(prev => prev.map(o => (o.id === order.id ? order : o)));
        showToast(order.code + ' yangilandi');
      } else {
        const { order } = await API.createOrder(payload);
        setOrders(prev => [...prev, order]);
        showToast('Yangi zakaz qoʼshildi');
      }
      setForm(null);
    } catch (ex) {
      showToast(ex.message || 'Saqlashda xatolik');
    }
  }

  async function deleteOrder(o) {
    try {
      await API.deleteOrder(o.id);
      setOrders(prev => prev.filter(x => x.id !== o.id));
      showToast((o.code || 'Zakaz') + ' oʼchirildi');
    } catch (ex) {
      showToast(ex.message || 'Oʼchirishda xatolik');
    }
  }

  if (booting) {
    return (
      <div style={{ height: '100%', display: 'grid', placeItems: 'center', background: 'var(--bg)' }}>
        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 14, color: 'var(--ink-4)' }}>
          <Logo />
          <div style={{ fontSize: 13, fontWeight: 600 }}>Yuklanmoqda…</div>
        </div>
      </div>
    );
  }

  if (!user) return <Login onLogin={login} />;

  const activeCount = orders.length;

  const navItems = buildNavItems({ user, perms, isSuper: !!(role && role.super) });
  const pickView = (key) => { setView(key); if (isMobile) setNavOpen(false); };

  return (
    <div style={{ height: '100%', position: 'relative' }}>
      <div className="glass-bg" aria-hidden="true" />
      <div className="gx-shell">
        <GlassTopBar user={user} role={role} isMobile={isMobile} onMenu={() => setNavOpen(o => !o)}
          onProfile={() => setProfileOpen(true)} onLogout={logout}
          canAsk={perms.viewAi !== false} onAsk={() => setView('ai')} />

        <div className="gx-body">
          {(!isMobile || navOpen) && (
            <>
              {isMobile && <div className="nav-backdrop" onClick={() => setNavOpen(false)} />}
              <GlassRail items={navItems} view={view} pick={pickView} drawer={isMobile} />
            </>
          )}

          <main className="gx-panel glass">
          <GlassPage key={view}>
        {view === 'dashboard' && (
          <div className="gx-greet">
            <h1>{greetingWord()}, {String(user.name || '').split(' ')[0]}</h1>
            <p>Bugungi savdo, zakaz va vazifalar holati — bir qarashda.</p>
          </div>
        )}
        {view === 'board' && (
          <>
            <BoardToolbar search={search} setSearch={setSearch} regionFilter={regionFilter} setRegionFilter={setRegionFilter}
              sortBy={sortBy} setSortBy={setSortBy}
              count={activeCount} perms={perms} onAdd={() => setForm({})} user={user} />
            <div style={{ flex: 1, minHeight: 0 }}>
              <KanbanBoard orders={orders} setOrders={setOrders} user={user} perms={perms}
                onAddOrder={() => setForm({})} onEditOrder={(o) => setForm({ initial: o })} onDeleteOrder={deleteOrder}
                showToast={showToast} reloadOrders={reloadOrders} density="medium" search={search} regionFilter={regionFilter} sortBy={sortBy} />
            </div>
          </>
        )}
        {view === 'tasks' && perms.taskView && (
          <TaskBoard tasks={tasks} setTasks={setTasks} taskLists={taskLists} setTaskLists={setTaskLists}
            perms={perms} showToast={showToast} reload={reloadTasks} />
        )}
        {view === 'dashboard' && <Dashboard orders={dashOrders} tasks={tasks} taskLists={taskLists} onNavigate={setView} perms={perms} scopeLabel={dashScopeLabel} scopeRegionIds={dashScoped ? myRegionIds : null} isSuper={!!(role && role.super)} />}
        {view === 'region' && <RegionView />}
        {view === 'distributors' && <Distributors user={user} showToast={showToast} />}
        {view === 'targets' && <Targets user={user} showToast={showToast} />}
        {view === 'outlets' && <Outlets user={user} showToast={showToast} />}
        {view === 'planfakt' && <PlanFaktView />}
        {view === 'factory' && <FactoryView />}
        {view === 'ai' && <AiInsights perms={perms} showToast={showToast} user={user} />}
        {view === 'settings' && <Settings showToast={showToast} user={user} isSuper={role && role.super} perms={perms} />}
        {view === 'storecheck' && !!(role && (role.super || DB.userRegionIds(user.id).length)) && <Storecheck user={user} showToast={showToast} />}
        {view === 'recruiting' && role && role.super && <Recruiting user={user} showToast={showToast} />}
        {view === 'maosh' && role && role.super && <Hr user={user} showToast={showToast} initialTab="maosh" maoshOnly />}
        {view === 'hr' && role && role.super && <Hr user={user} showToast={showToast} />}
        {view === 'salesdoc' && <SalesDocDashboard />}
        {view === 'checklist' && <Checklist user={user} showToast={showToast} isSuper={!!(role && role.super)}
          viewAll={!!(role && (role.super ? perms.checklistViewAll !== false : perms.checklistViewAll === true))} />}
        {view === 'log' && role && role.super && <LogView log={log} />}
          </GlassPage>
          </main>
        </div>

        <GlassTabs items={navItems} view={view} pick={pickView} onAdd={perms.addOrder ? () => setForm({}) : null} />
      </div>

      {form && (
        <OrderForm initial={form.initial} user={user} onClose={() => setForm(null)} onSave={saveOrder} />
      )}
      {profileOpen && (
        <ProfileModal user={user} onClose={() => setProfileOpen(false)} onSaved={applyMyAvatar} showToast={showToast} />
      )}
      {toast && <Toast key={toast.k} msg={toast.msg} onDone={() => setToast(null)} />}
    </div>
  );
}

// Kutilmagan render xatosi butun ilovani oq ekranga aylantirmasligi uchun —
// xato bo'lsa xabar + "Qayta yuklash" tugmasi ko'rsatiladi (blank screen o'rniga).
class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { error: null };
  }
  static getDerivedStateFromError(error) {
    return { error };
  }
  componentDidCatch(error, info) {
    console.error('Ilova xatosi:', error, info);
  }
  render() {
    if (this.state.error) {
      return (
        <div style={{ height: '100vh', display: 'grid', placeItems: 'center', padding: 24, fontFamily: 'system-ui, sans-serif' }}>
          <div style={{ maxWidth: 460, textAlign: 'center', display: 'flex', flexDirection: 'column', gap: 12 }}>
            <div style={{ fontSize: 16, fontWeight: 700 }}>Nimadir xato ketdi</div>
            <div style={{ fontSize: 13, color: '#64748b' }}>{String(this.state.error.message || this.state.error)}</div>
            <button
              onClick={() => { this.setState({ error: null }); window.location.reload(); }}
              style={{ height: 38, borderRadius: 8, border: 'none', background: '#5B45D6', color: '#fff', fontWeight: 600, cursor: 'pointer' }}
            >
              Qayta yuklash
            </button>
          </div>
        </div>
      );
    }
    return this.props.children;
  }
}

ReactDOM.createRoot(document.getElementById('root')).render(<ErrorBoundary><App /></ErrorBoundary>);
