// ===========================================================
// Main App — auth gate, role switcher, router, tweaks
// ===========================================================

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "variation": "classic",
  "role": "telesale",
  "density": "regular",
  "accentMode": "navy",
  "startLoggedIn": false
}/*EDITMODE-END*/;

// Nav items — GIỐNG NHAU cho mọi vai trò (thiết kế thống nhất, chốt 20/07/2026).
// Báo cáo + Cài đặt được thêm động theo QUYỀN (tvsCan) trong App — xem ma trận phân quyền ở Cài đặt.
const NAV_STANDARD = [
  { id: 'dashboard', label: 'Tổng quan',  icon: 'dashboard' },
  { id: 'customers', label: 'Khách hàng', icon: 'users' },
];
// Màn hình thay thế khi vị trí không có quyền truy cập module
function NoAccess() {
  return (
    <div style={{padding:'var(--space-8) 0'}}>
      <EmptyState icon="flag" title="Vị trí của bạn không có quyền truy cập mục này"
        desc="Liên hệ quản lý để được cấp quyền trong Cài đặt → Người dùng & Phân quyền."/>
    </div>
  );
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [authed, setAuthed] = useState(t.startLoggedIn !== false);
  // Tài khoản do Admin tạo (Cài đặt → Người dùng): ghi đè tên / team / email lên persona demo của vai trò
  const LOGIN_USER_KEY = 'tvs_crm_login_user';
  const [loginUser, setLoginUser] = useState(() => { try { return JSON.parse(localStorage.getItem(LOGIN_USER_KEY) || 'null'); } catch (e) { return null; } });
  const baseRole = D.roles.find(r => r.id === t.role)
    || (window.TVS_ROLE_DEFS || []).filter(r => r.id === t.role).map(r => ({ id: r.id, label: r.label, person: r.label, team: (r.teams || [])[0] || '', avatar: '' }))[0]
    || D.roles[0];
  const role = loginUser
    ? { ...baseRole, id: t.role, person: loginUser.name, team: loginUser.team || baseRole.team, email: loginUser.email, phone: loginUser.phone,
        ids: loginUser.roles && loginUser.roles.length > 1 ? loginUser.roles : undefined } // kiêm nhiều vai → quyền cộng dồn (tvsCan)
    : baseRole;
  const logout = () => { setAuthed(false); setLoginUser(null); try { localStorage.removeItem(LOGIN_USER_KEY); } catch (e) {} };
  // Đổi nhanh tài khoản từ menu avatar (tiện ích demo — UI của nó bị loại khi xuất bản bàn giao)
  const switchUser = (u) => {
    const payload = { name: u.name, team: u.team, email: u.email, phone: u.phone, roles: u.roles || [] };
    setTweak('role', (u.roles && u.roles[0]) || 'instore');
    setLoginUser(payload);
    try { localStorage.setItem(LOGIN_USER_KEY, JSON.stringify(payload)); } catch (e) {}
    setAuthed(true);
    window.tvsToast && window.tvsToast('Đã chuyển sang tài khoản ' + u.name);
  };
  const session = useTvsSession(); // re-render khi quản lý đổi phân quyền
  // Menu dựng theo QUYỀN thật (ma trận trong Cài đặt) — không còn cứng theo vai trò
  const nav = useMemo(() => [
    ...NAV_STANDARD,
    ...(tvsCan(role, 'reports.view')  ? [{ id: 'reports',  label: 'Báo cáo', icon: 'chart' }] : []),
    ...(tvsCan(role, 'settings.view') ? [{ id: 'settings', label: 'Cài đặt', icon: 'settings' }] : []),
  ], [role.id, role.ids, session.__ver]);

  // Default screen depends on role
  const [screen, setScreen] = useState(nav[0].id);
  const [openCustomer, setOpenCustomer] = useState(null);
  const [logOrderFor, setLogOrderFor] = useState(null);
  const [savedToast, setSavedToast] = useState(null);
  const [showAddCustomer, setShowAddCustomer] = useState(false);
  const [showAddPartner, setShowAddPartner] = useState(false);
  const [mobileNavOpen, setMobileNavOpen] = useState(false);
  const [showSearch, setShowSearch] = useState(false);
  const [accountMode, setAccountMode] = useState(null); // 'profile' | 'account' | null
  const [quickOutcome, setQuickOutcome] = useState(null); // customer — modal "Ghi kết quả liên hệ"
  const [quickSchedule, setQuickSchedule] = useState(null); // customer — modal "Đặt lịch follow-up" (mở từ hồ sơ 360°)

  // Navigate to a screen and exit account view
  const goTo = (s) => { setAccountMode(null); setScreen(s); };

  // Đối tác B2B (id P-xxx hoặc dòng gộp từ bảng khách) luôn mở modal ở chế độ B2B.
  // Chặn TẠI ĐÂY = chặn mọi đường vào modal ghi đơn (bảng khách, hồ sơ 360°, dashboard, cross-sell...)
  const onLogOrder = (c) => {
    if (!tvsCan(role, 'orders.create')) return window.tvsDenied();
    const subj = c && c._partner ? c._partner : c;
    const isPartner = subj && String(subj.id || '').startsWith('P-');
    setLogOrderFor(isPartner ? { ...subj, _b2b: true } : subj);
  };
  // Mọi đường mở wizard tạo khách (nút Thêm khách hàng, Đăng ký thành viên trên dashboard...)
  const onOpenAddCustomer = () => {
    if (!tvsCan(role, 'customers.edit')) return window.tvsDenied();
    setShowAddCustomer(true);
  };

  // Cmd+K / Ctrl+K opens global search; ESC closes overlays (lớp trên cùng trước)
  useEffect(() => {
    const onKey = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') {
        e.preventDefault();
        if (authed) setShowSearch(true);
      }
      if (e.key === 'Escape') {
        setShowSearch(false);
        setQuickOutcome(null);
        setLogOrderFor(null);
        setOpenCustomer(null);
      }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [authed]);

  // Re-set screen if role changes and current screen not in nav
  useEffect(() => {
    if (!nav.find(n => n.id === screen)) {
      setScreen(nav[0].id);
    }
  }, [t.role, session.__ver]);

  // Apply variation to <html>
  useEffect(() => {
    document.documentElement.setAttribute('data-variation', t.variation);
  }, [t.variation]);

  // Close mobile nav on route change
  useEffect(() => { setMobileNavOpen(false); }, [screen]);

  // ============ AUTH GATE ============
  if (!authed) {
    return <AuthScreen onLogin={(roleId, user) => {
      setTweak('role', roleId);
      setLoginUser(user || null);
      try { user ? localStorage.setItem(LOGIN_USER_KEY, JSON.stringify(user)) : localStorage.removeItem(LOGIN_USER_KEY); } catch (e) {}
      setAuthed(true);
    }}/>;
  }

  return (
    <div className={`app ${mobileNavOpen ? 'app--nav-open' : ''}`}>
      <Sidebar role={role} currentScreen={accountMode ? null : screen} onNavigate={goTo} navItems={nav} onLogout={logout}/>
      <Topbar
        role={role}
        currentScreen={screen}
        navItems={nav}
        onNavigate={goTo}
        onSwitchUser={switchUser}
        variation={t.variation}
        onAddCustomer={onOpenAddCustomer}
        onAddPartner={() => { if (!tvsCan(role, 'customers.edit')) return window.tvsDenied(); setShowAddPartner(true); }}
        onOpenMobileNav={() => setMobileNavOpen(true)}
        onOpenSearch={() => setShowSearch(true)}
        onOpenAccount={(m) => setAccountMode(m)}
        onLogout={logout}/>
      {mobileNavOpen && <div className="mobile-nav-overlay" onClick={() => setMobileNavOpen(false)}/>}
      <main className="main">
        {accountMode ? (
          <AccountScreen role={role} mode={accountMode} onChangeMode={(m) => setAccountMode(m)}/>
        ) : (
        <>
        {screen === 'dashboard' && <Dashboard role={role} onNavigate={goTo} onOpenCustomer={setOpenCustomer} onLogOrder={onLogOrder} onRegister={onOpenAddCustomer} onLogOutcome={(c) => setQuickOutcome(c)}/>}
        {screen === 'customers' && <CustomersScreen role={role} onOpenCustomer={setOpenCustomer} onGoToTelesale={(c) => { setOpenCustomer(null); setScreen('telesale'); }} onLogOrder={onLogOrder} onAddCustomer={onOpenAddCustomer}/>}
        {screen === 'telesale'  && <TelesaleScreen onOpenCustomer={setOpenCustomer} onLogOrder={onLogOrder}/>}
        {screen === 'b2b'       && (tvsCan(role, 'b2b.view') ? <B2BScreen onLogOrder={(p) => { if (!tvsCan(role, 'orders.create')) return window.tvsDenied(); setLogOrderFor({...p, _b2b: true}); }} onAddPartner={() => { if (!tvsCan(role, 'customers.edit')) return window.tvsDenied(); setShowAddPartner(true); }}/> : <NoAccess/>)}
        {screen === 'instore'   && <StoresScreen onOpenCustomer={setOpenCustomer}/>}
        {screen === 'inventory' && (tvsCan(role, 'inventory.view') ? <InventoryScreen role={role}/> : <NoAccess/>)}
        {screen === 'reports'   && (tvsCan(role, 'reports.view') ? <ReportsScreen role={role}/> : <NoAccess/>)}
        {screen === 'settings'  && (tvsCan(role, 'settings.view') ? <SettingsScreen role={role}/> : <NoAccess/>)}
        </>
        )}
      </main>

      {openCustomer && (
        <Customer360
          customer={openCustomer}
          role={role}
          onClose={() => setOpenCustomer(null)}
          onCall={() => { const c = openCustomer; setOpenCustomer(null); setQuickOutcome(c); }}
          onSchedule={() => { const c = openCustomer; setOpenCustomer(null); setQuickSchedule(c); }}
          onLogOrder={(c) => { if (!tvsCan(role, 'orders.create')) return window.tvsDenied(); setOpenCustomer(null); setLogOrderFor(c); }}
        />
      )}

      {quickOutcome && (
        <QuickActionModal
          mode="outcome"
          customer={quickOutcome}
          role={role}
          onClose={() => setQuickOutcome(null)}
        />
      )}
      {quickSchedule && (
        <QuickActionModal
          mode="followup"
          customer={quickSchedule}
          role={role}
          onClose={() => setQuickSchedule(null)}
        />
      )}

      {logOrderFor && (
        <LogOrderModal
          subject={logOrderFor}
          mode={logOrderFor._b2b ? 'b2b' : 'b2c'}
          onClose={() => setLogOrderFor(null)}
          onSave={(order) => {
            // Ghi đơn vào hồ sơ khách/đối tác + cập nhật chỉ số ngay lập tức
            window.TVS_SESSION.addOrder(logOrderFor.id, {
              date: order.orderDate, channel: D.channelLabel(order.channel),
              items: order.items.length, total: order.total,
              posRef: order.posRef || null, note: order.note || '',
              status: 'Đã ghi nhận', by: role.person, _new: true,
            });
            const c = D.customers.find(x => x.id === logOrderFor.id);
            const p = c ? null : D.partners.find(x => x.id === logOrderFor.id);
            if (c) {
              c.orders = (c.orders || 0) + 1;
              c.ltv = (c.ltv || 0) + order.total;
              c.avgOrder = Math.round(c.ltv / c.orders);
              if (!c.lastOrder || order.orderDate > c.lastOrder) c.lastOrder = order.orderDate;
            } else if (p) {
              p.gmv30d = (p.gmv30d || 0) + order.total;
              p.gmvYTD = (p.gmvYTD || 0) + order.total;
              p.commissionEarned = Math.round((p.commissionEarned || 0) + order.total * (p.commission || 0) / 100);
            }
            setSavedToast({name: logOrderFor.name, count: order.items.length, total: order.total});
            setLogOrderFor(null);
            setTimeout(() => setSavedToast(null), 4000);
          }}
        />
      )}

      {showAddCustomer && (
        <AddCustomerModal
          role={role}
          onClose={() => setShowAddCustomer(false)}
          onSave={(c) => {
            setShowAddCustomer(false);
            const isBiz = c.custType === 'business';
            const types = c.types && c.types.length ? c.types : [isBiz ? 'business' : 'retail'];
            // Năm sinh chỉ tính tuổi khi hợp lệ (1920 → hiện tại − 5)
            const by = parseInt(c.birthYear, 10);
            const nowY = new Date().getFullYear();
            const age = (by >= 1920 && by <= nowY - 5) ? nowY - by : null;
            // Ghi vào danh sách khách hàng để hiện ngay trong bảng
            const newCustomer = {
              id: 'C-' + String(Date.now()).slice(-5),
              owner: c.owner || role.person, // Marketing/Admin có thể gán cho nhân viên khác; mặc định là chính mình
              name: isBiz ? c.company : c.name,
              contactName: isBiz ? c.name : null,
              contactRole: isBiz ? c.contactRole : null,
              company: isBiz ? c.company : null,
              taxId: isBiz ? c.taxId : null,
              address: isBiz ? c.address : null,
              phone: c.phone, email: c.email,
              tier: 'Đồng', joined: D.iso(0),
              gender: isBiz ? '—' : (c.gender === 'male' ? 'Nam' : c.gender === 'female' ? 'Nữ' : 'Khác'),
              age,
              city: c.city,
              ltv: 0, orders: 0, avgOrder: 0, lastOrder: null,
              segment: types[0],
              roles: types.slice(1),
              affiliateId: c.affiliateId || null,
              source: D.channelLabel(c.channel), // lưu nhãn tiếng Việt thống nhất với dữ liệu có sẵn
              tags: [...(c.tags || []), 'New'],
              note: c.notes || (isBiz ? 'Khách tổ chức mới đăng ký' : 'Khách mới đăng ký'),
              nps: null, channel: D.channelLabel(c.channel),
              consent: c.consent, preferredContact: c.preferredContact,
              followUp: null,
            };
            D.customers.unshift(newCustomer);
            window.TVS_SESSION.addCustomer(newCustomer); // sống qua reload
            setSavedToast({name: isBiz ? c.company : c.name, count: 0, total: 0, kind:'new-customer'});
            setTimeout(() => setSavedToast(null), 4000);
          }}/>
      )}

      {showAddPartner && (
        <AddPartnerWizard
          onClose={() => setShowAddPartner(false)}
          onSave={(p) => {
            setShowAddPartner(false);
            // Thêm đối tác mới vào danh sách — stage Prospect, chưa có doanh số
            const typeLabels = { tiktok_affiliate:'TikTok Affiliate', pharmacy:'Nhà thuốc', wholesale:'Đại lý / Phân phối', gym:'Phòng gym', pt:'PT / HLV', spa:'Spa & Nutritionist', enterprise:'Doanh nghiệp (quà tặng NV)' };
            const newPartner = {
              id: 'P-' + String(Date.now()).slice(-3),
              name: p.name, type: typeLabels[p.type] || p.type,
              contact: p.contactName, phone: p.contactPhone, email: p.contactEmail,
              tier: 'Bạc', stage: 'Onboarding', onboarded: null, // khớp với màn "Hoàn tất" của wizard
              gmv30d: 0, gmvYTD: 0, commission: p.commission, commissionEarned: 0,
              followers: p.followers || null, conversion: null,
              socialHandle: p.socialHandle || null, taxCode: (p.legal && p.legal.taxCode) || null,
              note: p.notes || null,
              city: p.city, priceList: p.priceList,
              nextAction: { type: 'Gọi giới thiệu chương trình hợp tác', due: D.iso(2) },
            };
            D.partners.unshift(newPartner);
            window.TVS_SESSION.addPartner(newPartner); // sống qua reload
            setScreen('b2b');
            setSavedToast({name: p.name, count: 0, total: 0, kind:'new-partner'});
            setTimeout(() => setSavedToast(null), 4000);
          }}/>
      )}

      {savedToast && (
        <div style={{position:'fixed',bottom:24,left:'50%',transform:'translateX(-50%)',zIndex:200,background:'var(--vs-dark-blue)',color:'#fff',padding:'14px 22px',borderRadius:'var(--radius-md)',boxShadow:'var(--shadow-pop)',display:'flex',gap:12,alignItems:'center',animation:'slidein 0.28s var(--ease-out)',maxWidth:'90vw'}}>
          <div style={{width:28,height:28,borderRadius:'50%',background:'var(--status-success)',color:'#fff',display:'flex',alignItems:'center',justifyContent:'center',flexShrink:0}}>
            <Icon name="check" size={16}/>
          </div>
          <div>
            <div className="bold" style={{color:'#fff'}}>
              {savedToast.kind === 'new-customer' ? `Đã tạo khách hàng ${savedToast.name}` :
               savedToast.kind === 'new-partner'  ? `Đã thêm đối tác ${savedToast.name}` :
               `Đã lưu lịch sử mua cho ${savedToast.name}`}
            </div>
            {savedToast.count > 0 && (
              <div style={{fontSize:12,color:'rgba(255,255,255,0.72)'}}>{savedToast.count} sản phẩm · {fmt.vndFull(savedToast.total)}</div>
            )}
          </div>
          <button onClick={() => setSavedToast(null)} style={{background:'none',border:'none',color:'rgba(255,255,255,0.6)',cursor:'pointer',marginLeft:8}}>
            <Icon name="close" size={14}/>
          </button>
        </div>
      )}

      {showSearch && (
        <GlobalSearch
          role={role}
          onClose={() => setShowSearch(false)}
          onOpenCustomer={(c) => setOpenCustomer(c)}
          onNavigate={goTo}
        />
      )}

      <TweaksPanel>
        <TweakSection label="Vai trò"/>
        <TweakSelect label="Đăng nhập với vai trò"
          value={t.role}
          options={D.roles.map(r => ({value: r.id, label: r.label + ' — ' + r.person}))}
          onChange={(v) => setTweak('role', v)}/>

        <TweakSection label="3 phương án layout"/>
        <TweakRadio label="Layout"
          value={t.variation}
          options={[
            {value:'classic',label:'Classic'},
            {value:'compact',label:'Compact'},
            {value:'airy',label:'Airy'},
          ]}
          onChange={(v) => setTweak('variation', v)}/>
        <div style={{padding:'4px 8px 8px',fontSize:11,color:'var(--fg-muted)',lineHeight:1.5}}>
          {t.variation === 'classic' && '📐 Sidebar dọc + label · phù hợp cho power-user dùng cả ngày'}
          {t.variation === 'compact' && '⚡ Icon rail · tối ưu màn hình nhỏ, in-store tablet'}
          {t.variation === 'airy'    && '✨ Top nav + nhiều khoảng trắng · phù hợp quản lý xem báo cáo'}
        </div>

        <TweakSection label="Demo"/>
        <TweakButton onClick={() => setAuthed(false)}>Đăng xuất để xem màn login</TweakButton>
      </TweaksPanel>
    </div>
  );
}

window.App = App;
