// AdminApp — Manager/Admin panel with three sections:
//  1. Schedule users' work calendars
//  2. Approve/reject leave requests
//  3. Set agreed daily price per store

const { useState: useStateA, useMemo: useMemoA } = React;

const A_WEEKDAYS = ['ش', 'ی', 'د', 'س', 'چ', 'پ', 'ج'];
const A_DAYS_IN_MONTH = 31;
const A_FIRST_OFFSET = 0;

const LEAVE_TYPE_LABEL = {
  personal: 'استحقاقی',
  sick:     'استعلاجی',
  unpaid:   'بدون حقوق',
  mission:  'ماموریت',
};

// Five access levels, by reach. `level` orders the hierarchy; a superior must
// outrank the person reporting to them.
const ROLE_META = {
  promoter:       { label: 'پروموتور', level: 1 },
  supervisor:     { label: 'سرپرست',   level: 2 },
  manager:        { label: 'مدیر',      level: 3 },
  senior_manager: { label: 'مدیر ارشد', level: 4 },
  admin:          { label: 'ادمین',     level: 5 },
};
const ROLE_LABEL_A = (role) => ROLE_META[role]?.label || role;
const FULL_ACCESS_ROLES_A = ['admin', 'senior_manager'];

// ============================================================
// Top-level Admin shell with three tabs
// ============================================================

function AdminApp() {
  const [tab, setTab] = useStateA('schedule'); // schedule | performance | leaves | users | pricing | products | inventory | messages
  const app = window.useAppStore();

  const pendingLeaves = app.leaves.filter(l => l.status === 'pending').length;
  const unreadMessages = app.inbox.filter(m => !m.read).length;

  // The shared catalogues and user management belong to full-access roles only;
  // managers and supervisors get the team-scoped tabs.
  const isFullAccess = FULL_ACCESS_ROLES_A.includes(app.session?.role);
  // Projects are defined by managers and up (not supervisors).
  const canProjects = ['admin', 'senior_manager', 'manager'].includes(app.session?.role);
  const tabs = [
    { id: 'schedule', label: 'تقویم' },
    { id: 'performance', label: 'عملکرد' },
    { id: 'leaves',   label: 'مرخصی‌ها', badge: pendingLeaves },
    ...(isFullAccess ? [{ id: 'users', label: 'کاربران' }] : []),
    ...(canProjects ? [{ id: 'projects', label: 'پروژه‌ها' }] : []),
    ...(isFullAccess ? [
      { id: 'pricing',  label: 'فروشگاه‌ها' },
      { id: 'products', label: 'سمپل' },
      { id: 'inventory', label: 'موجودی' },
    ] : []),
    { id: 'messages', label: 'پیام‌ها', badge: unreadMessages },
  ];

  return (
    <div style={{
      direction: 'rtl', background: 'var(--bg)', height: '100%',
      fontFamily: 'Vazirmatn, system-ui, sans-serif', color: 'var(--ink)',
      display: 'flex', flexDirection: 'column', overflow: 'hidden',
    }}>
      <AdminHeader />

      {/* tabs */}
      <div style={{
        display: 'flex', gap: 4, padding: '4px 14px 8px',
        flexShrink: 0,
      }}>
        {tabs.map(t => {
          const active = tab === t.id;
          return (
            <button key={t.id}
              onClick={() => setTab(t.id)}
              style={{
                all: 'unset', cursor: 'pointer', flex: 1,
                textAlign: 'center', padding: '9px 4px',
                borderRadius: 10,
                background: active ? 'var(--ink)' : 'var(--surface)',
                color: active ? 'var(--bg)' : 'var(--ink)',
                border: active ? '1px solid var(--ink)' : '1px solid var(--border)',
                fontSize: 11.5, fontWeight: 600,
                position: 'relative',
                transition: 'all 160ms ease',
              }}>
              {t.label}
              {t.badge > 0 && (
                <span style={{
                  position: 'absolute', top: 4, right: 4,
                  minWidth: 16, height: 16, borderRadius: 99,
                  background: 'var(--danger)', color: '#fff',
                  fontSize: 9, fontWeight: 700,
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  padding: '0 4px',
                }}>{window.faNumS(t.badge)}</span>
              )}
            </button>
          );
        })}
      </div>

      <div style={{ flex: 1, minHeight: 0, overflow: 'hidden' }}>
        {tab === 'schedule' && <ScheduleTab />}
        {tab === 'performance' && <PerformanceTab />}
        {tab === 'leaves'   && <LeavesTab />}
        {tab === 'users'    && <UsersTab />}
        {tab === 'projects' && <ProjectsTab />}
        {tab === 'pricing'  && <PricingTab />}
        {tab === 'products' && <ProductsTab />}
        {tab === 'inventory' && <InventoryProductsTab />}
        {tab === 'messages' && <window.MessagesScreen embedded />}
      </div>
    </div>
  );
}

function AdminHeader() {
  const app = window.useAppStore();
  const user = window.getUserById(app.session?.userId);
  return (
    <div style={{
      padding: '14px 18px 10px', flexShrink: 0,
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <div style={{
          width: 38, height: 38, borderRadius: 11,
          background: 'var(--ink)', color: 'var(--bg)',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontWeight: 700, fontSize: 13,
        }}>{user?.initials || 'م'}</div>
        <div>
          <div style={{ fontSize: 14, fontWeight: 700 }}>پنل مدیریت</div>
          <div style={{ fontSize: 11, color: 'var(--muted)' }}>
            {user?.name || 'مدیر'} · {ROLE_LABEL_A(user?.role)}
          </div>
        </div>
      </div>
      <div style={{ display: 'flex', gap: 8 }}>
        <button style={{
          all: 'unset', cursor: 'pointer', position: 'relative',
          width: 38, height: 38, borderRadius: 99,
          background: 'var(--surface)', border: '1px solid var(--border)',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          color: 'var(--ink)',
        }}>
          <window.IconBell size={18} />
        </button>
        <button
          onClick={() => window.appActions.logout()}
          title="خروج"
          style={{
            all: 'unset', cursor: 'pointer',
            width: 38, height: 38, borderRadius: 99,
            background: 'var(--surface)', border: '1px solid var(--border)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            color: 'var(--muted)',
          }}>
          <window.IconLogout size={16} />
        </button>
      </div>
    </div>
  );
}

// ============================================================
// Tab 1 — Schedule users' work calendars
// ============================================================

function ScheduleTab() {
  const app = window.useAppStore();
  // Visits are scheduled for field workers (promoters) within this user's reach.
  const promoters = app.users.filter(u => u.role === 'promoter' || u.role === 'user');
  const [userId, setUserId] = useStateA(promoters[0]?.id || null);
  const [day, setDay] = useStateA(null);
  const [pickerOpen, setPickerOpen] = useStateA(false);

  const assignments = (userId && app.assignments[userId]) || {};
  const visits = day ? (assignments[day] || []) : [];

  if (promoters.length === 0) {
    return (
      <div style={{ textAlign: 'center', padding: '40px 20px', fontSize: 13, color: 'var(--muted)' }}>
        هنوز پروموتوری در زیرمجموعه‌ی شما نیست
      </div>
    );
  }

  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
      {/* user picker */}
      <div style={{ padding: '6px 14px 10px', flexShrink: 0 }}>
        <div style={{
          fontSize: 10.5, color: 'var(--muted)', letterSpacing: '0.04em',
          marginBottom: 6, fontWeight: 500, padding: '0 2px',
        }}>پروموتور</div>
        <div style={{
          display: 'flex', gap: 6, overflowX: 'auto', paddingBottom: 2,
          scrollbarWidth: 'none',
        }}>
          {promoters.map(u => {
            const active = u.id === userId;
            return (
              <button key={u.id}
                onClick={() => { setUserId(u.id); setDay(null); }}
                style={{
                  all: 'unset', cursor: 'pointer',
                  padding: '8px 12px',
                  borderRadius: 99,
                  background: active ? 'var(--ink)' : 'var(--surface)',
                  color: active ? 'var(--bg)' : 'var(--ink)',
                  border: active ? '1px solid var(--ink)' : '1px solid var(--border)',
                  fontSize: 12, fontWeight: 600,
                  whiteSpace: 'nowrap',
                  display: 'inline-flex', alignItems: 'center', gap: 7,
                }}>
                <span style={{
                  width: 20, height: 20, borderRadius: 99,
                  background: active ? 'rgba(255,255,255,0.15)' : 'var(--icon-bg)',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  fontSize: 9, fontWeight: 700,
                }}>{u.initials}</span>
                {u.name.split(' ')[0]}
              </button>
            );
          })}
        </div>
      </div>

      <div style={{ flex: 1, overflowY: 'auto', padding: '0 14px 14px' }}>
        {/* month label */}
        <div style={{
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          padding: '4px 8px 10px',
        }}>
          <button style={{ all: 'unset', cursor: 'pointer', padding: 4, color: 'var(--muted)' }}>
            <window.IconChevron size={14} dir="right" />
          </button>
          <div style={{ fontSize: 13, fontWeight: 600 }}>خرداد ۱۴۰۵</div>
          <button style={{ all: 'unset', cursor: 'pointer', padding: 4, color: 'var(--muted)' }}>
            <window.IconChevron size={14} dir="left" />
          </button>
        </div>

        <ScheduleCalendar
          assignments={assignments}
          today={app.today}
          selected={day}
          onSelect={setDay}
        />

        {day && (
          <DayAssignmentEditor
            userId={userId}
            day={day}
            visits={visits}
            onAddRequest={() => setPickerOpen(true)}
          />
        )}
      </div>

      {pickerOpen && (
        <StorePickerSheet
          userId={userId}
          day={day}
          existingIds={visits.map(v => v.storeId)}
          onClose={() => setPickerOpen(false)}
        />
      )}
    </div>
  );
}

function ScheduleCalendar({ assignments, today, selected, onSelect }) {
  const cells = [];
  for (let i = 0; i < A_FIRST_OFFSET; i++) cells.push({ blank: true, key: `b${i}` });
  for (let d = 1; d <= A_DAYS_IN_MONTH; d++) cells.push({ day: d, key: `d${d}` });

  return (
    <div>
      <div style={{
        display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)',
        gap: 2, marginBottom: 4,
      }}>
        {A_WEEKDAYS.map(w => (
          <div key={w} style={{
            textAlign: 'center', fontSize: 10.5, fontWeight: 600,
            color: 'var(--muted)', padding: '4px 0',
          }}>{w}</div>
        ))}
      </div>
      <div style={{
        display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 2,
      }}>
        {cells.map(c => {
          if (c.blank) return <div key={c.key} />;
          const visits = assignments[c.day] || [];
          const count = visits.length;
          const isToday = c.day === today;
          const isSelected = c.day === selected;
          const isPast = c.day < today;

          let total = 0;
          visits.forEach(v => {
            total += (window.getStoreById(v.storeId)?.price || 0);
          });

          return (
            <button
              key={c.key}
              onClick={() => onSelect(c.day)}
              style={{
                all: 'unset', cursor: 'pointer',
                aspectRatio: '1 / 1.15',
                borderRadius: 10,
                position: 'relative',
                display: 'flex', flexDirection: 'column',
                alignItems: 'center', justifyContent: 'center', gap: 2,
                background: isSelected
                  ? 'var(--accent)'
                  : count > 0
                    ? 'color-mix(in oklab, var(--accent) 9%, transparent)'
                    : isToday
                      ? 'color-mix(in oklab, var(--accent) 5%, transparent)'
                      : 'transparent',
                color: isSelected ? '#fff'
                  : isPast && !isToday ? 'var(--muted)' : 'var(--ink)',
                border: isToday && !isSelected ? '1px solid var(--accent)' : '1px solid transparent',
                transition: 'background 160ms ease',
              }}>
              <span style={{
                fontSize: 13, fontWeight: isSelected || isToday ? 700 : 500,
                fontVariantNumeric: 'tabular-nums',
              }}>{window.faNumS(c.day)}</span>
              {count > 0 && (
                <span style={{
                  fontSize: 8.5, fontWeight: 700,
                  color: isSelected ? '#fff' : 'var(--accent)',
                  opacity: isSelected ? 0.95 : 1,
                }}>{window.faNumS(count)} ویزیت</span>
              )}
            </button>
          );
        })}
      </div>
    </div>
  );
}

function DayAssignmentEditor({ userId, day, visits, onAddRequest }) {
  const total = visits.reduce((acc, v) => acc + (window.getStoreById(v.storeId)?.price || 0), 0);
  return (
    <div style={{ marginTop: 16 }}>
      <div style={{
        display: 'flex', alignItems: 'baseline', justifyContent: 'space-between',
        padding: '0 4px 8px',
      }}>
        <div style={{ fontSize: 12, fontWeight: 700, color: 'var(--ink)' }}>
          {window.faNumS(day)} خرداد · {window.faNumS(visits.length)} ویزیت
        </div>
        <div style={{
          fontSize: 11, fontWeight: 700, color: 'var(--accent)',
          fontFamily: 'JetBrains Mono, ui-monospace, monospace',
          fontVariantNumeric: 'tabular-nums',
        }}>{window.fmtToman(total)}</div>
      </div>

      <div style={{
        background: 'var(--surface)', border: '1px solid var(--border)',
        borderRadius: 14, overflow: 'hidden',
      }}>
        {visits.length === 0 ? (
          <div style={{
            padding: '18px 14px', textAlign: 'center',
            fontSize: 12, color: 'var(--muted)',
          }}>برای این روز فروشگاهی تعیین نشده</div>
        ) : visits.map((v, i) => {
          const store = window.getStoreById(v.storeId);
          if (!store) return null;
          return (
            <div key={i} style={{
              display: 'flex', alignItems: 'center', gap: 10,
              padding: '10px 12px',
              borderTop: i ? '1px solid var(--border)' : 'none',
            }}>
              <div style={{
                fontSize: 11, color: 'var(--muted)',
                fontFamily: 'JetBrains Mono, ui-monospace, monospace',
                width: 38, flexShrink: 0,
              }}>{v.time}</div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{
                  fontSize: 12.5, fontWeight: 600, color: 'var(--ink)',
                  overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                }}>{store.name}</div>
                <div style={{ fontSize: 10.5, color: 'var(--muted)' }}>
                  {store.addr} · <span style={{ color: 'var(--accent)', fontWeight: 600 }}>{window.fmtToman(store.price)}</span>
                </div>
              </div>
              <button
                onClick={() => window.appActions.removeAssignment(userId, day, store.id)}
                style={{
                  all: 'unset', cursor: 'pointer',
                  width: 28, height: 28, borderRadius: 8,
                  background: 'var(--icon-bg)',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  color: 'var(--danger)',
                }}>
                <window.IconTrash size={14} color="currentColor" />
              </button>
            </div>
          );
        })}
        <button
          onClick={onAddRequest}
          style={{
            all: 'unset', cursor: 'pointer', width: '100%', boxSizing: 'border-box',
            padding: '12px 14px',
            borderTop: visits.length ? '1px solid var(--border)' : 'none',
            display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6,
            fontSize: 12.5, fontWeight: 700, color: 'var(--accent)',
            background: 'color-mix(in oklab, var(--accent) 5%, transparent)',
          }}>
          <window.IconPlus size={16} color="currentColor" />
          <span>افزودن فروشگاه</span>
        </button>
      </div>
    </div>
  );
}

function StorePickerSheet({ userId, day, existingIds, onClose }) {
  const app = window.useAppStore();
  const available = app.stores.filter(s => !existingIds.includes(s.id));
  const [time, setTime] = useStateA(window.SLOTS[0]);
  const [selectedStore, setSelectedStore] = useStateA(null);

  const handleAdd = () => {
    if (!selectedStore) return;
    window.appActions.addAssignment(userId, day, selectedStore, time);
    onClose();
  };

  return (
    <>
      <div onClick={onClose}
           style={{
             position: 'absolute', inset: 0, background: 'rgba(8,10,10,0.45)',
             zIndex: 20,
           }} />
      <div style={{
        position: 'absolute', left: 0, right: 0, bottom: 0,
        background: 'var(--surface)',
        borderTopLeftRadius: 22, borderTopRightRadius: 22,
        padding: '12px 18px 18px',
        boxShadow: '0 -10px 40px rgba(0,0,0,0.18)',
        zIndex: 21, direction: 'rtl', maxHeight: '78%',
        display: 'flex', flexDirection: 'column',
      }}>
        <div style={{
          width: 40, height: 4, borderRadius: 99,
          background: 'var(--border)', margin: '0 auto 12px',
        }} />
        <div style={{
          display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
          marginBottom: 12,
        }}>
          <div>
            <div style={{ fontSize: 15, fontWeight: 700 }}>افزودن فروشگاه</div>
            <div style={{ fontSize: 11, color: 'var(--muted)' }}>روز {window.faNumS(day)} خرداد</div>
          </div>
          <button onClick={onClose} style={{
            all: 'unset', cursor: 'pointer',
            width: 28, height: 28, borderRadius: 99,
            background: 'var(--icon-bg)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            color: 'var(--ink)',
          }}>
            <window.IconClose size={14} />
          </button>
        </div>

        {/* time picker */}
        <div style={{
          fontSize: 10.5, color: 'var(--muted)', marginBottom: 6, fontWeight: 500,
        }}>ساعت</div>
        <div style={{
          display: 'flex', gap: 6, overflowX: 'auto',
          marginBottom: 14, paddingBottom: 2,
        }}>
          {window.SLOTS.map(s => (
            <button key={s}
              onClick={() => setTime(s)}
              style={{
                all: 'unset', cursor: 'pointer',
                padding: '8px 14px', borderRadius: 10,
                background: time === s ? 'var(--accent)' : 'var(--icon-bg)',
                color: time === s ? '#fff' : 'var(--ink)',
                fontSize: 12, fontWeight: 600,
                fontFamily: 'JetBrains Mono, ui-monospace, monospace',
                whiteSpace: 'nowrap',
              }}>{s}</button>
          ))}
        </div>

        {/* store list */}
        <div style={{
          fontSize: 10.5, color: 'var(--muted)', marginBottom: 6, fontWeight: 500,
        }}>فروشگاه</div>
        <div style={{
          flex: 1, minHeight: 0, overflowY: 'auto',
          background: 'var(--bg)', border: '1px solid var(--border)',
          borderRadius: 12,
        }}>
          {available.length === 0 && (
            <div style={{
              padding: 20, textAlign: 'center',
              fontSize: 12, color: 'var(--muted)',
            }}>همه فروشگاه‌ها قبلاً اضافه شده‌اند</div>
          )}
          {available.map((s, i) => {
            const active = selectedStore === s.id;
            return (
              <button key={s.id}
                onClick={() => setSelectedStore(s.id)}
                style={{
                  all: 'unset', cursor: 'pointer', width: '100%', boxSizing: 'border-box',
                  display: 'flex', alignItems: 'center', justifyContent: 'space-between',
                  gap: 8, padding: '10px 12px',
                  borderTop: i ? '1px solid var(--border)' : 'none',
                  background: active ? 'color-mix(in oklab, var(--accent) 10%, transparent)' : 'transparent',
                  transition: 'background 140ms ease',
                }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                  <span style={{
                    width: 16, height: 16, borderRadius: 99,
                    border: `2px solid ${active ? 'var(--accent)' : 'var(--border)'}`,
                    background: active ? 'var(--accent)' : 'transparent',
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                  }}>
                    {active && <span style={{
                      width: 6, height: 6, borderRadius: 99, background: '#fff',
                    }} />}
                  </span>
                  <div>
                    <div style={{ fontSize: 12.5, fontWeight: 600 }}>{s.name}</div>
                    <div style={{ fontSize: 10.5, color: 'var(--muted)' }}>{s.addr}</div>
                  </div>
                </div>
                <div style={{
                  fontSize: 11, fontWeight: 700, color: 'var(--accent)',
                  fontFamily: 'JetBrains Mono, ui-monospace, monospace',
                }}>{window.fmtToman(s.price)}</div>
              </button>
            );
          })}
        </div>

        <button
          disabled={!selectedStore}
          onClick={handleAdd}
          style={{
            all: 'unset', cursor: selectedStore ? 'pointer' : 'not-allowed',
            marginTop: 12, padding: '13px', textAlign: 'center',
            borderRadius: 14,
            background: selectedStore ? 'var(--accent)' : 'var(--icon-bg)',
            color: selectedStore ? '#fff' : 'var(--muted)',
            fontSize: 14, fontWeight: 700,
          }}>افزودن به برنامه</button>
      </div>
    </>
  );
}

// ============================================================
// Tab 2 — Leave approvals
// ============================================================

function LeavesTab() {
  const app = window.useAppStore();
  const [filter, setFilter] = useStateA('pending'); // pending | approved | rejected

  const filtered = app.leaves.filter(l => l.status === filter);

  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
      {/* filter chips */}
      <div style={{
        display: 'flex', gap: 6, padding: '4px 14px 10px', flexShrink: 0,
      }}>
        {[
          { id: 'pending',  label: 'در انتظار',   color: 'var(--accent)' },
          { id: 'approved', label: 'تایید شده',   color: 'var(--ink)' },
          { id: 'rejected', label: 'رد شده',      color: 'var(--muted)' },
        ].map(f => {
          const active = filter === f.id;
          const count = app.leaves.filter(l => l.status === f.id).length;
          return (
            <button key={f.id}
              onClick={() => setFilter(f.id)}
              style={{
                all: 'unset', cursor: 'pointer', flex: 1, textAlign: 'center',
                padding: '8px 6px', borderRadius: 10,
                background: active ? 'var(--ink)' : 'var(--surface)',
                color: active ? 'var(--bg)' : 'var(--ink)',
                border: active ? '1px solid var(--ink)' : '1px solid var(--border)',
                fontSize: 11.5, fontWeight: 600,
              }}>
              {f.label} · {window.faNumS(count)}
            </button>
          );
        })}
      </div>

      <div style={{ flex: 1, overflowY: 'auto', padding: '0 14px 14px' }}>
        {filtered.length === 0 && (
          <div style={{
            textAlign: 'center', padding: '40px 20px',
            fontSize: 13, color: 'var(--muted)',
          }}>درخواستی در این دسته نیست</div>
        )}
        {filtered.map(l => <LeaveCard key={l.id} leave={l} />)}
      </div>
    </div>
  );
}

function LeaveCard({ leave }) {
  const user = window.getUserById(leave.userId);
  const days = Math.abs(leave.end - leave.start) + 1;
  const rangeLabel = leave.start === leave.end
    ? `${window.faNumS(leave.start)} خرداد`
    : `${window.faNumS(leave.start)} تا ${window.faNumS(leave.end)} خرداد`;

  return (
    <div style={{
      background: 'var(--surface)', border: '1px solid var(--border)',
      borderRadius: 14, padding: '12px 14px', marginBottom: 8,
    }}>
      {/* user row */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 10, marginBottom: 10,
      }}>
        <div style={{
          width: 34, height: 34, borderRadius: 10,
          background: 'var(--icon-bg)', border: '1px solid var(--border)',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontSize: 11, fontWeight: 700, color: 'var(--ink)',
        }}>{user?.initials}</div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--ink)' }}>{user?.name}</div>
          <div style={{ fontSize: 10.5, color: 'var(--muted)' }}>
            {user?.region} · ثبت شده {leave.submittedAt}
          </div>
        </div>
        <span style={{
          fontSize: 10.5, fontWeight: 700,
          padding: '3px 10px', borderRadius: 99,
          background: 'var(--icon-bg)', color: 'var(--ink)',
        }}>{LEAVE_TYPE_LABEL[leave.type]}</span>
      </div>

      {/* range */}
      <div style={{
        display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
        padding: '8px 10px', borderRadius: 10,
        background: 'var(--bg)', marginBottom: leave.reason ? 8 : 12,
      }}>
        <div style={{ fontSize: 12.5, fontWeight: 600 }}>{rangeLabel}</div>
        <div style={{
          fontSize: 11.5, fontWeight: 700, color: 'var(--accent)',
        }}>{window.faNumS(days)} روز</div>
      </div>

      {leave.reason && (
        <div style={{
          fontSize: 11.5, color: 'var(--muted)', marginBottom: 12,
          padding: '0 2px', lineHeight: 1.6,
        }}>«{leave.reason}»</div>
      )}

      {/* actions */}
      {leave.status === 'pending' ? (
        <div style={{ display: 'flex', gap: 6 }}>
          <button
            onClick={() => window.appActions.setLeaveStatus(leave.id, 'rejected')}
            style={{
              all: 'unset', cursor: 'pointer', flex: 1, textAlign: 'center',
              padding: '10px', borderRadius: 10,
              background: 'var(--surface)', border: '1px solid var(--danger)',
              color: 'var(--danger)', fontSize: 12.5, fontWeight: 700,
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6,
            }}>
            <window.IconXCircle size={16} color="currentColor" />
            <span>رد درخواست</span>
          </button>
          <button
            onClick={() => window.appActions.setLeaveStatus(leave.id, 'approved')}
            style={{
              all: 'unset', cursor: 'pointer', flex: 1.4, textAlign: 'center',
              padding: '10px', borderRadius: 10,
              background: 'var(--accent)', color: '#fff',
              fontSize: 12.5, fontWeight: 700,
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6,
            }}>
            <window.IconCheckCircle size={16} color="#fff" />
            <span>تایید درخواست</span>
          </button>
        </div>
      ) : (
        <div style={{
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          padding: '8px 0 0',
        }}>
          <div style={{
            display: 'inline-flex', alignItems: 'center', gap: 6,
            fontSize: 11.5, fontWeight: 700,
            color: leave.status === 'approved' ? 'var(--accent)' : 'var(--danger)',
          }}>
            {leave.status === 'approved'
              ? <><window.IconCheckCircle size={14} color="currentColor" /><span>تایید شده</span></>
              : <><window.IconXCircle size={14} color="currentColor" /><span>رد شده</span></>}
          </div>
          <button
            onClick={() => window.appActions.setLeaveStatus(leave.id, 'pending')}
            style={{
              all: 'unset', cursor: 'pointer',
              fontSize: 11, color: 'var(--muted)', fontWeight: 600,
            }}>بازگشت به انتظار</button>
        </div>
      )}
    </div>
  );
}

// ============================================================
// Tab 3 — Store pricing
// ============================================================

function PricingTab() {
  const app = window.useAppStore();
  const [formOpen, setFormOpen] = useStateA(false);
  const [editStore, setEditStore] = useStateA(null); // store being edited, or null for "add"

  const count = app.stores.length;
  const total = app.stores.reduce((acc, s) => acc + s.price, 0);
  const avg   = count ? Math.round(total / count) : 0;

  const openAdd  = () => { setEditStore(null); setFormOpen(true); };
  const openEdit = (s) => { setEditStore(s); setFormOpen(true); };

  const handleDelete = (s) => {
    if (window.confirm(`فروشگاه «${s.name}» حذف شود؟ ویزیت‌های مرتبط نیز حذف می‌شوند.`)) {
      window.appActions.deleteStore(s.id);
    }
  };

  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
      {/* summary */}
      <div style={{
        margin: '4px 14px 10px', padding: '12px 14px',
        background: 'var(--surface)', border: '1px solid var(--border)',
        borderRadius: 14,
        display: 'flex', justifyContent: 'space-between',
        flexShrink: 0,
      }}>
        <div>
          <div style={{ fontSize: 10.5, color: 'var(--muted)', marginBottom: 3 }}>تعداد فروشگاه</div>
          <div style={{ fontSize: 17, fontWeight: 700 }}>{window.faNumS(count)}</div>
        </div>
        <div style={{ width: 1, background: 'var(--border)' }} />
        <div>
          <div style={{ fontSize: 10.5, color: 'var(--muted)', marginBottom: 3 }}>میانگین تعرفه</div>
          <div style={{
            fontSize: 14, fontWeight: 700, color: 'var(--accent)',
            fontFamily: 'JetBrains Mono, ui-monospace, monospace',
          }}>{window.fmtToman(avg)}</div>
        </div>
      </div>

      {/* add store button */}
      <div style={{ padding: '0 14px 10px', flexShrink: 0 }}>
        <button onClick={openAdd} style={{
          all: 'unset', cursor: 'pointer', width: '100%', boxSizing: 'border-box',
          padding: '12px', borderRadius: 12,
          display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6,
          background: 'var(--accent)', color: '#fff',
          fontSize: 13, fontWeight: 700,
        }}>
          <window.IconPlus size={16} color="#fff" />
          <span>افزودن فروشگاه</span>
        </button>
      </div>

      <div style={{ flex: 1, overflowY: 'auto', padding: '0 14px 14px' }}>
        <div style={{
          background: 'var(--surface)', border: '1px solid var(--border)',
          borderRadius: 14, overflow: 'hidden',
        }}>
          {count === 0 && (
            <div style={{
              padding: '24px 14px', textAlign: 'center',
              fontSize: 12.5, color: 'var(--muted)',
            }}>هنوز فروشگاهی تعریف نشده</div>
          )}
          {app.stores.map((s, i) => (
            <div key={s.id} style={{
              padding: '12px 14px',
              borderTop: i ? '1px solid var(--border)' : 'none',
              display: 'flex', alignItems: 'center', gap: 10,
            }}>
              <div style={{
                width: 36, height: 36, borderRadius: 10,
                background: 'var(--icon-bg)',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                color: 'var(--accent)', flexShrink: 0,
              }}>
                <window.IconPin size={16} color="currentColor" />
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{
                  fontSize: 13, fontWeight: 600, color: 'var(--ink)',
                  overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                }}>{s.name}</div>
                <div style={{
                  fontSize: 10.5, color: 'var(--muted)',
                  overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                }}>
                  {s.addr}
                  {(s.open || s.close) && <span> · {s.open}–{s.close}</span>}
                </div>
              </div>
              <button onClick={() => openEdit(s)} style={{
                all: 'unset', cursor: 'pointer',
                display: 'flex', alignItems: 'center', gap: 6,
                padding: '6px 10px', borderRadius: 10,
                background: 'color-mix(in oklab, var(--accent) 10%, transparent)',
                color: 'var(--accent)', fontWeight: 700, fontSize: 12,
                fontFamily: 'JetBrains Mono, ui-monospace, monospace',
                fontVariantNumeric: 'tabular-nums',
              }}>
                <window.IconEdit size={12} color="currentColor" />
                <span>{window.fmtToman(s.price)}</span>
              </button>
              <button onClick={() => handleDelete(s)} style={{
                all: 'unset', cursor: 'pointer',
                width: 28, height: 28, borderRadius: 8,
                background: 'var(--icon-bg)',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                color: 'var(--danger)', flexShrink: 0,
              }}>
                <window.IconTrash size={14} color="currentColor" />
              </button>
            </div>
          ))}
        </div>
        <div style={{
          fontSize: 11, color: 'var(--muted)', textAlign: 'center',
          marginTop: 14, padding: '0 16px', lineHeight: 1.6,
        }}>
          تعرفه‌ها برای محاسبه درآمد روزانه فیلدفورس استفاده می‌شود
        </div>
      </div>

      {formOpen && (
        <StoreFormSheet
          store={editStore}
          onClose={() => setFormOpen(false)}
        />
      )}
    </div>
  );
}

// Add / edit a store. `store` null => add mode; otherwise edit mode.
function StoreFormSheet({ store, onClose }) {
  const isEdit = !!store;
  const [name, setName]   = useStateA(store?.name || '');
  const [addr, setAddr]   = useStateA(store?.addr || '');
  const [open, setOpen]   = useStateA(store?.open || '');
  const [close, setClose] = useStateA(store?.close || '');
  const [price, setPrice] = useStateA(store ? String(store.price) : '');

  const priceNum = parseInt(
    String(price).replace(/[۰-۹]/g, d => '۰۱۲۳۴۵۶۷۸۹'.indexOf(d)).replace(/\D/g, ''),
    10,
  );
  const valid = name.trim() && !isNaN(priceNum);

  const handleSubmit = () => {
    if (!valid) return;
    const fields = {
      name: name.trim(), addr: addr.trim(),
      open: open.trim(), close: close.trim(), price: priceNum,
    };
    if (isEdit) window.appActions.updateStore(store.id, fields);
    else        window.appActions.addStore(fields);
    onClose();
  };

  const labelStyle = {
    fontSize: 10.5, color: 'var(--muted)', marginBottom: 6,
    fontWeight: 500, padding: '0 2px',
  };
  const inputStyle = {
    width: '100%', boxSizing: 'border-box',
    padding: '11px 12px', borderRadius: 10,
    background: 'var(--bg)', border: '1px solid var(--border)',
    fontSize: 13, color: 'var(--ink)', outline: 'none',
    fontFamily: 'Vazirmatn, system-ui, sans-serif',
  };

  return (
    <>
      <div onClick={onClose}
           style={{
             position: 'absolute', inset: 0, background: 'rgba(8,10,10,0.45)',
             zIndex: 20,
           }} />
      <div style={{
        position: 'absolute', left: 0, right: 0, bottom: 0,
        background: 'var(--surface)',
        borderTopLeftRadius: 22, borderTopRightRadius: 22,
        padding: '12px 18px 18px',
        boxShadow: '0 -10px 40px rgba(0,0,0,0.18)',
        zIndex: 21, direction: 'rtl', maxHeight: '88%',
        display: 'flex', flexDirection: 'column',
      }}>
        <div style={{
          width: 40, height: 4, borderRadius: 99,
          background: 'var(--border)', margin: '0 auto 12px',
        }} />
        <div style={{
          display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
          marginBottom: 14,
        }}>
          <div style={{ fontSize: 15, fontWeight: 700 }}>
            {isEdit ? 'ویرایش فروشگاه' : 'تعریف فروشگاه جدید'}
          </div>
          <button onClick={onClose} style={{
            all: 'unset', cursor: 'pointer',
            width: 28, height: 28, borderRadius: 99,
            background: 'var(--icon-bg)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            color: 'var(--ink)',
          }}>
            <window.IconClose size={14} />
          </button>
        </div>

        <div style={{ flex: 1, minHeight: 0, overflowY: 'auto', paddingBottom: 4 }}>
          <div style={labelStyle}>نام فروشگاه</div>
          <input value={name} onChange={e => setName(e.target.value)}
                 placeholder="مثلاً فروشگاه افق"
                 style={{ ...inputStyle, marginBottom: 12 }} />

          <div style={labelStyle}>آدرس</div>
          <input value={addr} onChange={e => setAddr(e.target.value)}
                 placeholder="مثلاً میدان ولیعصر"
                 style={{ ...inputStyle, marginBottom: 12 }} />

          <div style={{ display: 'flex', gap: 10, marginBottom: 12 }}>
            <div style={{ flex: 1 }}>
              <div style={labelStyle}>ساعت باز شدن</div>
              <input value={open} onChange={e => setOpen(e.target.value)}
                     placeholder="۰۹:۰۰"
                     style={{ ...inputStyle, textAlign: 'center' }} />
            </div>
            <div style={{ flex: 1 }}>
              <div style={labelStyle}>ساعت بسته شدن</div>
              <input value={close} onChange={e => setClose(e.target.value)}
                     placeholder="۱۸:۰۰"
                     style={{ ...inputStyle, textAlign: 'center' }} />
            </div>
          </div>

          <div style={labelStyle}>تعرفه (تومان)</div>
          <input value={price} onChange={e => setPrice(e.target.value)}
                 type="text" inputMode="numeric" placeholder="۸۵۰۰۰۰"
                 style={{ ...inputStyle, direction: 'ltr', textAlign: 'left',
                          fontFamily: 'JetBrains Mono, ui-monospace, monospace',
                          fontVariantNumeric: 'tabular-nums' }} />
        </div>

        <button
          disabled={!valid}
          onClick={handleSubmit}
          style={{
            all: 'unset', cursor: valid ? 'pointer' : 'not-allowed',
            marginTop: 12, padding: '13px', textAlign: 'center',
            borderRadius: 14,
            background: valid ? 'var(--accent)' : 'var(--icon-bg)',
            color: valid ? '#fff' : 'var(--muted)',
            fontSize: 14, fontWeight: 700,
          }}>{isEdit ? 'ذخیره تغییرات' : 'افزودن فروشگاه'}</button>
      </div>
    </>
  );
}

// ============================================================
// Tab 4 — Sample product catalogue
// Defines the product list that field users fill in on the
// "received samples" screen.
// ============================================================

function ProductsTab() {
  const app = window.useAppStore();
  const [formOpen, setFormOpen] = useStateA(false);
  const [editProduct, setEditProduct] = useStateA(null); // product being edited, or null for "add"

  const count = app.products.length;

  const openAdd  = () => { setEditProduct(null); setFormOpen(true); };
  const openEdit = (p) => { setEditProduct(p); setFormOpen(true); };

  const handleDelete = (p) => {
    if (window.confirm(`محصول «${p.name}» از فهرست سمپل حذف شود؟`)) {
      window.appActions.deleteProduct(p.id);
    }
  };

  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
      {/* summary */}
      <div style={{
        margin: '4px 14px 10px', padding: '12px 14px',
        background: 'var(--surface)', border: '1px solid var(--border)',
        borderRadius: 14,
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        flexShrink: 0,
      }}>
        <div>
          <div style={{ fontSize: 10.5, color: 'var(--muted)', marginBottom: 3 }}>تعداد محصول</div>
          <div style={{ fontSize: 17, fontWeight: 700 }}>{window.faNumS(count)}</div>
        </div>
        <div style={{
          fontSize: 11, color: 'var(--muted)', textAlign: 'left',
          maxWidth: 180, lineHeight: 1.6,
        }}>این فهرست در صفحه «ثبت سمپل دریافتی» به کاربران نمایش داده می‌شود</div>
      </div>

      {/* add product button */}
      <div style={{ padding: '0 14px 10px', flexShrink: 0 }}>
        <button onClick={openAdd} style={{
          all: 'unset', cursor: 'pointer', width: '100%', boxSizing: 'border-box',
          padding: '12px', borderRadius: 12,
          display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6,
          background: 'var(--accent)', color: '#fff',
          fontSize: 13, fontWeight: 700,
        }}>
          <window.IconPlus size={16} color="#fff" />
          <span>افزودن محصول</span>
        </button>
      </div>

      <div style={{ flex: 1, overflowY: 'auto', padding: '0 14px 14px' }}>
        <div style={{
          background: 'var(--surface)', border: '1px solid var(--border)',
          borderRadius: 14, overflow: 'hidden',
        }}>
          {count === 0 && (
            <div style={{
              padding: '24px 14px', textAlign: 'center',
              fontSize: 12.5, color: 'var(--muted)',
            }}>هنوز محصولی تعریف نشده</div>
          )}
          {app.products.map((p, i) => (
            <div key={p.id} style={{
              padding: '12px 14px',
              borderTop: i ? '1px solid var(--border)' : 'none',
              display: 'flex', alignItems: 'center', gap: 10,
            }}>
              <div style={{
                width: 40, height: 40, borderRadius: 10,
                background: 'var(--icon-bg)', border: '1px solid var(--border)',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                fontSize: 9, color: 'var(--muted)', flexShrink: 0,
                fontFamily: 'JetBrains Mono, ui-monospace, monospace',
                letterSpacing: '0.04em', textAlign: 'center',
              }}>{p.code || '—'}</div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{
                  fontSize: 13, fontWeight: 600, color: 'var(--ink)',
                  overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                }}>{p.name}</div>
                <div style={{
                  fontSize: 10.5, color: 'var(--muted)',
                  overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                }}>{p.spec || 'بدون مشخصات'}</div>
              </div>
              <button onClick={() => openEdit(p)} style={{
                all: 'unset', cursor: 'pointer',
                width: 28, height: 28, borderRadius: 8,
                background: 'color-mix(in oklab, var(--accent) 10%, transparent)',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                color: 'var(--accent)', flexShrink: 0,
              }}>
                <window.IconEdit size={13} color="currentColor" />
              </button>
              <button onClick={() => handleDelete(p)} style={{
                all: 'unset', cursor: 'pointer',
                width: 28, height: 28, borderRadius: 8,
                background: 'var(--icon-bg)',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                color: 'var(--danger)', flexShrink: 0,
              }}>
                <window.IconTrash size={14} color="currentColor" />
              </button>
            </div>
          ))}
        </div>
      </div>

      {formOpen && (
        <ProductFormSheet
          product={editProduct}
          onClose={() => setFormOpen(false)}
        />
      )}
    </div>
  );
}

// Add / edit a sample product. `product` null => add mode; otherwise edit mode.
function ProductFormSheet({ product, onClose }) {
  const isEdit = !!product;
  const [name, setName] = useStateA(product?.name || '');
  const [spec, setSpec] = useStateA(product?.spec || '');
  const [code, setCode] = useStateA(product?.code || '');

  const valid = !!name.trim();

  const handleSubmit = () => {
    if (!valid) return;
    const fields = { name: name.trim(), spec: spec.trim(), code: code.trim() };
    if (isEdit) window.appActions.updateProduct(product.id, fields);
    else        window.appActions.addProduct(fields);
    onClose();
  };

  const labelStyle = {
    fontSize: 10.5, color: 'var(--muted)', marginBottom: 6,
    fontWeight: 500, padding: '0 2px',
  };
  const inputStyle = {
    width: '100%', boxSizing: 'border-box',
    padding: '11px 12px', borderRadius: 10,
    background: 'var(--bg)', border: '1px solid var(--border)',
    fontSize: 13, color: 'var(--ink)', outline: 'none',
    fontFamily: 'Vazirmatn, system-ui, sans-serif',
  };

  return (
    <>
      <div onClick={onClose}
           style={{
             position: 'absolute', inset: 0, background: 'rgba(8,10,10,0.45)',
             zIndex: 20,
           }} />
      <div style={{
        position: 'absolute', left: 0, right: 0, bottom: 0,
        background: 'var(--surface)',
        borderTopLeftRadius: 22, borderTopRightRadius: 22,
        padding: '12px 18px 18px',
        boxShadow: '0 -10px 40px rgba(0,0,0,0.18)',
        zIndex: 21, direction: 'rtl', maxHeight: '88%',
        display: 'flex', flexDirection: 'column',
      }}>
        <div style={{
          width: 40, height: 4, borderRadius: 99,
          background: 'var(--border)', margin: '0 auto 12px',
        }} />
        <div style={{
          display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
          marginBottom: 14,
        }}>
          <div style={{ fontSize: 15, fontWeight: 700 }}>
            {isEdit ? 'ویرایش محصول' : 'تعریف محصول جدید'}
          </div>
          <button onClick={onClose} style={{
            all: 'unset', cursor: 'pointer',
            width: 28, height: 28, borderRadius: 99,
            background: 'var(--icon-bg)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            color: 'var(--ink)',
          }}>
            <window.IconClose size={14} />
          </button>
        </div>

        <div style={{ flex: 1, minHeight: 0, overflowY: 'auto', paddingBottom: 4 }}>
          <div style={labelStyle}>نام محصول</div>
          <input value={name} onChange={e => setName(e.target.value)}
                 placeholder="مثلاً شامپو هد اند شولدرز"
                 style={{ ...inputStyle, marginBottom: 12 }} />

          <div style={labelStyle}>مشخصات</div>
          <input value={spec} onChange={e => setSpec(e.target.value)}
                 placeholder="مثلاً ۴۰۰ میلی‌لیتر"
                 style={{ ...inputStyle, marginBottom: 12 }} />

          <div style={labelStyle}>کد محصول</div>
          <input value={code} onChange={e => setCode(e.target.value)}
                 placeholder="مثلاً HS-400"
                 style={{ ...inputStyle, direction: 'ltr', textAlign: 'left',
                          fontFamily: 'JetBrains Mono, ui-monospace, monospace' }} />
        </div>

        <button
          disabled={!valid}
          onClick={handleSubmit}
          style={{
            all: 'unset', cursor: valid ? 'pointer' : 'not-allowed',
            marginTop: 12, padding: '13px', textAlign: 'center',
            borderRadius: 14,
            background: valid ? 'var(--accent)' : 'var(--icon-bg)',
            color: valid ? '#fff' : 'var(--muted)',
            fontSize: 14, fontWeight: 700,
          }}>{isEdit ? 'ذخیره تغییرات' : 'افزودن محصول'}</button>
      </div>
    </>
  );
}

// ============================================================
// Tab 5 — In-stock product catalogue
// Defines the product list field users fill in on the
// "record in-stock product count" screen. Managed independently
// from the sample catalogue above.
// ============================================================

function InventoryProductsTab() {
  const app = window.useAppStore();
  const [formOpen, setFormOpen] = useStateA(false);
  const [editProduct, setEditProduct] = useStateA(null); // product being edited, or null for "add"

  const count = app.inventoryProducts.length;

  const openAdd  = () => { setEditProduct(null); setFormOpen(true); };
  const openEdit = (p) => { setEditProduct(p); setFormOpen(true); };

  const handleDelete = (p) => {
    if (window.confirm(`محصول «${p.name}» از فهرست موجودی حذف شود؟`)) {
      window.appActions.deleteInventoryProduct(p.id);
    }
  };

  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
      {/* summary */}
      <div style={{
        margin: '4px 14px 10px', padding: '12px 14px',
        background: 'var(--surface)', border: '1px solid var(--border)',
        borderRadius: 14,
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        flexShrink: 0,
      }}>
        <div>
          <div style={{ fontSize: 10.5, color: 'var(--muted)', marginBottom: 3 }}>تعداد محصول</div>
          <div style={{ fontSize: 17, fontWeight: 700 }}>{window.faNumS(count)}</div>
        </div>
        <div style={{
          fontSize: 11, color: 'var(--muted)', textAlign: 'left',
          maxWidth: 180, lineHeight: 1.6,
        }}>این فهرست در صفحه «ثبت تعداد محصول موجود» به کاربران نمایش داده می‌شود</div>
      </div>

      {/* add product button */}
      <div style={{ padding: '0 14px 10px', flexShrink: 0 }}>
        <button onClick={openAdd} style={{
          all: 'unset', cursor: 'pointer', width: '100%', boxSizing: 'border-box',
          padding: '12px', borderRadius: 12,
          display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6,
          background: 'var(--accent)', color: '#fff',
          fontSize: 13, fontWeight: 700,
        }}>
          <window.IconPlus size={16} color="#fff" />
          <span>افزودن محصول</span>
        </button>
      </div>

      <div style={{ flex: 1, overflowY: 'auto', padding: '0 14px 14px' }}>
        <div style={{
          background: 'var(--surface)', border: '1px solid var(--border)',
          borderRadius: 14, overflow: 'hidden',
        }}>
          {count === 0 && (
            <div style={{
              padding: '24px 14px', textAlign: 'center',
              fontSize: 12.5, color: 'var(--muted)',
            }}>هنوز محصولی تعریف نشده</div>
          )}
          {app.inventoryProducts.map((p, i) => (
            <div key={p.id} style={{
              padding: '12px 14px',
              borderTop: i ? '1px solid var(--border)' : 'none',
              display: 'flex', alignItems: 'center', gap: 10,
            }}>
              <div style={{
                width: 40, height: 40, borderRadius: 10,
                background: 'var(--icon-bg)', border: '1px solid var(--border)',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                fontSize: 9, color: 'var(--muted)', flexShrink: 0,
                fontFamily: 'JetBrains Mono, ui-monospace, monospace',
                letterSpacing: '0.04em', textAlign: 'center',
              }}>{p.code || '—'}</div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{
                  fontSize: 13, fontWeight: 600, color: 'var(--ink)',
                  overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                }}>{p.name}</div>
                <div style={{
                  fontSize: 10.5, color: 'var(--muted)',
                  overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                }}>{p.spec || 'بدون مشخصات'}</div>
              </div>
              <button onClick={() => openEdit(p)} style={{
                all: 'unset', cursor: 'pointer',
                width: 28, height: 28, borderRadius: 8,
                background: 'color-mix(in oklab, var(--accent) 10%, transparent)',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                color: 'var(--accent)', flexShrink: 0,
              }}>
                <window.IconEdit size={13} color="currentColor" />
              </button>
              <button onClick={() => handleDelete(p)} style={{
                all: 'unset', cursor: 'pointer',
                width: 28, height: 28, borderRadius: 8,
                background: 'var(--icon-bg)',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                color: 'var(--danger)', flexShrink: 0,
              }}>
                <window.IconTrash size={14} color="currentColor" />
              </button>
            </div>
          ))}
        </div>
      </div>

      {formOpen && (
        <InventoryProductFormSheet
          product={editProduct}
          onClose={() => setFormOpen(false)}
        />
      )}
    </div>
  );
}

// Add / edit an in-stock product. `product` null => add mode; otherwise edit mode.
function InventoryProductFormSheet({ product, onClose }) {
  const isEdit = !!product;
  const [name, setName] = useStateA(product?.name || '');
  const [spec, setSpec] = useStateA(product?.spec || '');
  const [code, setCode] = useStateA(product?.code || '');

  const valid = !!name.trim();

  const handleSubmit = () => {
    if (!valid) return;
    const fields = { name: name.trim(), spec: spec.trim(), code: code.trim() };
    if (isEdit) window.appActions.updateInventoryProduct(product.id, fields);
    else        window.appActions.addInventoryProduct(fields);
    onClose();
  };

  const labelStyle = {
    fontSize: 10.5, color: 'var(--muted)', marginBottom: 6,
    fontWeight: 500, padding: '0 2px',
  };
  const inputStyle = {
    width: '100%', boxSizing: 'border-box',
    padding: '11px 12px', borderRadius: 10,
    background: 'var(--bg)', border: '1px solid var(--border)',
    fontSize: 13, color: 'var(--ink)', outline: 'none',
    fontFamily: 'Vazirmatn, system-ui, sans-serif',
  };

  return (
    <>
      <div onClick={onClose}
           style={{
             position: 'absolute', inset: 0, background: 'rgba(8,10,10,0.45)',
             zIndex: 20,
           }} />
      <div style={{
        position: 'absolute', left: 0, right: 0, bottom: 0,
        background: 'var(--surface)',
        borderTopLeftRadius: 22, borderTopRightRadius: 22,
        padding: '12px 18px 18px',
        boxShadow: '0 -10px 40px rgba(0,0,0,0.18)',
        zIndex: 21, direction: 'rtl', maxHeight: '88%',
        display: 'flex', flexDirection: 'column',
      }}>
        <div style={{
          width: 40, height: 4, borderRadius: 99,
          background: 'var(--border)', margin: '0 auto 12px',
        }} />
        <div style={{
          display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
          marginBottom: 14,
        }}>
          <div style={{ fontSize: 15, fontWeight: 700 }}>
            {isEdit ? 'ویرایش محصول' : 'تعریف محصول جدید'}
          </div>
          <button onClick={onClose} style={{
            all: 'unset', cursor: 'pointer',
            width: 28, height: 28, borderRadius: 99,
            background: 'var(--icon-bg)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            color: 'var(--ink)',
          }}>
            <window.IconClose size={14} />
          </button>
        </div>

        <div style={{ flex: 1, minHeight: 0, overflowY: 'auto', paddingBottom: 4 }}>
          <div style={labelStyle}>نام محصول</div>
          <input value={name} onChange={e => setName(e.target.value)}
                 placeholder="مثلاً شامپو هد اند شولدرز"
                 style={{ ...inputStyle, marginBottom: 12 }} />

          <div style={labelStyle}>مشخصات</div>
          <input value={spec} onChange={e => setSpec(e.target.value)}
                 placeholder="مثلاً ۴۰۰ میلی‌لیتر"
                 style={{ ...inputStyle, marginBottom: 12 }} />

          <div style={labelStyle}>کد محصول</div>
          <input value={code} onChange={e => setCode(e.target.value)}
                 placeholder="مثلاً HS-400"
                 style={{ ...inputStyle, direction: 'ltr', textAlign: 'left',
                          fontFamily: 'JetBrains Mono, ui-monospace, monospace' }} />
        </div>

        <button
          disabled={!valid}
          onClick={handleSubmit}
          style={{
            all: 'unset', cursor: valid ? 'pointer' : 'not-allowed',
            marginTop: 12, padding: '13px', textAlign: 'center',
            borderRadius: 14,
            background: valid ? 'var(--accent)' : 'var(--icon-bg)',
            color: valid ? '#fff' : 'var(--muted)',
            fontSize: 14, fontWeight: 700,
          }}>{isEdit ? 'ذخیره تغییرات' : 'افزودن محصول'}</button>
      </div>
    </>
  );
}

// ============================================================
// Tab — Field-force performance review
// Per user: visit/earning totals, sample & inventory tallies,
// and the daily work sessions with their start/end selfies.
// ============================================================

function PerformanceTab() {
  const app = window.useAppStore();
  const fieldUsers = app.users.filter(u => u.role === 'promoter' || u.role === 'user');
  const [userId, setUserId] = useStateA(fieldUsers[0]?.id || null);
  const [data, setData] = useStateA(null);
  const [loading, setLoading] = useStateA(false);
  const [lightbox, setLightbox] = useStateA(null); // { src, caption } | null

  React.useEffect(() => {
    if (!userId) { setData(null); return; }
    let alive = true;
    setLoading(true);
    setData(null);
    window.appActions.fetchPerformance(userId).then(d => {
      if (alive) { setData(d); setLoading(false); }
    });
    return () => { alive = false; };
  }, [userId]);

  const earn = userId ? window.computeEarnings(userId) : null;

  const fmtDur = (min) => {
    const h = Math.floor(min / 60), m = min % 60;
    if (h && m) return `${window.faNumS(h)} ساعت و ${window.faNumS(m)} دقیقه`;
    if (h) return `${window.faNumS(h)} ساعت`;
    return `${window.faNumS(m)} دقیقه`;
  };
  const fmtDate = (iso) => {
    try {
      return new Intl.DateTimeFormat('fa-IR', {
        weekday: 'long', day: 'numeric', month: 'long',
      }).format(new Date(iso + 'T00:00:00'));
    } catch { return window.faNumS(iso); }
  };

  if (fieldUsers.length === 0) {
    return (
      <div style={{
        textAlign: 'center', padding: '40px 20px',
        fontSize: 13, color: 'var(--muted)',
      }}>هنوز نیروی میدانی ثبت نشده است</div>
    );
  }

  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
      {/* user picker */}
      <div style={{ padding: '6px 14px 10px', flexShrink: 0 }}>
        <div style={{
          fontSize: 10.5, color: 'var(--muted)', letterSpacing: '0.04em',
          marginBottom: 6, fontWeight: 500, padding: '0 2px',
        }}>نیرو</div>
        <div style={{
          display: 'flex', gap: 6, overflowX: 'auto', paddingBottom: 2,
          scrollbarWidth: 'none',
        }}>
          {fieldUsers.map(u => {
            const active = u.id === userId;
            return (
              <button key={u.id}
                onClick={() => setUserId(u.id)}
                style={{
                  all: 'unset', cursor: 'pointer', padding: '8px 12px', borderRadius: 99,
                  background: active ? 'var(--ink)' : 'var(--surface)',
                  color: active ? 'var(--bg)' : 'var(--ink)',
                  border: active ? '1px solid var(--ink)' : '1px solid var(--border)',
                  fontSize: 12, fontWeight: 600, whiteSpace: 'nowrap',
                  display: 'inline-flex', alignItems: 'center', gap: 7,
                }}>
                <span style={{
                  width: 20, height: 20, borderRadius: 99,
                  background: active ? 'rgba(255,255,255,0.15)' : 'var(--icon-bg)',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  fontSize: 9, fontWeight: 700,
                }}>{u.initials}</span>
                {u.name.split(' ')[0]}
              </button>
            );
          })}
        </div>
      </div>

      <div style={{ flex: 1, overflowY: 'auto', padding: '0 14px 14px' }}>
        {/* summary cards */}
        {earn && (
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8, marginBottom: 10 }}>
            <PerfStat
              label="ویزیت‌ها"
              value={`${window.faNumS(earn.visitsDone)}/${window.faNumS(earn.visitsDone + earn.visitsToday + earn.visitsUpcoming)}`}
              sub="انجام‌شده از کل" accent />
            <PerfStat
              label="درآمد"
              value={window.fmtToman(earn.earnedTotal)}
              sub="ثبت‌شده تا امروز" mono />
            <PerfStat
              label="سمپل دریافتی"
              value={data ? window.faNumS(data.samplesTotal) + ' عدد' : '—'}
              sub={data ? `${window.faNumS(data.samplesCount)} بار ثبت` : ''} />
            <PerfStat
              label="موجودی شمارش‌شده"
              value={data ? window.faNumS(data.inventoryTotal) + ' عدد' : '—'}
              sub={data ? `${window.faNumS(data.inventoryCount)} بار ثبت` : ''} />
          </div>
        )}

        {/* which sample products were received */}
        {!loading && data && data.sampleProducts && data.sampleProducts.length > 0 && (
          <>
            <div style={{
              fontSize: 11, color: 'var(--muted)', fontWeight: 600,
              padding: '6px 2px 8px',
            }}>سمپل‌های دریافتی به تفکیک محصول</div>
            <div style={{
              background: 'var(--surface)', border: '1px solid var(--border)',
              borderRadius: 14, overflow: 'hidden', marginBottom: 10,
            }}>
              {data.sampleProducts.map((p, i) => (
                <div key={p.id} style={{
                  padding: '10px 14px',
                  borderTop: i ? '1px solid var(--border)' : 'none',
                  display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10,
                }}>
                  <span style={{
                    fontSize: 12.5, fontWeight: 600, color: 'var(--ink)', minWidth: 0,
                    overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                  }}>{p.name}</span>
                  <span style={{
                    flexShrink: 0, fontSize: 11, fontWeight: 700, color: 'var(--accent)',
                    background: 'color-mix(in oklab, var(--accent) 10%, transparent)',
                    padding: '3px 10px', borderRadius: 99,
                    fontVariantNumeric: 'tabular-nums',
                  }}>{window.faNumS(p.count)} عدد</span>
                </div>
              ))}
            </div>
          </>
        )}

        {loading && (
          <div style={{ textAlign: 'center', padding: '30px 0', fontSize: 12.5, color: 'var(--muted)' }}>
            در حال بارگذاری…
          </div>
        )}

        {/* daily worked hours */}
        {!loading && data && (
          <>
            <div style={{
              fontSize: 11, color: 'var(--muted)', fontWeight: 600,
              padding: '6px 2px 8px',
            }}>ساعت کارکرد روزانه</div>

            {data.days.length === 0 ? (
              <div style={{
                background: 'var(--surface)', border: '1px solid var(--border)',
                borderRadius: 14, padding: '22px 14px', textAlign: 'center',
                fontSize: 12.5, color: 'var(--muted)',
              }}>هنوز شروع/پایان کاری برای این نیرو ثبت نشده</div>
            ) : (
              <div style={{
                background: 'var(--surface)', border: '1px solid var(--border)',
                borderRadius: 14, overflow: 'hidden',
              }}>
                {data.days.map((d, i) => (
                  <div key={d.date} style={{
                    padding: '11px 14px',
                    borderTop: i ? '1px solid var(--border)' : 'none',
                    display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10,
                  }}>
                    <div style={{ minWidth: 0 }}>
                      <div style={{ fontSize: 12.5, fontWeight: 700, color: 'var(--ink)' }}>{fmtDate(d.date)}</div>
                      <div style={{
                        fontSize: 11, color: 'var(--muted)', marginTop: 2,
                        fontFamily: 'JetBrains Mono, ui-monospace, monospace',
                      }}>
                        {d.start ? window.faNumS(d.start) : '—'} ← {d.end ? window.faNumS(d.end) : '—'}
                      </div>
                    </div>
                    <span style={{
                      display: 'inline-flex', alignItems: 'center', gap: 5, flexShrink: 0,
                      fontSize: 10.5, fontWeight: 700,
                      color: d.durationMin > 0 ? 'var(--accent)' : 'var(--muted)',
                      background: d.durationMin > 0
                        ? 'color-mix(in oklab, var(--accent) 10%, transparent)' : 'var(--icon-bg)',
                      padding: '4px 9px', borderRadius: 99,
                    }}>
                      <window.IconClock size={12} color="currentColor" />
                      {d.durationMin > 0 ? fmtDur(d.durationMin) : 'ناتمام'}
                    </span>
                  </div>
                ))}
              </div>
            )}

            {/* selfie gallery — every uploaded start/end photo */}
            {(() => {
              const gallery = data.photos.filter(p => p.photo);
              return (
                <>
                  <div style={{
                    fontSize: 11, color: 'var(--muted)', fontWeight: 600,
                    padding: '16px 2px 8px',
                  }}>عکس‌های شروع و پایان کار · {window.faNumS(gallery.length)}</div>

                  {gallery.length === 0 ? (
                    <div style={{
                      background: 'var(--surface)', border: '1px solid var(--border)',
                      borderRadius: 14, padding: '22px 14px', textAlign: 'center',
                      fontSize: 12.5, color: 'var(--muted)',
                    }}>هنوز عکسی آپلود نشده است</div>
                  ) : (
                    <div style={{
                      display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 6,
                    }}>
                      {gallery.map((p, i) => (
                        <PerfPhoto key={i} item={p}
                          caption={`${p.kind === 'start' ? 'شروع کار' : 'پایان کار'} · ${fmtDate(p.date)} · ${window.faNumS(p.time)}`}
                          onOpen={setLightbox} />
                      ))}
                    </div>
                  )}
                </>
              );
            })()}
          </>
        )}
      </div>

      {lightbox && (
        <div onClick={() => setLightbox(null)}
             style={{
               position: 'absolute', inset: 0, zIndex: 30,
               background: 'rgba(8,10,10,0.88)',
               display: 'flex', flexDirection: 'column',
               alignItems: 'center', justifyContent: 'center', gap: 14, padding: 20,
             }}>
          <img src={lightbox.src} alt="selfie"
               style={{
                 maxWidth: '100%', maxHeight: '78%', borderRadius: 16,
                 objectFit: 'contain', boxShadow: '0 10px 40px rgba(0,0,0,0.5)',
               }} />
          <div style={{ fontSize: 12.5, color: '#fff', fontWeight: 600 }}>{lightbox.caption}</div>
          <button onClick={() => setLightbox(null)} style={{
            all: 'unset', cursor: 'pointer',
            padding: '10px 22px', borderRadius: 99,
            background: 'rgba(255,255,255,0.16)', color: '#fff',
            fontSize: 13, fontWeight: 700,
          }}>بستن</button>
        </div>
      )}
    </div>
  );
}

function PerfStat({ label, value, sub, accent, mono }) {
  return (
    <div style={{
      background: 'var(--surface)', border: '1px solid var(--border)',
      borderRadius: 14, padding: '11px 13px',
    }}>
      <div style={{ fontSize: 10.5, color: 'var(--muted)', marginBottom: 5 }}>{label}</div>
      <div style={{
        fontSize: 15, fontWeight: 700,
        color: accent ? 'var(--accent)' : 'var(--ink)',
        fontFamily: mono ? 'JetBrains Mono, ui-monospace, monospace' : undefined,
        fontVariantNumeric: 'tabular-nums',
        overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
      }}>{value}</div>
      {sub && <div style={{ fontSize: 9.5, color: 'var(--muted)', marginTop: 3 }}>{sub}</div>}
    </div>
  );
}

// A single selfie thumbnail in the gallery; tap to open the lightbox.
function PerfPhoto({ item, caption, onOpen }) {
  const isStart = item.kind === 'start';
  return (
    <button onClick={() => onOpen({ src: item.photo, caption })}
      style={{
        all: 'unset', cursor: 'pointer', position: 'relative', display: 'block',
        aspectRatio: '1 / 1', borderRadius: 12, overflow: 'hidden',
        border: '1px solid var(--border)', background: 'var(--icon-bg)',
      }}>
      <img src={item.photo} alt={item.kind}
           loading="lazy"
           style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
      <span style={{
        position: 'absolute', top: 6, right: 6,
        fontSize: 9, fontWeight: 700, color: '#fff',
        padding: '2px 8px', borderRadius: 99, backdropFilter: 'blur(4px)',
        background: isStart ? 'var(--accent)' : 'rgba(8,10,10,0.62)',
      }}>{isStart ? 'شروع' : 'پایان'}</span>
      <span style={{
        position: 'absolute', left: 0, right: 0, bottom: 0,
        background: 'linear-gradient(transparent, rgba(0,0,0,0.62))',
        color: '#fff', fontSize: 9.5, fontWeight: 600,
        padding: '14px 6px 4px', textAlign: 'center',
        fontFamily: 'JetBrains Mono, ui-monospace, monospace',
      }}>{window.faNumS(item.time)}</span>
    </button>
  );
}

// ============================================================
// Tab — Projects (manager and up)
// Define a project and assign the supervisors responsible for it.
// ============================================================

function ProjectsTab() {
  const app = window.useAppStore();
  const [formOpen, setFormOpen] = useStateA(false);
  const [editProject, setEditProject] = useStateA(null); // project being edited, or null for "add"

  const projects = app.projects || [];
  // Supervisors the current user can assign (bootstrap already scopes app.users).
  const supervisors = app.users.filter(u => u.role === 'supervisor');

  const openAdd  = () => { setEditProject(null); setFormOpen(true); };
  const openEdit = (p) => { setEditProject(p); setFormOpen(true); };

  const handleDelete = (p) => {
    if (window.confirm(`پروژه «${p.name}» حذف شود؟`)) {
      window.appActions.deleteProject(p.id);
    }
  };

  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
      {/* summary */}
      <div style={{
        margin: '4px 14px 10px', padding: '12px 14px',
        background: 'var(--surface)', border: '1px solid var(--border)',
        borderRadius: 14,
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        flexShrink: 0,
      }}>
        <div>
          <div style={{ fontSize: 10.5, color: 'var(--muted)', marginBottom: 3 }}>تعداد پروژه</div>
          <div style={{ fontSize: 17, fontWeight: 700 }}>{window.faNumS(projects.length)}</div>
        </div>
        <div style={{
          fontSize: 11, color: 'var(--muted)', textAlign: 'left',
          maxWidth: 190, lineHeight: 1.6,
        }}>برای هر پروژه سرپرست‌های مسئول را انتخاب کنید</div>
      </div>

      {/* add project button */}
      <div style={{ padding: '0 14px 10px', flexShrink: 0 }}>
        <button onClick={openAdd} style={{
          all: 'unset', cursor: 'pointer', width: '100%', boxSizing: 'border-box',
          padding: '12px', borderRadius: 12,
          display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6,
          background: 'var(--accent)', color: '#fff', fontSize: 13, fontWeight: 700,
        }}>
          <window.IconPlus size={16} color="#fff" />
          <span>تعریف پروژه جدید</span>
        </button>
      </div>

      <div style={{ flex: 1, overflowY: 'auto', padding: '0 14px 14px' }}>
        <div style={{
          background: 'var(--surface)', border: '1px solid var(--border)',
          borderRadius: 14, overflow: 'hidden',
        }}>
          {projects.length === 0 && (
            <div style={{
              padding: '24px 14px', textAlign: 'center',
              fontSize: 12.5, color: 'var(--muted)',
            }}>هنوز پروژه‌ای تعریف نشده</div>
          )}
          {projects.map((p, i) => {
            const names = (p.supervisorIds || [])
              .map(id => window.getUserById(id)?.name)
              .filter(Boolean);
            return (
              <div key={p.id} style={{
                padding: '12px 14px',
                borderTop: i ? '1px solid var(--border)' : 'none',
                display: 'flex', alignItems: 'center', gap: 10,
              }}>
                <div style={{
                  width: 40, height: 40, borderRadius: 10,
                  background: 'var(--icon-bg)', border: '1px solid var(--border)',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  color: 'var(--muted)', flexShrink: 0,
                }}>
                  <window.IconAdmin size={18} color="currentColor" />
                </div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{
                    fontSize: 13, fontWeight: 600, color: 'var(--ink)',
                    overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                  }}>{p.name}</div>
                  <div style={{
                    fontSize: 10.5, color: 'var(--muted)',
                    overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                  }}>
                    {names.length
                      ? `${window.faNumS(names.length)} سرپرست: ${names.join('، ')}`
                      : 'بدون سرپرست'}
                  </div>
                </div>
                <button onClick={() => openEdit(p)} style={{
                  all: 'unset', cursor: 'pointer',
                  width: 28, height: 28, borderRadius: 8,
                  background: 'color-mix(in oklab, var(--accent) 10%, transparent)',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  color: 'var(--accent)', flexShrink: 0,
                }}>
                  <window.IconEdit size={13} color="currentColor" />
                </button>
                <button onClick={() => handleDelete(p)} style={{
                  all: 'unset', cursor: 'pointer',
                  width: 28, height: 28, borderRadius: 8,
                  background: 'var(--icon-bg)',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  color: 'var(--danger)', flexShrink: 0,
                }}>
                  <window.IconTrash size={14} color="currentColor" />
                </button>
              </div>
            );
          })}
        </div>
      </div>

      {formOpen && (
        <ProjectFormSheet
          project={editProject}
          supervisors={supervisors}
          onClose={() => setFormOpen(false)}
        />
      )}
    </div>
  );
}

// Add / edit a project. `project` null => add mode; otherwise edit mode.
// `supervisors` is the list of assignable supervisor users.
function ProjectFormSheet({ project, supervisors, onClose }) {
  const isEdit = !!project;
  const [name, setName] = useStateA(project?.name || '');
  const [description, setDescription] = useStateA(project?.description || '');
  const [selected, setSelected] = useStateA(() => new Set(project?.supervisorIds || []));
  const [error, setError] = useStateA('');
  const [busy, setBusy] = useStateA(false);

  const toggle = (id) => {
    setSelected(prev => {
      const next = new Set(prev);
      next.has(id) ? next.delete(id) : next.add(id);
      return next;
    });
  };

  const valid = !!name.trim() && !busy;

  const handleSubmit = async () => {
    if (!valid) return;
    setBusy(true); setError('');
    const fields = {
      name: name.trim(),
      description: description.trim(),
      supervisorIds: [...selected],
    };
    const res = isEdit
      ? await window.appActions.updateProject(project.id, fields)
      : await window.appActions.addProject(fields);
    setBusy(false);
    if (res.ok) onClose();
    else setError(res.data?.error || 'خطا در ذخیره پروژه');
  };

  const labelStyle = {
    fontSize: 10.5, color: 'var(--muted)', marginBottom: 6,
    fontWeight: 500, padding: '0 2px',
  };
  const inputStyle = {
    width: '100%', boxSizing: 'border-box',
    padding: '11px 12px', borderRadius: 10,
    background: 'var(--bg)', border: '1px solid var(--border)',
    fontSize: 13, color: 'var(--ink)', outline: 'none',
    fontFamily: 'Vazirmatn, system-ui, sans-serif',
  };

  return (
    <>
      <div onClick={onClose}
           style={{ position: 'absolute', inset: 0, background: 'rgba(8,10,10,0.45)', zIndex: 20 }} />
      <div style={{
        position: 'absolute', left: 0, right: 0, bottom: 0,
        background: 'var(--surface)',
        borderTopLeftRadius: 22, borderTopRightRadius: 22,
        padding: '12px 18px 18px',
        boxShadow: '0 -10px 40px rgba(0,0,0,0.18)',
        zIndex: 21, direction: 'rtl', maxHeight: '90%',
        display: 'flex', flexDirection: 'column',
      }}>
        <div style={{ width: 40, height: 4, borderRadius: 99, background: 'var(--border)', margin: '0 auto 12px' }} />
        <div style={{
          display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 14,
        }}>
          <div style={{ fontSize: 15, fontWeight: 700 }}>
            {isEdit ? 'ویرایش پروژه' : 'تعریف پروژه جدید'}
          </div>
          <button onClick={onClose} style={{
            all: 'unset', cursor: 'pointer', width: 28, height: 28, borderRadius: 99,
            background: 'var(--icon-bg)',
            display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--ink)',
          }}>
            <window.IconClose size={14} />
          </button>
        </div>

        <div style={{ flex: 1, minHeight: 0, overflowY: 'auto', paddingBottom: 4 }}>
          <div style={labelStyle}>نام پروژه</div>
          <input value={name} onChange={e => setName(e.target.value)}
                 placeholder="مثلاً کمپین تابستان"
                 style={{ ...inputStyle, marginBottom: 12 }} />

          <div style={labelStyle}>توضیحات (اختیاری)</div>
          <input value={description} onChange={e => setDescription(e.target.value)}
                 placeholder="توضیح کوتاه درباره‌ی پروژه"
                 style={{ ...inputStyle, marginBottom: 14 }} />

          <div style={labelStyle}>سرپرست‌های پروژه</div>
          {supervisors.length === 0 ? (
            <div style={{
              padding: '16px 12px', textAlign: 'center', borderRadius: 10,
              background: 'var(--bg)', border: '1px dashed var(--border)',
              fontSize: 12, color: 'var(--muted)', lineHeight: 1.6,
            }}>هیچ سرپرستی برای انتخاب موجود نیست. ابتدا کاربری با نقش «سرپرست» بسازید.</div>
          ) : (
            <div style={{
              border: '1px solid var(--border)', borderRadius: 12, overflow: 'hidden',
            }}>
              {supervisors.map((s, i) => {
                const on = selected.has(s.id);
                return (
                  <button key={s.id} onClick={() => toggle(s.id)} style={{
                    all: 'unset', cursor: 'pointer', boxSizing: 'border-box', width: '100%',
                    padding: '11px 12px',
                    borderTop: i ? '1px solid var(--border)' : 'none',
                    display: 'flex', alignItems: 'center', gap: 10,
                    background: on ? 'color-mix(in oklab, var(--accent) 8%, transparent)' : 'transparent',
                  }}>
                    <div style={{
                      width: 32, height: 32, borderRadius: 9,
                      background: 'var(--icon-bg)', border: '1px solid var(--border)',
                      display: 'flex', alignItems: 'center', justifyContent: 'center',
                      fontSize: 11, fontWeight: 700, color: 'var(--ink)', flexShrink: 0,
                    }}>{s.initials}</div>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{
                        fontSize: 13, fontWeight: 600, color: 'var(--ink)',
                        overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                      }}>{s.name}</div>
                      {s.region && <div style={{ fontSize: 10.5, color: 'var(--muted)' }}>{s.region}</div>}
                    </div>
                    <div style={{
                      width: 22, height: 22, borderRadius: 7, flexShrink: 0,
                      border: on ? 'none' : '1.5px solid var(--border)',
                      background: on ? 'var(--accent)' : 'transparent',
                      display: 'flex', alignItems: 'center', justifyContent: 'center',
                    }}>
                      {on && <window.IconCheck size={13} color="#fff" />}
                    </div>
                  </button>
                );
              })}
            </div>
          )}

          {error && (
            <div style={{ marginTop: 12, fontSize: 12, color: 'var(--danger)', textAlign: 'center' }}>{error}</div>
          )}
        </div>

        <button
          disabled={!valid}
          onClick={handleSubmit}
          style={{
            all: 'unset', cursor: valid ? 'pointer' : 'not-allowed',
            marginTop: 12, padding: '13px', textAlign: 'center', borderRadius: 14,
            background: valid ? 'var(--accent)' : 'var(--icon-bg)',
            color: valid ? '#fff' : 'var(--muted)',
            fontSize: 14, fontWeight: 700,
          }}>{isEdit ? 'ذخیره تغییرات' : 'افزودن پروژه'}</button>
      </div>
    </>
  );
}

// ============================================================
// Tab — User management (full-access roles)
// Create users, set their role, and link them to a superior so the
// five-level hierarchy (promoter → supervisor → manager → senior_manager → admin)
// stays connected. Editing is also exposed via manage_users.py on the CLI.
// ============================================================

function UsersTab() {
  const app = window.useAppStore();
  const [formOpen, setFormOpen] = useStateA(false);
  const [editUser, setEditUser] = useStateA(null); // user being edited, or null for "add"

  const users = [...app.users].sort((a, b) =>
    (ROLE_META[b.role]?.level || 0) - (ROLE_META[a.role]?.level || 0)
    || (a.name || '').localeCompare(b.name || ''));

  const openAdd  = () => { setEditUser(null); setFormOpen(true); };
  const openEdit = (u) => { setEditUser(u); setFormOpen(true); };

  const handleDelete = (u) => {
    if (window.confirm(`کاربر «${u.name}» حذف شود؟ زیرمجموعه‌ی او به سرپرست بالادست منتقل می‌شود.`)) {
      window.appActions.deleteUser(u.id);
    }
  };

  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
      <div style={{ padding: '0 14px 10px', flexShrink: 0 }}>
        <button onClick={openAdd} style={{
          all: 'unset', cursor: 'pointer', width: '100%', boxSizing: 'border-box',
          padding: '12px', borderRadius: 12,
          display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6,
          background: 'var(--accent)', color: '#fff', fontSize: 13, fontWeight: 700,
        }}>
          <window.IconPlus size={16} color="#fff" />
          <span>افزودن کاربر</span>
        </button>
      </div>

      <div style={{ flex: 1, overflowY: 'auto', padding: '0 14px 14px' }}>
        <div style={{
          background: 'var(--surface)', border: '1px solid var(--border)',
          borderRadius: 14, overflow: 'hidden',
        }}>
          {users.length === 0 && (
            <div style={{ padding: '24px 14px', textAlign: 'center', fontSize: 12.5, color: 'var(--muted)' }}>
              هنوز کاربری ثبت نشده
            </div>
          )}
          {users.map((u, i) => {
            const parent = u.parentId ? window.getUserById(u.parentId) : null;
            return (
              <div key={u.id} style={{
                padding: '12px 14px',
                borderTop: i ? '1px solid var(--border)' : 'none',
                display: 'flex', alignItems: 'center', gap: 10,
              }}>
                <div style={{
                  width: 36, height: 36, borderRadius: 10,
                  background: 'var(--icon-bg)', border: '1px solid var(--border)',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  fontSize: 11, fontWeight: 700, color: 'var(--ink)', flexShrink: 0,
                }}>{u.initials}</div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{
                    fontSize: 13, fontWeight: 600, color: 'var(--ink)',
                    overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                  }}>{u.name}</div>
                  <div style={{
                    fontSize: 10.5, color: 'var(--muted)',
                    overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                  }}>
                    {ROLE_LABEL_A(u.role)}
                    {parent && <span> · سرپرست: {parent.name}</span>}
                  </div>
                </div>
                <button onClick={() => openEdit(u)} style={{
                  all: 'unset', cursor: 'pointer',
                  width: 28, height: 28, borderRadius: 8,
                  background: 'color-mix(in oklab, var(--accent) 10%, transparent)',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  color: 'var(--accent)', flexShrink: 0,
                }}>
                  <window.IconEdit size={13} color="currentColor" />
                </button>
                <button onClick={() => handleDelete(u)} style={{
                  all: 'unset', cursor: 'pointer',
                  width: 28, height: 28, borderRadius: 8,
                  background: 'var(--icon-bg)',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  color: 'var(--danger)', flexShrink: 0,
                }}>
                  <window.IconTrash size={14} color="currentColor" />
                </button>
              </div>
            );
          })}
        </div>
        <div style={{
          fontSize: 11, color: 'var(--muted)', textAlign: 'center',
          marginTop: 14, padding: '0 16px', lineHeight: 1.6,
        }}>
          هر کاربر به سرپرستِ بالادست خود متصل می‌شود؛ مدیر همه‌ی زیرمجموعه را می‌بیند.
        </div>
      </div>

      {formOpen && (
        <UserFormSheet
          user={editUser}
          allUsers={app.users}
          onClose={() => setFormOpen(false)}
        />
      )}
    </div>
  );
}

// Add / edit a user. `user` null => add mode (username + password required);
// otherwise edit mode (credentials fixed; an optional new password resets it).
function UserFormSheet({ user, allUsers, onClose }) {
  const isEdit = !!user;
  const [name, setName] = useStateA(user?.name || '');
  const [username, setUsername] = useStateA(user?.username || '');
  const [password, setPassword] = useStateA('');
  const [role, setRole] = useStateA(user?.role || 'promoter');
  const [parentId, setParentId] = useStateA(user?.parentId || '');
  const [phone, setPhone] = useStateA(user?.phone || '');
  const [region, setRegion] = useStateA(user?.region || '');
  const [error, setError] = useStateA('');
  const [busy, setBusy] = useStateA(false);

  const isFull = FULL_ACCESS_ROLES_A.includes(role);
  const myLevel = ROLE_META[role]?.level || 0;
  // Eligible superiors: anyone outranking the chosen role, except this user.
  const parentOptions = allUsers.filter(u =>
    u.id !== user?.id && (ROLE_META[u.role]?.level || 0) > myLevel);

  // If the chosen parent no longer outranks the role, drop it.
  React.useEffect(() => {
    if (isFull) { setParentId(''); return; }
    if (parentId && !parentOptions.some(p => p.id === parentId)) setParentId('');
  }, [role]); // eslint-disable-line

  const usernameOk = isEdit || (username.trim().length >= 3);
  const passwordOk = isEdit || (password.length >= 4);
  const valid = name.trim() && usernameOk && passwordOk && !busy;

  const handleSubmit = async () => {
    if (!valid) return;
    setBusy(true); setError('');
    let res;
    if (isEdit) {
      res = await window.appActions.updateUser(user.id, {
        name: name.trim(), role, parentId: isFull ? null : (parentId || null),
        phone: phone.trim(), region: region.trim(),
      });
      if (res.ok && password) {
        const pr = await window.appActions.resetUserPassword(user.id, password);
        if (!pr.ok) res = pr;
      }
    } else {
      res = await window.appActions.createUser({
        name: name.trim(), username: username.trim(), password, role,
        parentId: isFull ? null : (parentId || null),
        phone: phone.trim(), region: region.trim(),
      });
    }
    setBusy(false);
    if (res.ok) onClose();
    else setError(res.error || 'خطا');
  };

  const labelStyle = {
    fontSize: 10.5, color: 'var(--muted)', marginBottom: 6,
    fontWeight: 500, padding: '0 2px',
  };
  const inputStyle = {
    width: '100%', boxSizing: 'border-box',
    padding: '11px 12px', borderRadius: 10,
    background: 'var(--bg)', border: '1px solid var(--border)',
    fontSize: 13, color: 'var(--ink)', outline: 'none',
    fontFamily: 'Vazirmatn, system-ui, sans-serif',
  };

  return (
    <>
      <div onClick={onClose}
           style={{ position: 'absolute', inset: 0, background: 'rgba(8,10,10,0.45)', zIndex: 20 }} />
      <div style={{
        position: 'absolute', left: 0, right: 0, bottom: 0,
        background: 'var(--surface)',
        borderTopLeftRadius: 22, borderTopRightRadius: 22,
        padding: '12px 18px 18px',
        boxShadow: '0 -10px 40px rgba(0,0,0,0.18)',
        zIndex: 21, direction: 'rtl', maxHeight: '90%',
        display: 'flex', flexDirection: 'column',
      }}>
        <div style={{ width: 40, height: 4, borderRadius: 99, background: 'var(--border)', margin: '0 auto 12px' }} />
        <div style={{
          display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 14,
        }}>
          <div style={{ fontSize: 15, fontWeight: 700 }}>
            {isEdit ? 'ویرایش کاربر' : 'افزودن کاربر'}
          </div>
          <button onClick={onClose} style={{
            all: 'unset', cursor: 'pointer', width: 28, height: 28, borderRadius: 99,
            background: 'var(--icon-bg)',
            display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--ink)',
          }}>
            <window.IconClose size={14} />
          </button>
        </div>

        <div style={{ flex: 1, minHeight: 0, overflowY: 'auto', paddingBottom: 4 }}>
          <div style={labelStyle}>نام و نام خانوادگی</div>
          <input value={name} onChange={e => setName(e.target.value)}
                 placeholder="مثلاً علی رضایی" style={{ ...inputStyle, marginBottom: 12 }} />

          <div style={labelStyle}>نام کاربری</div>
          <input value={username} onChange={e => setUsername(e.target.value)}
                 disabled={isEdit} placeholder="ali"
                 style={{ ...inputStyle, marginBottom: 12, direction: 'ltr', textAlign: 'left',
                          opacity: isEdit ? 0.6 : 1,
                          fontFamily: 'JetBrains Mono, ui-monospace, monospace' }} />

          <div style={labelStyle}>{isEdit ? 'گذرواژه جدید (اختیاری)' : 'گذرواژه'}</div>
          <input value={password} onChange={e => setPassword(e.target.value)}
                 type="password" placeholder={isEdit ? 'برای تغییر وارد کنید' : 'حداقل ۴ نویسه'}
                 style={{ ...inputStyle, marginBottom: 12, direction: 'ltr', textAlign: 'left',
                          fontFamily: 'JetBrains Mono, ui-monospace, monospace' }} />

          <div style={labelStyle}>نقش</div>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginBottom: 12 }}>
            {Object.keys(ROLE_META).map(r => {
              const active = role === r;
              return (
                <button key={r} onClick={() => setRole(r)} style={{
                  all: 'unset', cursor: 'pointer', padding: '8px 12px', borderRadius: 99,
                  background: active ? 'var(--accent)' : 'var(--icon-bg)',
                  color: active ? '#fff' : 'var(--ink)',
                  fontSize: 12, fontWeight: 600,
                }}>{ROLE_META[r].label}</button>
              );
            })}
          </div>

          {!isFull && (
            <>
              <div style={labelStyle}>سرپرست بالادست</div>
              <select value={parentId} onChange={e => setParentId(e.target.value)}
                      style={{ ...inputStyle, marginBottom: 12 }}>
                <option value="">— بدون سرپرست —</option>
                {parentOptions.map(p => (
                  <option key={p.id} value={p.id}>{p.name} ({ROLE_LABEL_A(p.role)})</option>
                ))}
              </select>
            </>
          )}

          <div style={{ display: 'flex', gap: 10, marginBottom: 12 }}>
            <div style={{ flex: 1 }}>
              <div style={labelStyle}>تلفن</div>
              <input value={phone} onChange={e => setPhone(e.target.value)}
                     placeholder="۰۹۱۲…"
                     style={{ ...inputStyle, direction: 'ltr', textAlign: 'left',
                              fontFamily: 'JetBrains Mono, ui-monospace, monospace' }} />
            </div>
            <div style={{ flex: 1 }}>
              <div style={labelStyle}>منطقه</div>
              <input value={region} onChange={e => setRegion(e.target.value)}
                     placeholder="تهران شمال" style={inputStyle} />
            </div>
          </div>

          {error && (
            <div style={{ fontSize: 11.5, color: 'var(--danger)', padding: '2px 2px 4px', fontWeight: 600 }}>
              {error}
            </div>
          )}
        </div>

        <button disabled={!valid} onClick={handleSubmit} style={{
          all: 'unset', cursor: valid ? 'pointer' : 'not-allowed',
          marginTop: 12, padding: '13px', textAlign: 'center', borderRadius: 14,
          background: valid ? 'var(--accent)' : 'var(--icon-bg)',
          color: valid ? '#fff' : 'var(--muted)', fontSize: 14, fontWeight: 700,
        }}>{busy ? 'در حال ذخیره…' : (isEdit ? 'ذخیره تغییرات' : 'افزودن کاربر')}</button>
      </div>
    </>
  );
}

window.AdminApp = AdminApp;
