// ===========================================================
// Settings — Cài đặt (Users, Roles, Integrations, Pricelist, Segments, Notifications)
// ===========================================================

function SettingsScreen({ role }) {
  const [tab, setTab] = useState('users');

  return (
    <>
      <div className="page-header">
        <div>
          <h1>Cài đặt hệ thống</h1>
          <div className="sub">Quản lý người dùng, phân quyền, tích hợp & cấu hình toàn hệ thống</div>
        </div>
      </div>

      <div className="grid" style={{gridTemplateColumns:'240px minmax(0, 1fr)',gap:'var(--space-4)',alignItems:'flex-start'}}>
        {/* Settings nav */}
        <Card pad={false} className="settings-nav" style={{position:'sticky',top:0}}>
          <div style={{padding:'var(--space-3)',display:'flex',flexDirection:'column',gap:2}}>
            {[
              ['users','Người dùng & Phân quyền','users'],
              ['pricelist','Bảng giá','receipt'],
              ['integrations','Kết nối & Nhập dữ liệu','layers'],
              ['data','Dữ liệu & Backup','package'],
            ].map(([k,l,ic]) => (
              <button key={k}
                onClick={() => setTab(k)}
                className={`sidebar-item ${tab===k?'active':''}`}
                style={{margin:0,width:'100%',color: tab===k ? 'var(--vs-dark-blue)' : 'var(--fg-2)', background: tab===k ? 'rgba(65,182,230,0.10)' : 'transparent'}}>
                <Icon name={ic} size={16}/>
                <span className="label">{l}</span>
              </button>
            ))}
          </div>
        </Card>

        {/* Settings content */}
        <div>
          {tab === 'users' && <><UsersTab role={role}/><div className="mt-4"><RolesTab/></div></>}
          {tab === 'integrations' && <IntegrationsTab/>}
          {tab === 'pricelist' && <PricelistTab/>}
          {tab === 'data' && <DataTab role={role}/>}
        </div>
      </div>
    </>
  );
}

// ===== Users tab =====
// Người dùng thêm trong phiên — lưu vào TVS_SESSION để hiện ngay và sống qua reload
function UsersTab({ role }) {
  const session = useTvsSession();
  const [showAdd, setShowAdd] = useState(false);
  const [editUser, setEditUser] = useState(null); // Admin sửa tài khoản hiện hữu
  const [search, setSearch] = useState('');
  // Tài khoản nhân viên THẬT (src/accounts.js) — nhãn vai trò lấy từ TVS_ROLE_DEFS
  const roleLabelOf = (id) => (window.TVS_ROLE_DEFS.find(r => r.id === id) || {label: id}).label;
  // tvsAllAccounts = tài khoản cài sẵn (+ phần Admin đã sửa) + tài khoản tạo trong app — phụ thuộc session.__ver để cập nhật ngay
  const all = window.tvsAllAccounts().map(a => ({
    ...a, role: (a.roles || []).map(roleLabelOf).join(' · '),
    last: a.last || (a.status === 'active' ? '—' : a.status === 'pending' ? 'Chưa kích hoạt' : 'Tạm khoá'),
  }));
  const sessionUsers = all.filter(a => a._source === 'session');
  const users = search
    ? all.filter(u => (u.name + u.email + u.team + u.role).toLowerCase().includes(search.toLowerCase()))
    : all;
  return (
    <>
      <Card pad={false}>
        <div className="users-head" style={{padding:'var(--space-4) var(--space-5)',borderBottom:'1px solid var(--border-1)',display:'flex',gap:'var(--space-3)',alignItems:'center'}}>
          <div>
            <h3 style={{margin:0,fontSize:'var(--t-md)',color:'var(--fg-1)'}}>Người dùng hệ thống</h3>
            <div className="text-xs fg-muted mt-1">{all.length} tài khoản · {all.filter(u=>u.status==='active').length} đang hoạt động{sessionUsers.length > 0 && <> · <b style={{color:'var(--vs-light-blue)'}}>{sessionUsers.length} vừa thêm</b></>}</div>
          </div>
          <div className="topbar-search" style={{flex:'0 1 280px',marginLeft:'auto'}}>
            <Icon name="search" size={14} style={{color:'var(--fg-muted)'}}/>
            <input placeholder="Tìm tên, email, team..." value={search} onChange={(e)=>setSearch(e.target.value)}/>
          </div>
          <button className="btn btn-cta" onClick={() => setShowAdd(true)}><Icon name="plus" size={14}/>Thêm người dùng</button>
        </div>
        <div className="table-wrap">
          <table className="tbl tbl--users">
            <thead>
              <tr><th>Người dùng</th><th>Vai trò</th><th>Team / Cửa hàng</th><th>Hoạt động cuối</th><th>Trạng thái</th><th></th></tr>
            </thead>
            <tbody>
              {users.map(u => (
                <tr key={u.id || u.email || u.phone} style={u._new ? {background:'rgba(65,182,230,0.07)'} : undefined}>
                  <td>
                    <div className="row gap-3">
                      <Avatar name={u.name} size="sm"/>
                      <div>
                        <div className="strong">{u.name}{u._new && <Tag variant="info" style={{marginLeft:6}}>Mới</Tag>}</div>
                        <div className="text-xs fg-muted tnum">{[u.email, u.phone].filter(Boolean).join(' · ')}</div>
                      </div>
                    </div>
                  </td>
                  <td>
                    <div className="row gap-1" style={{flexWrap:'wrap',maxWidth:260}}>
                      {u.role.split('·').map(r => r.trim()).filter(Boolean).map(r => (
                        <Tag key={r} variant={r.includes('Admin')?'platinum':r.includes('B2B')?'gold':r.includes('TikTok')||r.includes('Shopee')?'info':r.includes('Livestream')?'danger':r.includes('Chăm sóc')?'success':'outline'}>{r}</Tag>
                      ))}
                    </div>
                  </td>
                  <td className="text-sm">{u.team}</td>
                  <td className="text-sm fg-muted">{u.last}</td>
                  <td>
                    <Tag variant={u.status==='active'?'success':u.status==='pending'?'warning':'outline'} dot>
                      {u.status==='active' ? 'Hoạt động' : u.status==='pending' ? 'Chờ kích hoạt' : 'Tạm khoá'}
                    </Tag>
                  </td>
                  <td><button className="btn btn-icon btn-sm btn-secondary" title="Sửa tài khoản" onClick={() => setEditUser(u)}><Icon name="note" size={13}/></button></td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </Card>
      {showAdd && <AddUserModal existingEmails={all.map(u => (u.email || '').toLowerCase()).filter(Boolean)} existingPhones={all.map(u => u.phone).filter(Boolean).map(p => window.tvsNormPhone(p))} onClose={() => setShowAdd(false)}/>}
      {editUser && <EditUserModal user={editUser} me={role}
        existingEmails={all.filter(u => u.id !== editUser.id).map(u => (u.email || '').toLowerCase()).filter(Boolean)}
        existingPhones={all.filter(u => u.id !== editUser.id).map(u => u.phone).filter(Boolean).map(p => window.tvsNormPhone(p))}
        onClose={() => setEditUser(null)}/>}
    </>
  );
}


// ===== Edit user modal — Admin sửa tài khoản hiện hữu (tên, email/SĐT, vị trí, khoá/mở, đặt lại mật khẩu) =====
function EditUserModal({ user, me, onClose, existingEmails = [], existingPhones = [] }) {
  const [f, setF] = useState({ name: user.name || '', email: user.email || '', phone: user.phone || '', roles: [...(user.roles || [])], status: user.status || 'active', pwd: '' });
  const [showPwd, setShowPwd] = useState(false);
  const up = (k, v) => setF(s => ({ ...s, [k]: v }));
  const ROLES = window.TVS_ROLE_DEFS;
  const toggleRole = (id) => setF(s => ({ ...s, roles: s.roles.includes(id) ? s.roles.filter(x => x !== id) : [...s.roles, id] }));
  // Không cho Admin tự khoá / tự bỏ vai Admin của chính mình
  const isSelf = !!me && ((me.email && user.email && me.email.toLowerCase() === String(user.email).toLowerCase()) || (me.phone && user.phone && window.tvsNormPhone(me.phone) === window.tvsNormPhone(user.phone)));
  const emailFilled = f.email.trim().length > 0;
  const emailValid = /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(f.email.trim());
  const emailDup = emailFilled && emailValid && existingEmails.includes(f.email.trim().toLowerCase());
  const phoneFilled = f.phone.trim().length > 0;
  const phoneOk = phoneFilled && window.tvsPhoneValid(f.phone);
  const phoneDup = phoneOk && existingPhones.includes(window.tvsNormPhone(f.phone));
  const loginIdOk = (emailFilled && emailValid && !emailDup) || (phoneOk && !phoneDup);
  const noInvalid = (!emailFilled || (emailValid && !emailDup)) && (!phoneFilled || (phoneOk && !phoneDup));
  const pwdOk = !f.pwd || f.pwd.length >= 6;
  const selfOk = !isSelf || (f.roles.includes('manager') && f.status === 'active');
  const canSave = f.name.trim() && loginIdOk && noInvalid && f.roles.length > 0 && pwdOk && selfOk;
  const genPwd = () => 'Tvs@' + Math.random().toString(36).slice(2, 6).toUpperCase() + Math.floor(100 + Math.random() * 900);
  const save = () => {
    const patch = { name: f.name.trim(), email: f.email.trim().toLowerCase(), phone: phoneFilled ? window.tvsNormPhone(f.phone) : '', roles: f.roles, status: f.status };
    if (f.pwd) patch.pwdHash = window.tvsHash(f.pwd); // đặt lại mật khẩu — vẫn chỉ lưu hash
    window.TVS_SESSION.updateUser(user.id, patch);
    window.tvsToast('Đã cập nhật tài khoản ' + patch.name + (f.pwd ? ' · mật khẩu mới đã đặt' : ''));
    onClose();
  };
  const Req = () => <span style={{color:'var(--status-sale)'}}>*</span>;
  return (
    <div className="drawer-overlay" style={{justifyContent:'center',alignItems:'center'}} onClick={onClose}>
      <div onClick={(e) => e.stopPropagation()}
        style={{background:'var(--bg-page)',width:'min(600px, 95vw)',maxHeight:'92vh',display:'flex',flexDirection:'column',borderRadius:'var(--radius-lg)',overflow:'hidden',boxShadow:'var(--shadow-pop)'}}>
        <div style={{padding:'var(--space-4) var(--space-6)',background:'var(--vs-dark-blue)',color:'#fff',display:'flex',alignItems:'center',gap:12}}>
          <Avatar name={user.name} size="sm"/>
          <div style={{flex:1}}>
            <div className="eyebrow" style={{color:'var(--vs-light-blue)'}}>Sửa tài khoản</div>
            <h2 style={{margin:'2px 0 0',fontFamily:'var(--font-display)',fontSize:20,fontWeight:700,color:'#fff'}}>{user.name}</h2>
          </div>
          <button onClick={onClose} title="Đóng" style={{background:'rgba(255,255,255,0.18)',border:'none',color:'#fff',width:32,height:32,borderRadius:'50%',cursor:'pointer',display:'inline-flex',alignItems:'center',justifyContent:'center'}}><Icon name="close" size={14}/></button>
        </div>
        <div style={{padding:'var(--space-5) var(--space-6)',overflow:'auto',flex:1}}>
          <div className="mb-3">
            <div className="field-label">Họ và tên <Req/></div>
            <input className="input" autoFocus value={f.name} onChange={(e)=>up('name',e.target.value)}/>
          </div>
          <div className="field-label">Tên đăng nhập <Req/> <span className="fg-muted" style={{fontWeight:400,textTransform:'none',letterSpacing:0}}>— email hoặc số điện thoại (ít nhất 1)</span></div>
          <div className="grid grid-2 mb-3">
            <div>
              <div className="text-xs fg-muted mb-1">Email</div>
              <input className="input" placeholder="a.nv@tvs.vn" value={f.email} onChange={(e)=>up('email',e.target.value)}/>
              {emailFilled && !emailValid && <div className="text-xs mt-1" style={{color:'var(--status-sale)'}}>Email không hợp lệ</div>}
              {emailDup && <div className="text-xs mt-1" style={{color:'var(--status-sale)',fontWeight:700}}>⚠ Email đã dùng cho tài khoản khác</div>}
            </div>
            <div>
              <div className="text-xs fg-muted mb-1">Số điện thoại</div>
              <input className="input tnum" placeholder="0903 xxx xxx" value={f.phone} onChange={(e)=>up('phone',e.target.value)}/>
              {phoneFilled && !phoneOk && <div className="text-xs mt-1" style={{color:'var(--status-sale)'}}>SĐT cần 9–11 chữ số</div>}
              {phoneDup && <div className="text-xs mt-1" style={{color:'var(--status-sale)',fontWeight:700}}>⚠ SĐT đã dùng cho tài khoản khác</div>}
            </div>
          </div>
          {!emailFilled && !phoneFilled && <div className="text-xs mb-3" style={{color:'var(--status-sale)',fontWeight:700}}>⚠ Cần ít nhất email hoặc số điện thoại để đăng nhập.</div>}
          <div className="field-label">Vai trò <Req/></div>
          <div className="row gap-1 mb-3" style={{flexWrap:'wrap'}}>
            {ROLES.map(r => (
              <button key={r.id} className={f.roles.includes(r.id) ? 'btn btn-cta btn-sm' : 'btn btn-secondary btn-sm'}
                disabled={isSelf && r.id === 'manager'} title={isSelf && r.id === 'manager' ? 'Không thể tự bỏ vai Admin của chính mình' : undefined}
                onClick={() => toggleRole(r.id)}>
                {f.roles.includes(r.id) ? <Icon name="check" size={11}/> : <Icon name="plus" size={11}/>}{r.label}
              </button>
            ))}
          </div>
          {f.roles.length === 0 && <div className="text-xs mb-3" style={{color:'var(--status-sale)',fontWeight:700}}>⚠ Cần ít nhất 1 vai trò.</div>}
          <div className="grid grid-2 mb-3">
            <div>
              <div className="field-label">Trạng thái</div>
              <Segmented value={f.status} options={[
                {value:'active', label:'Hoạt động'},
                {value:'inactive', label:'Tạm khoá'},
              ]} onChange={(v) => { if (isSelf && v !== 'active') return window.tvsToast('Không thể tự khoá tài khoản đang đăng nhập', 'demo'); up('status', v); }}/>
              {f.status === 'pending' && <div className="text-xs fg-muted mt-1">Đang "Chờ kích hoạt" — tự chuyển Hoạt động ở lần đăng nhập đầu.</div>}
            </div>
            <div>
              <div className="field-label">Mật khẩu mới <span className="fg-muted" style={{fontWeight:400,textTransform:'none',letterSpacing:0}}>— để trống nếu giữ nguyên</span></div>
              <div className="row gap-2">
                <div style={{position:'relative',flex:1}}>
                  <input className="input" type={showPwd ? 'text' : 'password'} placeholder="Tối thiểu 6 ký tự" value={f.pwd} onChange={(e)=>up('pwd',e.target.value)} style={{paddingRight:36}}/>
                  <button type="button" title={showPwd ? 'Ẩn' : 'Hiện'} onClick={() => setShowPwd(v => !v)} style={{position:'absolute',right:6,top:'50%',transform:'translateY(-50%)',background:'none',border:'none',cursor:'pointer',color: showPwd ? 'var(--vs-dark-blue)' : 'var(--fg-muted)',display:'inline-flex',padding:2}}><Icon name="eye" size={15}/></button>
                </div>
                <button type="button" className="btn btn-secondary btn-sm" style={{flexShrink:0}} onClick={() => { up('pwd', genPwd()); setShowPwd(true); }}>Tạo</button>
              </div>
              {f.pwd && !pwdOk && <div className="text-xs mt-1" style={{color:'var(--status-sale)'}}>Mật khẩu cần ít nhất 6 ký tự</div>}
            </div>
          </div>
          <div className="text-xs fg-muted">{user._source === 'code' ? 'Tài khoản cài sẵn — phần chỉnh sửa lưu trong hệ thống, đè lên dữ liệu gốc.' : 'Tài khoản tạo trong app.'}{isSelf ? ' Đây là tài khoản của bạn.' : ''}</div>
        </div>
        <div style={{padding:'var(--space-4) var(--space-6)',borderTop:'1px solid var(--border-1)',background:'var(--bg-soft)',display:'flex',gap:'var(--space-3)',justifyContent:'flex-end'}}>
          <button className="btn btn-secondary" onClick={onClose}>Huỷ</button>
          <button className="btn btn-cta" disabled={!canSave} onClick={save}><Icon name="check" size={14}/>Lưu thay đổi</button>
        </div>
      </div>
    </div>
  );
}

// ===== Add user modal =====
function AddUserModal({ onClose, existingEmails = [], existingPhones = [] }) {
  const [f, setF] = useState({ name:'', email:'', phone:'', roles:['telesale'], status:'pending', pwd:'' });
  const [showPwd, setShowPwd] = useState(false);
  const genPwd = () => 'Tvs@' + Math.random().toString(36).slice(2, 6).toUpperCase() + Math.floor(100 + Math.random() * 900);
  const pwdOk = f.pwd.length >= 6;
  const [done, setDone] = useState(false);
  const up = (k,v) => setF(s => ({...s, [k]:v}));
  // 1 nhân sự có thể giữ nhiều vai trò — danh sách vị trí dùng CHUNG với ma trận phân quyền
  const ROLES = window.TVS_ROLE_DEFS;
  const roleLabel = (id) => (ROLES.find(r => r.id === id) || {}).label || id;
  const toggleRole = (id) => setF(s => ({
    ...s,
    roles: s.roles.includes(id) ? s.roles.filter(x => x !== id) : [...s.roles, id],
  }));
  // Đăng nhập bằng EMAIL hoặc SĐT — cần ít nhất 1 trong 2; ô nào đã điền thì phải hợp lệ và chưa trùng
  const emailFilled = f.email.trim().length > 0;
  const emailValid = /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(f.email.trim());
  const emailOk = emailFilled && emailValid;
  const emailDup = emailOk && existingEmails.includes(f.email.trim().toLowerCase());
  const phoneFilled = f.phone.trim().length > 0;
  const phoneOk = phoneFilled && window.tvsPhoneValid(f.phone);
  const phoneDup = phoneOk && existingPhones.includes(window.tvsNormPhone(f.phone));
  const loginIdOk = (emailOk && !emailDup) || (phoneOk && !phoneDup);
  const noInvalid = (!emailFilled || (emailValid && !emailDup)) && (!phoneFilled || (phoneOk && !phoneDup));
  // Team tự suy ra từ vai trò đầu tiên (bỏ mục chọn Team / Cửa hàng theo yêu cầu — giữ form tối giản)
  const autoTeam = ((ROLES.find(r => r.id === f.roles[0]) || {teams: []}).teams || [])[0] || '—';
  const canSave = f.name.trim() && loginIdOk && noInvalid && f.roles.length > 0 && pwdOk;
  const save = () => {
    window.TVS_SESSION.addUser({
      name: f.name, email: f.email.trim(), phone: phoneFilled ? window.tvsNormPhone(f.phone) : '', team: autoTeam, status: f.status,
      pwdHash: window.tvsHash(f.pwd), // KHÔNG lưu mật khẩu chữ thường
      role: f.roles.map(roleLabel).join(' · '),
      roles: f.roles,
      last: f.status === 'active' ? 'Vừa tạo' : 'Chưa kích hoạt', _new:true,
    });
    setDone(true);
    setTimeout(onClose, 1300);
  };
  return (
    <div className="drawer-overlay" style={{justifyContent:'center',alignItems:'center'}} onClick={onClose}>
      <div onClick={(e)=>e.stopPropagation()}
        style={{background:'var(--bg-page)',width:'min(560px,94vw)',maxHeight:'92vh',display:'flex',flexDirection:'column',borderRadius:'var(--radius-lg)',overflow:'hidden',boxShadow:'var(--shadow-pop)',animation:'slidein 0.28s var(--ease-out)'}}>
        <div style={{padding:'var(--space-5) var(--space-6)',background:'var(--vs-dark-blue)',color:'#fff',display:'flex',alignItems:'center',gap:'var(--space-3)'}}>
          <div style={{width:40,height:40,borderRadius:'50%',background:'var(--vs-light-blue)',color:'var(--vs-dark-blue)',display:'flex',alignItems:'center',justifyContent:'center'}}>
            <Icon name="user" size={20}/>
          </div>
          <div style={{flex:1}}>
            <div className="eyebrow" style={{color:'var(--vs-light-blue)'}}>Người dùng mới</div>
            <h3 style={{margin:'2px 0 0',fontFamily:'var(--font-display)',fontSize:18,fontWeight:700,color:'#fff'}}>{done ? 'Đã tạo tài khoản' : 'Tạo tài khoản nhân viên'}</h3>
          </div>
          <button onClick={onClose} style={{background:'rgba(255,255,255,0.18)',border:'none',color:'#fff',width:34,height:34,borderRadius:'50%',cursor:'pointer',display:'inline-flex',alignItems:'center',justifyContent:'center'}}>
            <Icon name="close" size={16}/>
          </button>
        </div>
        {done ? (
          <div style={{textAlign:'center',padding:'var(--space-8) var(--space-6)'}}>
            <div style={{width:72,height:72,borderRadius:'50%',background:'var(--status-success)',color:'#fff',display:'inline-flex',alignItems:'center',justifyContent:'center',marginBottom:'var(--space-4)'}}>
              <Icon name="check" size={36} stroke={3}/>
            </div>
            <div className="strong fg-1" style={{fontSize:18}}>{f.name}</div>
            <div className="text-sm fg-muted mt-2">Tài khoản: <b className="tnum">{[f.email.trim(), phoneFilled ? window.tvsNormPhone(f.phone) : ''].filter(Boolean).join(' / ')}</b> · vai trò <b>{f.roles.map(roleLabel).join(' · ')}</b></div>
            <div className="text-sm fg-muted mt-2">Đăng nhập bằng email hoặc SĐT trên + mật khẩu <b className="tnum" style={{color:'var(--vs-dark-blue)'}}>{f.pwd}</b>{f.status === 'pending' ? ' — tài khoản tự kích hoạt ở lần đăng nhập đầu' : ''}</div>
          </div>
        ) : (
          <>
            <div style={{padding:'var(--space-5) var(--space-6)',overflow:'auto',flex:1}}>
              <div className="mb-3">
                <div className="field-label">Họ và tên <span style={{color:'var(--status-sale)'}}>*</span></div>
                <input className="input" autoFocus placeholder="Nguyễn Văn A" value={f.name} onChange={(e)=>up('name',e.target.value)}/>
              </div>
              {/* Tên đăng nhập: email HOẶC số điện thoại — cần ít nhất 1 trong 2 */}
              <div className="field-label">Tên đăng nhập <span style={{color:'var(--status-sale)'}}>*</span> <span className="fg-muted" style={{fontWeight:400,textTransform:'none',letterSpacing:0}}>— điền email hoặc số điện thoại (chọn 1 trong 2, hoặc cả hai)</span></div>
              <div className="grid grid-2 mb-3">
                <div>
                  <div className="text-xs fg-muted mb-1">Email công ty</div>
                  <input className="input" placeholder="a.nv@tvs.vn" value={f.email} onChange={(e)=>up('email',e.target.value)}/>
                  {emailFilled && !emailValid && <div className="text-xs mt-1" style={{color:'var(--status-sale)'}}>Email không hợp lệ</div>}
                  {emailDup && <div className="text-xs mt-1" style={{color:'var(--status-sale)',fontWeight:700}}>⚠ Email đã tồn tại trong hệ thống</div>}
                </div>
                <div>
                  <div className="text-xs fg-muted mb-1">Số điện thoại</div>
                  <input className="input tnum" placeholder="0903 xxx xxx" value={f.phone} onChange={(e)=>up('phone',e.target.value)}/>
                  {phoneFilled && !phoneOk && <div className="text-xs mt-1" style={{color:'var(--status-sale)'}}>SĐT cần 9–11 chữ số</div>}
                  {phoneDup && <div className="text-xs mt-1" style={{color:'var(--status-sale)',fontWeight:700}}>⚠ SĐT đã tồn tại trong hệ thống</div>}
                </div>
              </div>
              {!emailFilled && !phoneFilled && (
                <div className="text-xs mb-3" style={{color:'var(--status-sale)',fontWeight:700}}>⚠ Cần ít nhất email hoặc số điện thoại để đăng nhập.</div>
              )}
              {/* Mật khẩu đăng nhập — Admin đặt, gửi cho nhân viên; tài khoản đăng nhập được ngay bằng email + mật khẩu này */}
              <div className="mb-3">
                <div className="field-label">Mật khẩu đăng nhập <span style={{color:'var(--status-sale)'}}>*</span> <span className="fg-muted" style={{fontWeight:400,textTransform:'none',letterSpacing:0}}>— tối thiểu 6 ký tự, gửi cho nhân viên để đăng nhập</span></div>
                <div className="row gap-2">
                  <div style={{position:'relative',flex:1}}>
                    <input className="input" type={showPwd ? 'text' : 'password'} placeholder="VD: Tvs@2026" value={f.pwd} onChange={(e)=>up('pwd',e.target.value)} style={{paddingRight:40}}/>
                    <button type="button" title={showPwd ? 'Ẩn mật khẩu' : 'Hiện mật khẩu'} onClick={() => setShowPwd(v => !v)}
                      style={{position:'absolute',right:8,top:'50%',transform:'translateY(-50%)',background:'none',border:'none',cursor:'pointer',color: showPwd ? 'var(--vs-dark-blue)' : 'var(--fg-muted)',display:'inline-flex',padding:2}}>
                      <Icon name="eye" size={16}/>
                    </button>
                  </div>
                  <button type="button" className="btn btn-secondary btn-sm" style={{flexShrink:0}} onClick={() => { up('pwd', genPwd()); setShowPwd(true); }}>
                    <Icon name="sparkles" size={12}/>Tạo ngẫu nhiên
                  </button>
                </div>
                {f.pwd && !pwdOk && <div className="text-xs mt-1" style={{color:'var(--status-sale)'}}>Mật khẩu cần ít nhất 6 ký tự</div>}
              </div>
              <div className="field-label">Vai trò <span style={{color:'var(--status-sale)'}}>*</span> <span className="fg-muted" style={{fontWeight:400,textTransform:'none',letterSpacing:0}}>— chọn nhiều nếu nhân sự kiêm việc</span></div>
              <div className="row gap-1 mb-2" style={{flexWrap:'wrap'}}>
                {ROLES.map(r => (
                  <button key={r.id} className={f.roles.includes(r.id) ? 'btn btn-cta btn-sm' : 'btn btn-secondary btn-sm'}
                    onClick={() => toggleRole(r.id)}>
                    {f.roles.includes(r.id) ? <Icon name="check" size={11}/> : <Icon name="plus" size={11}/>}{r.label}
                  </button>
                ))}
              </div>
              {f.roles.length === 0 && (
                <div className="text-xs mb-3" style={{color:'var(--status-sale)',fontWeight:700}}>⚠ Cần chọn ít nhất 1 vai trò.</div>
              )}
              {f.roles.length > 1 && (
                <div className="text-xs fg-muted mb-3">Mọi vị trí chăm sóc khách có cùng bộ quyền — chọn nhiều vai trò chỉ để ghi nhận kiêm nhiệm.</div>
              )}
              <div className="field-label">Trạng thái ban đầu</div>
              <Segmented value={f.status} options={[
                {value:'pending',label:'Chờ kích hoạt'},
                {value:'active',label:'Hoạt động ngay'},
              ]} onChange={(v)=>up('status',v)}/>
              <div className="banner mt-4">
                <Icon name="zap" size={16}/>
                <div className="text-sm" style={{flex:1}}>
                  Nhân viên chỉ thấy dữ liệu trong phạm vi vai trò — xem chi tiết ở bảng <b>Vai trò &amp; Quyền</b> bên dưới.
                </div>
              </div>
            </div>
            <div style={{padding:'var(--space-4) var(--space-6)',borderTop:'1px solid var(--border-1)',background:'var(--bg-soft)',display:'flex',gap:'var(--space-3)',justifyContent:'flex-end'}}>
              <button className="btn btn-secondary" onClick={onClose}>Huỷ</button>
              <button className="btn btn-cta" disabled={!canSave} onClick={save}>
                <Icon name="check" size={14}/>Tạo tài khoản
              </button>
            </div>
          </>
        )}
      </div>
    </div>
  );
}

// ===== Roles & Permissions =====
// Ma trận phân quyền THẬT: đọc/ghi bộ quyền trung tâm (TVS_PERM_DEFS + TVS_SESSION.permissions).
// Lưu là áp dụng ngay cho toàn app: menu, ⌘K, nút thêm/sửa khách, ghi đơn, thêm/xoá sản phẩm...
function RolesTab() {
  // QUY TẮC: chỉ 2 cột — Admin (khoá, toàn quyền) và NHÂN VIÊN CHĂM SÓC KHÁCH (mọi vị trí dùng chung 1 bộ quyền).
  // Sửa cột Nhân viên = áp cho TẤT CẢ vị trí không phải Admin.
  // + cột Marketing riêng: bộ quyền nhân viên KHÔNG gồm 'gán khách', Marketing thì có
  const STAFF_IDS = window.TVS_ROLE_DEFS.filter(r => r.id !== 'manager' && r.id !== 'marketing').map(r => r.id);
  const ROLES = [
    { key: 'manager',   label: 'Admin' },
    { key: 'staff',     label: 'Nhân viên chăm sóc khách (mọi vị trí)' },
    { key: 'marketing', label: 'Marketing' },
  ];
  const defs = window.TVS_PERM_DEFS || [];
  // Quyền hiệu lực hiện tại (mặc định + tuỳ chỉnh đã lưu) → ma trận 0/1; cột nhân viên đọc từ 1 vị trí đại diện
  const effective = () => ROLES.map(r => defs.map(d => window.tvsCan(r.key === 'staff' ? STAFF_IDS[0] : r.key, d.id) ? 1 : 0));
  const [grid, setGrid] = useState(effective);
  const [savedGrid, setSavedGrid] = useState(effective);
  const dirtyCount = grid.reduce((n, row, ri) => n + row.reduce((m, v, ci) => m + (v !== savedGrid[ri][ci] ? 1 : 0), 0), 0);
  const toggle = (ri, ci) => {
    if (ROLES[ri].key === 'manager') { window.tvsToast('Quyền Admin luôn bật đầy đủ — không thể tự khoá', 'demo'); return; }
    setGrid(g => g.map((row, i) => i === ri ? row.map((v, j) => j === ci ? (v ? 0 : 1) : v) : row));
  };
  const save = () => {
    const map = {};
    const staffRow = grid[ROLES.findIndex(r => r.key === 'staff')];
    const staffList = defs.filter((d, ci) => staffRow[ci] === 1).map(d => d.id);
    STAFF_IDS.forEach(id => { map[id] = staffList; }); // cùng một bộ quyền cho mọi vị trí chăm sóc khách
    const mkRow = grid[ROLES.findIndex(r => r.key === 'marketing')];
    map.marketing = defs.filter((d, ci) => mkRow[ci] === 1).map(d => d.id);
    window.TVS_SESSION.setPermissions(map);
    setSavedGrid(grid.map(r => [...r]));
    window.tvsToast('Đã lưu phân quyền — áp dụng ngay cho toàn hệ thống');
  };
  const resetDefaults = () => {
    window.TVS_SESSION.setPermissions({});
    const g = ROLES.map(r => defs.map(d => {
      const list = r.key === 'manager' ? '*' : r.key === 'marketing' ? (window.TVS_MARKETING_PERMS || []) : (window.TVS_STAFF_PERMS || []);
      return list === '*' || list.includes(d.id) ? 1 : 0;
    }));
    setGrid(g.map(r => [...r]));
    setSavedGrid(g.map(r => [...r]));
    window.tvsToast('Đã khôi phục phân quyền mặc định');
  };
  return (
    <Card pad={false}>
      <CardHeader title="Vai trò & Phân quyền"
        sub={`Quy tắc: mọi vị trí chăm sóc khách (${STAFF_IDS.length} vị trí) dùng CHUNG một bộ quyền; Marketing có thêm quyền gán khách cho nhân viên bán hàng; chỉ Admin toàn quyền. Bấm ô để bật / tắt, Lưu là áp dụng ngay`}
        actions={<button className="btn btn-secondary btn-sm" onClick={resetDefaults}><Icon name="refresh" size={12}/>Khôi phục mặc định</button>}/>
      <div className="table-wrap">
        <table className="tbl tbl--matrix">
          <thead>
            <tr>
              <th style={{minWidth:220}}>Quyền</th>
              {ROLES.map(r => <th key={r.key} className="num" style={{minWidth:160}}>{r.label}</th>)}
            </tr>
          </thead>
          <tbody>
            {defs.map((d, i) => (
              <tr key={d.id}>
                <td>{d.label}</td>
                {ROLES.map((r, ri) => (
                  <td key={r.key} className="num">
                    <button onClick={() => toggle(ri, i)} title={r.key === 'manager' ? 'Admin luôn có đủ quyền' : 'Bấm để đổi'}
                      style={{border:'none',background:'none',padding:0,cursor: r.key === 'manager' ? 'not-allowed' : 'pointer'}}>
                      {grid[ri][i] === 1 ? (
                        <span style={{display:'inline-flex',width:20,height:20,borderRadius:4,background:'var(--status-success)',color:'#fff',alignItems:'center',justifyContent:'center'}}>
                          <Icon name="check" size={14} stroke={3}/>
                        </span>
                      ) : (
                        <span style={{display:'inline-flex',width:20,height:20,borderRadius:4,background:'var(--bg-soft)',color:'var(--fg-muted)',alignItems:'center',justifyContent:'center'}}>
                          <Icon name="close" size={12}/>
                        </span>
                      )}
                    </button>
                  </td>
                ))}
              </tr>
            ))}
          </tbody>
        </table>
      </div>
      <div style={{padding:'var(--space-4) var(--space-5)',background:'var(--bg-soft)',borderTop:'1px solid var(--border-1)',display:'flex',gap:'var(--space-3)',alignItems:'center'}}>
        <span className="text-sm fg-muted">{dirtyCount > 0 ? `${dirtyCount} thay đổi chưa lưu` : 'Chưa có thay đổi'}</span>
        <div style={{flex:1}}/>
        <button className="btn btn-ghost" disabled={dirtyCount === 0}
          onClick={() => { setGrid(savedGrid.map(r => [...r])); window.tvsToast('Đã huỷ thay đổi'); }}>Huỷ</button>
        <button className="btn btn-cta" disabled={dirtyCount === 0} onClick={save}>Lưu thay đổi</button>
      </div>
    </Card>
  );
}

// ===== Integrations tab =====
function IntegrationsTab() {
  const integrations = [
    {
      key:'sapo',
      name:'Sapo POS & ERP',
      desc:'Đồng bộ sản phẩm, tồn kho, đơn hàng B2C/B2B từ Sapo về CRM',
      icon:'cart',
      status:'connected',
      lastSync:'2 phút trước',
      details:'1.247 sản phẩm · 12 chi nhánh kho · API key đã cấu hình',
      color:'#0FA958',
    },
    {
      key:'zalo',
      name:'Zalo Official Account',
      desc:'Gửi tin nhắn ZNS, nhận inbox, broadcast chiến dịch',
      icon:'chat',
      status:'connected',
      lastSync:'Realtime',
      details:'OA "The Vitamin Shoppe VN" · 12.4K followers · 8 ZNS templates đã duyệt',
      color:'#0068FF',
    },
    {
      key:'sms',
      name:'SMS Brandname Viettel',
      desc:'Gửi SMS marketing & OTP',
      icon:'mail',
      status:'connected',
      lastSync:'8 phút trước',
      details:'Brand: TVS · Quota 50.000 SMS/tháng · còn 38.420',
      color:'#FF0000',
    },
    {
      key:'email',
      name:'SendGrid Email',
      desc:'Gửi email transactional + marketing campaigns',
      icon:'mail',
      status:'connected',
      lastSync:'Realtime',
      details:'Sender domain xác thực · Quota 200K email/tháng',
      color:'#1A82E2',
    },
    {
      key:'shipper',
      name:'GHN · GHTK · VNPost',
      desc:'Tạo & track vận đơn B2B',
      icon:'truck',
      status:'connected',
      lastSync:'1 giờ trước',
      details:'3 đối tác giao hàng · webhook tracking auto-update',
      color:'#FF6600',
    },
    {
      key:'tiktok',
      name:'TikTok Shop Affiliate',
      desc:'Đồng bộ KOC/affiliate, tracking link, hoa hồng',
      icon:'sparkles',
      status:'pending',
      lastSync:'Chưa kết nối',
      details:'Đang đợi approval shop B2B từ TikTok',
      color:'#000000',
    },
    {
      key:'misa',
      name:'MISA Kế toán',
      desc:'Đẩy số liệu doanh thu sang phần mềm kế toán',
      icon:'fileText',
      status:'available',
      lastSync:'Chưa kết nối',
      details:'Plugin có sẵn — cấu hình 10 phút',
      color:'#E60012',
    },
    {
      key:'callcenter',
      name:'StringeeX Call Center',
      desc:'Click-to-call, ghi âm cuộc gọi, IVR',
      icon:'phone',
      status:'connected',
      lastSync:'Realtime',
      details:'12 extension · 4 hunting group · ghi âm 90 ngày',
      color:'#7C3AED',
    },
  ];
  return (
    <>
      <div className="banner mb-4">
        <Icon name="zap" size={16}/>
        <div className="text-sm" style={{flex:1}}>
          <b>{integrations.filter(i => i.status === 'connected').length}/{integrations.length} dịch vụ đã kết nối.</b> Tích hợp giúp CRM nhận data từ Sapo, đồng bộ Zalo OA, và gửi SMS/Email tự động.
        </div>
      </div>
      <div className="grid grid-2" style={{gap:'var(--space-3)'}}>
        {integrations.map(it => (
          <Card key={it.key} className="row gap-4" style={{alignItems:'flex-start'}}>
            <div style={{width:48,height:48,borderRadius:'var(--radius-md)',background: it.color + '12',color: it.color,display:'flex',alignItems:'center',justifyContent:'center',flexShrink:0}}>
              <Icon name={it.icon} size={24}/>
            </div>
            <div style={{flex:1,minWidth:0}}>
              <div className="row mb-1">
                <h4 style={{margin:0,fontSize:'var(--t-md)',color:'var(--fg-1)'}}>{it.name}</h4>
                <Tag variant={it.status==='connected'?'success':it.status==='pending'?'warning':'outline'} dot style={{marginLeft:'auto'}}>
                  {it.status==='connected' ? 'Đã kết nối' : it.status==='pending' ? 'Đang chờ' : 'Chưa kết nối'}
                </Tag>
              </div>
              <div className="text-sm fg-2 mb-2" style={{lineHeight:1.5}}>{it.desc}</div>
              <div className="text-xs fg-muted">{it.details}</div>
              <div className="row mt-3" style={{justifyContent:'space-between'}}>
                <span className="text-xs fg-muted">Đồng bộ: {it.lastSync}</span>
                <button className={it.status==='connected' ? 'btn btn-ghost btn-sm' : 'btn btn-cta btn-sm'} onClick={() => window.tvsDemo(it.status==='connected' ? 'Cấu hình ' + it.name : 'Kết nối ' + it.name)}>
                  {it.status==='connected' ? 'Cấu hình' : it.status==='pending' ? 'Kiểm tra' : 'Kết nối'}
                </button>
              </div>
            </div>
          </Card>
        ))}
      </div>
    </>
  );
}

// ===== Pricelist tab =====
function PricelistTab() {
  const [active, setActive] = useState('B2C Bán lẻ');
  const lists = ['B2C Bán lẻ','Pharmacy Chain','Enterprise Chain','Gym & PT','Affiliate KOC','Spa & Clinic','Wholesale Tier 1','Enterprise B2B'];
  // Mỗi bảng giá đối tác có hệ số riêng trên giá B2B gốc — đổi bảng là đổi giá thật
  const TIER_MULT = {
    'Pharmacy Chain': 1.0, 'Enterprise Chain': 0.94, 'Gym & PT': 1.02,
    'Affiliate KOC': 1.05, 'Spa & Clinic': 1.04, 'Wholesale Tier 1': 0.90, 'Enterprise B2B': 0.92,
  };
  return (
    <>
      <div className="row gap-2 mb-4" style={{flexWrap:'wrap'}}>
        {lists.map(l => (
          <button key={l}
            className={l===active ? 'btn btn-cta' : 'btn btn-secondary'}
            onClick={() => setActive(l)}>
            {l}
          </button>
        ))}
        <button className="btn btn-ghost" onClick={() => window.tvsDemo('Tạo bảng giá mới')}><Icon name="plus" size={14}/>Tạo bảng giá mới</button>
      </div>
      <Card pad={false}>
        <CardHeader title={`Bảng giá: ${active}`}
          sub={active === 'B2C Bán lẻ' ? 'Giá lẻ áp dụng cho khách cá nhân tại cửa hàng / web / app' : 'Áp dụng cho đối tác — chiết khấu so với giá lẻ'}
          actions={
            <div className="row gap-2">
              <button className="btn btn-secondary btn-sm" onClick={() => window.tvsDemo('Xuất Excel bảng giá')}><Icon name="download" size={12}/>Xuất Excel</button>
              <button className="btn btn-cta btn-sm" onClick={() => window.tvsDemo('Thêm sản phẩm vào bảng giá')}><Icon name="plus" size={12}/>Thêm SP</button>
            </div>
          }/>
        <div className="table-wrap">
          <table className="tbl">
            <thead>
              <tr>
                <th>SKU</th>
                <th>Sản phẩm</th>
                <th>Danh mục</th>
                <th className="num">Giá lẻ</th>
                <th className="num">Giá {active}</th>
                <th className="num">Chiết khấu</th>
                <th className="num">SL tối thiểu</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {D.products.map(p => {
                const isRetail = active === 'B2C Bán lẻ';
                const partnerPrice = isRetail ? p.price : Math.round(p.b2bPrice * (TIER_MULT[active] || 1) / 1000) * 1000;
                const discount = isRetail ? 0 : Math.round(((p.price - partnerPrice) / p.price) * 100);
                return (
                  <tr key={p.sku}>
                    <td className="tnum text-xs fg-muted">{p.sku}</td>
                    <td className="strong">{p.name}</td>
                    <td><Tag variant="outline">{p.cat}</Tag></td>
                    <td className="num tnum">{fmt.vndFull(p.price)}</td>
                    <td className="num strong">{fmt.vndFull(partnerPrice)}</td>
                    <td className="num">
                      {discount > 0 ? <Tag variant="success">-{discount}%</Tag> : <span className="text-xs fg-muted">—</span>}
                    </td>
                    <td className="num tnum">{isRetail ? '1' : active.includes('Tier') ? '50' : active.includes('Enterprise') ? '200' : '20'}</td>
                    <td><button className="btn btn-icon btn-sm btn-ghost" title="Sửa giá" onClick={() => window.tvsDemo('Sửa giá ' + p.sku)}><Icon name="note" size={14}/></button></td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      </Card>
    </>
  );
}

// ===== Data & Backup =====
function DataTab({ role }) {
  const [showImport, setShowImport] = useState(false); // modal nhập khách từ file
  return (
    <>
      <div className="grid grid-2 mb-4">
        <Card>
          <h3 style={{margin:'0 0 var(--space-3)',fontSize:'var(--t-md)',color:'var(--fg-1)'}}>Nhập dữ liệu</h3>
          <div className="text-sm fg-2 mb-3" style={{lineHeight:1.5}}>Tải lên file Excel/CSV để import danh sách khách hàng, sản phẩm, hoặc đơn hàng cũ.</div>
          <div className="col gap-2">
            <button className="btn btn-secondary" style={{justifyContent:'flex-start'}} onClick={() => { if (!tvsCan(role, 'customers.import')) return window.tvsDenied(); setShowImport(true); }}><Icon name="users" size={14}/>Import khách hàng (.csv / .xlsx)</button>
            <button className="btn btn-secondary" style={{justifyContent:'flex-start'}} onClick={() => window.tvsDemo('Import đối tác B2B')}><Icon name="handshake" size={14}/>Import đối tác B2B</button>
            <button className="btn btn-secondary" style={{justifyContent:'flex-start'}} onClick={() => window.tvsDemo('Import lịch sử đơn hàng')}><Icon name="receipt" size={14}/>Import lịch sử đơn hàng</button>
          </div>
        </Card>
        <Card>
          <h3 style={{margin:'0 0 var(--space-3)',fontSize:'var(--t-md)',color:'var(--fg-1)'}}>Xuất dữ liệu</h3>
          <div className="text-sm fg-2 mb-3" style={{lineHeight:1.5}}>Xuất toàn bộ hoặc theo bộ lọc — phục vụ phân tích, GDPR, hoặc backup nội bộ.</div>
          <div className="col gap-2">
            <button className="btn btn-secondary" style={{justifyContent:'flex-start'}} onClick={() => window.tvsDemo('Export danh sách khách (CSV)')}><Icon name="download" size={14}/>Export tất cả khách (CSV)</button>
            <button className="btn btn-secondary" style={{justifyContent:'flex-start'}} onClick={() => window.tvsDemo('Export lịch sử đơn 12 tháng')}><Icon name="download" size={14}/>Export lịch sử đơn 12 tháng</button>
            <button className="btn btn-secondary" style={{justifyContent:'flex-start'}} onClick={() => window.tvsDemo('Export báo cáo doanh số')}><Icon name="download" size={14}/>Export báo cáo doanh số</button>
          </div>
        </Card>
      </div>

      <Card pad={false}>
        <CardHeader title="Backup tự động" sub="Sao lưu hàng ngày lên cloud — an toàn dữ liệu"/>
        <div className="card-pad">
          <div className="row mb-3">
            <div style={{width:40,height:40,background:'rgba(6,167,125,0.10)',color:'var(--status-success)',borderRadius:'var(--radius-md)',display:'flex',alignItems:'center',justifyContent:'center'}}>
              <Icon name="check" size={20}/>
            </div>
            <div style={{flex:1}}>
              <div className="strong fg-1">Backup hoạt động bình thường</div>
              <div className="text-xs fg-muted">Backend sẽ tự sao lưu theo lịch — thông tin hiển thị ở đây</div>
            </div>
            <Tag variant="success" dot>Active</Tag>
          </div>
          <div className="divider mb-3"/>
          <div className="grid grid-3">
            <div>
              <div className="text-xs fg-muted">Tần suất</div>
              <div className="strong fg-1 mt-1">Hàng ngày, 03:00</div>
            </div>
            <div>
              <div className="text-xs fg-muted">Lưu trữ</div>
              <div className="strong fg-1 mt-1">AWS S3 (Singapore)</div>
            </div>
            <div>
              <div className="text-xs fg-muted">Retention</div>
              <div className="strong fg-1 mt-1">90 ngày</div>
            </div>
          </div>
        </div>
      </Card>

      {showImport && window.ImportCustomersModal && (
        <ImportCustomersModal role={role} onClose={() => setShowImport(false)}/>
      )}
    </>
  );
}

window.SettingsScreen = SettingsScreen;
