/* global React, Icon, Button, Field, TextField, formatPhone, PickerTrigger, SlidePicker, RangeCalendar */
// Schools.ArtemenkoCRM — Добавить / редактировать сотрудника

const STAFF_ROLES = [
  { value: 'teacher', label: 'Преподаватель' },
  { value: 'manager', label: 'Менеджер' },
  { value: 'admin', label: 'Администратор' },
];

function StaffContacts({ contacts, onChange, openPicker }) {
  const { CONTACT_TYPES } = window.CRM_DATA;
  const setOne = (i, k, v) => onChange(contacts.map((c, idx) => idx === i ? { ...c, [k]: v } : c));
  const add = () => onChange([...contacts, { type: 'phone', value: '+7 ' }]);
  const remove = (i) => onChange(contacts.filter((_, idx) => idx !== i));
  const label = (t) => { const m = CONTACT_TYPES.find(x => x.value === t); return m ? m.label : (t || 'Канал'); };
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
      {contacts.map((c, i) => {
        const meta = CONTACT_TYPES.find(t => t.value === c.type) || {};
        return (
          <div key={i} className="om-fade-in" style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
            <div style={{ width: 130, flex: 'none' }}>
              <PickerTrigger label={label(c.type)} onClick={() => openPicker({ title: 'Способ связи', value: c.type, options: CONTACT_TYPES.map(t => ({ value: t.value, label: t.label })), allowCustom: true, customPlaceholder: 'Название канала', onPick: (v) => onChange(contacts.map((cc, idx) => idx === i ? { ...cc, type: v, value: window.reseedContactValue(v, cc.type, cc.value) } : cc)) })} />
            </div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <TextField value={c.value} onChange={v => setOne(i, 'value', window.maskContactValue(c.type, v))} placeholder={meta.ph || '@username'} mono={!!meta.mono} />
            </div>
            <button onClick={() => remove(i)} title="Удалить" style={{ border: 'none', background: 'none', cursor: 'pointer', color: 'var(--text-dim)', display: 'inline-flex', padding: 4, flex: 'none' }}>
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round"><path d="M9.2 9.2l5.6 5.6M14.8 9.2l-5.6 5.6"/></svg>
            </button>
          </div>
        );
      })}
      <button onClick={add} style={{ alignSelf: 'flex-start', border: 'none', background: 'none', cursor: 'pointer', color: 'var(--brand-ink)', fontSize: 13, fontWeight: 600, fontFamily: 'var(--font-sans)', display: 'inline-flex', alignItems: 'center', gap: 5, padding: '2px 0' }}>
        <Icon name="plus" size={15} />Добавить способ связи
      </button>
    </div>
  );
}

function ChipMulti({ items, selected, onToggle, onAdd }) {
  const [expanded, setExpanded] = React.useState(false);
  // ~2 rows ≈ 8 chips before collapsing
  const LIMIT = 8;
  const overflow = items.length > LIMIT;
  const shown = expanded || !overflow ? items : items.slice(0, LIMIT);
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 7 }}>
        {shown.map((it, ci) => {
          const on = selected.includes(it);
          return (
            <button key={it} onClick={() => onToggle(it)} className={expanded && ci >= LIMIT ? 'om-fade-in' : ''} style={{
              padding: '6px 12px', borderRadius: 'var(--radius-pill)', cursor: 'pointer', fontFamily: 'var(--font-sans)', fontSize: 13, fontWeight: 600,
              border: '1px solid ' + (on ? 'var(--brand)' : 'var(--border)'), background: on ? 'var(--brand-soft)' : 'var(--bg-card)', color: on ? 'var(--brand-ink)' : 'var(--text-secondary)',
              transition: 'background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease)',
            }}>{it}</button>
          );
        })}
        {overflow && (
          <button onClick={() => setExpanded(e => !e)} style={{ padding: '6px 12px', borderRadius: 'var(--radius-pill)', cursor: 'pointer', fontFamily: 'var(--font-sans)', fontSize: 13, fontWeight: 600, border: '1px dashed var(--border-strong)', background: 'var(--bg-card)', color: 'var(--brand-ink)' }}>
            {expanded ? 'Свернуть' : `Показать все (${items.length})`}
          </button>
        )}
      </div>
      {onAdd && (
        <button onClick={onAdd} style={{ alignSelf: 'flex-start', border: 'none', background: 'none', cursor: 'pointer', color: 'var(--brand-ink)', fontSize: 13, fontWeight: 600, fontFamily: 'var(--font-sans)', display: 'inline-flex', alignItems: 'center', gap: 5, padding: '2px 0' }}>
          <Icon name="settings-2" size={15} />Добавить направление
        </button>
      )}
    </div>
  );
}

// Модалка смены ставки: спрашивает, с какого числа ставка актуальна (прошлое/будущее/весь
// период), и предупреждает, что пересчитаются все непроведённые выплаты с этой даты.
function RateChangeModal({ staff, oldRate, newRate, onConfirm, onCancel }) {
  const fmt = (n) => new Intl.NumberFormat('ru-RU').format(n || 0);
  const todayISO = window.APP_TODAY_ISO || '2026-05-31';
  const hireISO = window.staffHireISO ? window.staffHireISO(staff) : '2000-01-01';
  const [mode, setMode] = React.useState('today'); // today | date | all
  const [date, setDate] = React.useState(todayISO);
  const [dateCalOpen, setDateCalOpen] = React.useState(false); // открыт ли наш стилизованный календарь
  const effFrom = mode === 'today' ? todayISO : mode === 'all' ? hireISO : date;
  const ruDate = (iso) => { const p = String(iso).split('-'); return p.length === 3 ? `${p[2]}.${p[1]}.${p[0]}` : iso; };
  const opt = (val, label, sub) => (
    <button onClick={() => setMode(val)} style={{ display: 'flex', alignItems: 'flex-start', gap: 10, textAlign: 'left', width: '100%', padding: '11px 13px', borderRadius: 'var(--radius-sm)', cursor: 'pointer', background: mode === val ? 'var(--brand-soft)' : 'var(--bg-card)', border: '1px solid ' + (mode === val ? 'var(--brand)' : 'var(--border)'), transition: 'background var(--dur-fast), border-color var(--dur-fast)' }}>
      <span style={{ width: 16, height: 16, borderRadius: '50%', flex: 'none', marginTop: 1, boxSizing: 'border-box', border: '2px solid ' + (mode === val ? 'var(--brand)' : 'var(--border-strong)'), background: mode === val ? 'var(--brand)' : 'transparent', boxShadow: mode === val ? 'inset 0 0 0 2px var(--bg-card)' : 'none' }} />
      <span style={{ flex: 1, minWidth: 0 }}>
        <span style={{ display: 'block', fontSize: 13.5, fontWeight: 600, color: 'var(--text)' }}>{label}</span>
        {sub && <span style={{ display: 'block', fontSize: 12, color: 'var(--text-dim)', marginTop: 2 }}>{sub}</span>}
      </span>
    </button>
  );
  return (
    <div style={{ position: 'fixed', inset: 0, zIndex: 60, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 24 }}>
      <div onClick={onCancel} className="om-fade-in" style={{ position: 'absolute', inset: 0, background: 'rgba(21,28,46,0.5)', backdropFilter: 'blur(2px)' }} />
      <div className="om-sheet-up" style={{ position: 'relative', width: 440, maxWidth: '100%', background: 'var(--bg-card)', borderRadius: 'var(--radius-lg)', boxShadow: 'var(--shadow-lg)', overflow: 'visible' }}>
        <div style={{ padding: '18px 22px 14px', borderBottom: '1px solid var(--border)' }}>
          <h3 style={{ fontSize: 17, fontWeight: 700, margin: 0, color: 'var(--text)' }}>Смена ставки</h3>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 10, marginTop: 8 }}>
            <span style={{ fontFamily: 'var(--font-mono)', fontSize: 15, color: 'var(--text-dim)', textDecoration: 'line-through' }}>{fmt(oldRate)} ₽</span>
            <Icon name="arrow-right" size={15} style={{ color: 'var(--text-dim)', alignSelf: 'center' }} />
            <span style={{ fontFamily: 'var(--font-mono)', fontSize: 15, fontWeight: 700, color: 'var(--brand-ink)' }}>{fmt(newRate)} ₽</span>
            <span style={{ fontSize: 12, color: 'var(--text-dim)' }}>/занятие</span>
          </div>
        </div>
        <div style={{ padding: '16px 22px', display: 'flex', flexDirection: 'column', gap: 9 }}>
          <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--text-secondary)' }}>С какого числа действует новая ставка?</div>
          {opt('today', 'С сегодняшнего дня', ruDate(todayISO))}
          {opt('date', 'С конкретной даты', 'можно указать в прошлом или будущем')}
          {mode === 'date' && (
            <div className="om-fade-in" style={{ position: 'relative', marginLeft: 26 }}>
              <button type="button" onClick={() => setDateCalOpen(o => !o)} style={{ display: 'inline-flex', alignItems: 'center', gap: 8, padding: '9px 12px', cursor: 'pointer', background: 'var(--bg-card)', border: '1px solid ' + (dateCalOpen ? 'var(--brand)' : 'var(--border-strong)'), borderRadius: 'var(--radius-sm)', fontFamily: 'var(--font-mono)', fontSize: 13.5, color: 'var(--text)', boxShadow: dateCalOpen ? 'var(--shadow-focus)' : 'none' }}>
                <Icon name="calendar" size={15} style={{ color: 'var(--text-dim)' }} />{ruDate(date)}
              </button>
              {dateCalOpen && <RangeCalendar single value={{ start: date, end: date }} onApply={(r) => setDate(r.start)} onClose={() => setDateCalOpen(false)} />}
            </div>
          )}
          {opt('all', 'За весь период работы', `с ${ruDate(hireISO)}`)}
        </div>
        <div style={{ margin: '0 22px 16px', padding: '12px 14px', borderRadius: 'var(--radius-md)', background: 'var(--gold-soft)', border: '1px solid #E7CFA3', display: 'flex', gap: 10 }}>
          <Icon name="alert-triangle" size={17} style={{ color: 'var(--gold-ink)', flex: 'none', marginTop: 1 }} />
          <span style={{ fontSize: 12.5, color: 'var(--text-secondary)', lineHeight: 1.45 }}>
            Будут пересчитаны <b style={{ color: 'var(--text)' }}>все непроведённые (несформированные) выплаты</b> начиная с <b style={{ color: 'var(--text)' }}>{ruDate(effFrom)}</b>. Уже выплаченные начисления не изменятся.
          </span>
        </div>
        <div style={{ padding: '0 22px 18px', display: 'flex', justifyContent: 'flex-end', gap: 10 }}>
          <Button variant="ghost" onClick={onCancel}>Отмена</Button>
          <Button variant="primary" icon="check" onClick={() => onConfirm(effFrom)}>Подтвердить</Button>
        </div>
      </div>
    </div>
  );
}

// Стилизованная подсказка (как наши модалки): всплывает над кнопкой, исчезает при уходе мыши.
function Tip({ text, width = 250, children }) {
  const [show, setShow] = React.useState(false);
  return (
    <span style={{ position: 'relative', display: 'inline-flex' }}
      onMouseEnter={() => setShow(true)} onMouseLeave={() => setShow(false)}>
      {children}
      {show && (
        <span className="om-fade-in" style={{
          position: 'absolute', bottom: 'calc(100% + 10px)', left: '50%', transform: 'translateX(-50%)',
          width, zIndex: 60, background: 'var(--bg-card)', color: 'var(--text-secondary)',
          border: '1px solid var(--border)', padding: '11px 13px', borderRadius: 'var(--radius-md)',
          boxShadow: 'var(--shadow-lg)', fontSize: 12, lineHeight: 1.5, fontWeight: 500,
          textAlign: 'left', pointerEvents: 'none', whiteSpace: 'normal',
        }}>
          {text}
          <span style={{ position: 'absolute', top: '100%', left: '50%', transform: 'translateX(-50%) rotate(45deg)', marginTop: -5, width: 10, height: 10, background: 'var(--bg-card)', borderRight: '1px solid var(--border)', borderBottom: '1px solid var(--border)' }} />
        </span>
      )}
    </span>
  );
}

function AddStaffModal({ onClose, onCreate, staff, onNavSettings, onFire, onDelete }) {
  const D = window.CRM_DATA;
  const editing = !!staff;
  const [shown, setShown] = React.useState(false);
  const [picker, setPicker] = React.useState(null);
  const [pickerCloseReq, setPickerCloseReq] = React.useState(0);

  const [role, setRole] = React.useState(staff ? staff.role : 'teacher');
  const [name, setName] = React.useState(staff ? staff.name : '');
  const origRate = staff ? (staff.rate || 0) : 0;
  const [rateModal, setRateModal] = React.useState(false);
  // teacher
  const [tPosition, setTPosition] = React.useState(staff && staff.position ? staff.position : D.TEACHER_POSITIONS[0]);
  const [rate, setRate] = React.useState(staff && staff.rate ? String(staff.rate) : '');
  // Seed контактов: если массива contacts ещё нет (старые педагоги) — переносим телефон/Telegram
  // из legacy-полей contact/tg, иначе при сохранении номер затирается.
  const seedStaffContacts = () => {
    if (staff && staff.contacts && staff.contacts.length) return staff.contacts.map(c => ({ ...c }));
    if (staff) {
      const arr = [];
      if (staff.contact && staff.contact !== '—') arr.push({ type: 'phone', value: staff.contact });
      if (staff.tg) arr.push({ type: 'telegram', value: staff.tg.replace(/^@?/, '@') });
      if (arr.length) return arr;
    }
    return [{ type: 'phone', value: '+7 ' }];
  };
  const [contacts, setContacts] = React.useState(seedStaffContacts());
  const [subjects, setSubjects] = React.useState(staff && staff.subjects ? [...staff.subjects] : []);
  const [payMethod, setPayMethod] = React.useState(staff && staff.payMethod ? staff.payMethod : null);
  const [notes, setNotes] = React.useState(staff && staff.notes ? staff.notes : '');
  // manager / admin
  const [login, setLogin] = React.useState(staff && staff.login ? staff.login : '');
  const [password, setPassword] = React.useState('');
  const [tg, setTg] = React.useState(staff && staff.tg ? staff.tg.replace(/^@/, '') : '');
  const [phone, setPhone] = React.useState(staff ? (staff.phone || (staff.contact && staff.contact !== '—' ? staff.contact : '')) : '');
  const [mPosition, setMPosition] = React.useState(staff && staff.position ? staff.position : D.MANAGER_POSITIONS[0]);
  const [payDest, setPayDest] = React.useState(staff && staff.payDest ? staff.payDest : '');

  React.useEffect(() => { const t = setTimeout(() => setShown(true), 10); return () => clearTimeout(t); }, []);
  const close = () => { setShown(false); setTimeout(onClose, 200); };
  const roleDef = (D.STAFF_ROLES || []).find(r => r.value === role) || { value: role, label: role, kind: role === 'teacher' ? 'teacher' : 'account' };
  const isTeacher = roleDef.kind === 'teacher';
  const roleLabel = roleDef.label;
  const goAddRole = () => { close(); if (onNavSettings) onNavSettings('staff-roles'); };
  const goAddDirection = () => { close(); if (onNavSettings) onNavSettings('staff-directions'); };

  // Аккаунт обязателен ВСЕМ: без логина сотрудник не войдёт в кабинет, а профиль не к чему привязать.
  // При правке пароль можно не трогать (пустое поле = оставить прежний).
  const canSave = !!name.trim() && !!login.trim() && (editing || !!password.trim());
  const submit = (rateChange) => {
    const base = { id: staff ? staff.id : Date.now() % 100000, role, name: name.trim(), status: staff ? staff.status : 'active', since: staff ? staff.since : 'сегодня', animal: staff ? staff.animal : 'paw-print', tone: staff ? staff.tone : (role === 'teacher' ? 'navy' : role === 'manager' ? 'green' : 'gold') };
    const payload = isTeacher
      ? { ...base, position: tPosition, rate: parseInt((rate || '0').replace(/\D/g, ''), 10) || 0, contacts, subjects, payMethod, notes: notes.trim(), login: login.trim(), password: password.trim() ? password.trim() : (staff ? staff.password : ''), tg: (contacts.find(c => c.type === 'telegram') || {}).value || (staff ? staff.tg : ''), contact: (contacts.find(c => c.type === 'phone') || {}).value || '—' }
      : { ...base, position: mPosition, login: login.trim(), password: password.trim() ? password.trim() : (staff ? staff.password : ''), tg: tg ? '@' + tg.replace(/^@/, '') : '', phone, payDest, subjects: [], rate: 0, contact: phone || '—' };
    if (rateChange) payload.__rateChange = rateChange;
    onCreate(payload, editing);
  };
  const finish = () => {
    // Сменили ставку преподавателю → сначала спросить, с какого числа она действует.
    if (editing && isTeacher) {
      const nr = parseInt((rate || '0').replace(/\D/g, ''), 10) || 0;
      if (nr !== origRate) { setRateModal(true); return; }
    }
    setPicker(null); setShown(false); setTimeout(() => submit(), 200);
  };
  const confirmRate = (effFrom) => {
    const nr = parseInt((rate || '0').replace(/\D/g, ''), 10) || 0;
    setRateModal(false); setPicker(null); setShown(false);
    setTimeout(() => submit({ from: effFrom, rate: nr }), 200);
  };
  const toggleSubject = (s) => setSubjects(p => p.includes(s) ? p.filter(x => x !== s) : [...p, s]);

  return (
    <div style={{ position: 'fixed', inset: 0, zIndex: 50 }}>
      <div onClick={close} style={{ position: 'absolute', inset: 0, background: 'rgba(21,28,46,0.45)', backdropFilter: 'blur(2px)', opacity: shown ? 1 : 0, transition: 'opacity var(--dur) var(--ease)' }} />
      <div style={{ position: 'absolute', top: 0, right: 0, bottom: 0, display: 'flex' }}>
        <div style={{ position: 'relative', width: 0, zIndex: 0 }}>
          <SlidePicker cfg={picker} onClose={() => setPicker(null)} closeReq={pickerCloseReq} />
        </div>
        <aside style={{
          width: 440, maxWidth: '100vw', background: 'var(--bg-card)', boxShadow: 'var(--shadow-lg)', position: 'relative', zIndex: 2,
          display: 'flex', flexDirection: 'column', height: '100%',
          transform: shown ? 'translateX(0)' : 'translateX(100%)', transition: 'transform 280ms cubic-bezier(0.22, 1, 0.36, 1)',
        }}>
          <div style={{ padding: '18px 22px', borderBottom: '1px solid var(--border)', display: 'flex', alignItems: 'center', gap: 12 }}>
            <span style={{ width: 40, height: 40, borderRadius: 'var(--radius-md)', background: 'var(--brand-soft)', color: 'var(--brand-ink)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flex: 'none' }}>
              <Icon name="user-plus" size={20} />
            </span>
            <div style={{ flex: 1 }}>
              <h2 style={{ fontSize: 18, fontWeight: 700, letterSpacing: '-0.3px', margin: 0, color: 'var(--text)' }}>{editing ? 'Редактировать сотрудника' : 'Добавить сотрудника'}</h2>
              <div style={{ fontSize: 13, color: 'var(--text-dim)', marginTop: 1 }}>{editing ? staff.name : 'Новый сотрудник школы'}</div>
            </div>
            <button onClick={close} title="Закрыть" style={{ width: 34, height: 34, borderRadius: 6, border: '1px solid var(--border)', background: 'var(--bg-card)', cursor: 'pointer', color: 'var(--text-secondary)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flex: 'none' }}>
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round"><path d="M9.2 9.2l5.6 5.6M14.8 9.2l-5.6 5.6"/></svg>
            </button>
          </div>

          <div style={{ flex: 1, overflowY: 'auto', padding: '20px 22px', display: 'flex', flexDirection: 'column', gap: 16 }}>
            {/* Role picker (configurable, slides left) — can be changed even when editing */}
            <Field label="Роль">
              <PickerTrigger label={roleLabel} onClick={() => { setPicker({
                title: 'Роль сотрудника', value: role,
                options: (D.STAFF_ROLES || []).map(r => ({ value: r.value, label: r.label })).concat([{ value: '__add', label: '+ Добавить роль…' }]),
                onPick: (v) => { if (v === '__add') goAddRole(); else setRole(v); },
              }); }} />
            </Field>

            <Field label="ФИО" required><TextField value={name} onChange={setName} placeholder="Например, Иванов Иван Иванович" autoFocus /></Field>

            <div key={role} className="om-step-in" style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
              {isTeacher ? (
                <React.Fragment>
                  <Field label="Должность">
                    <PickerTrigger label={tPosition} onClick={() => setPicker({ title: 'Должность', value: tPosition, options: D.TEACHER_POSITIONS.map(p => ({ value: p, label: p })), allowCustom: true, customPlaceholder: 'Своя должность', onPick: setTPosition })} />
                  </Field>
                  <Field label="Ставка (₽/занятие)"><TextField value={rate} onChange={v => setRate(v.replace(/\D/g, ''))} placeholder="0" mono /></Field>
                  <Field label="Способы связи"><StaffContacts contacts={contacts} onChange={setContacts} openPicker={setPicker} /></Field>
                  <Field label="Направления обучения"><ChipMulti items={D.DIRECTIONS} selected={subjects} onToggle={toggleSubject} onAdd={goAddDirection} /></Field>
                  <Field label="Приоритетный способ оплаты">
                    <PickerTrigger label={payMethod} placeholder="Не указан" onClick={() => setPicker({ title: 'Способ оплаты', value: payMethod, options: D.PAYMENT_METHODS.map(m => ({ value: m, label: m })), onPick: setPayMethod })} />
                  </Field>
                  {/* Доступ в кабинет — обязателен: по этому логину преподаватель войдёт,
                      и именно к нему привяжется его профиль (staff.user_id). */}
                  <Field label="Логин для входа в кабинет" required>
                    <TextField value={login} onChange={setLogin} placeholder="ivanov" mono />
                  </Field>
                  <Field label={editing ? 'Новый пароль' : 'Пароль'} required={!editing}>
                    <TextField value={password} onChange={setPassword} placeholder={editing ? 'оставьте пустым, чтобы не менять' : '••••••••'} />
                  </Field>
                  <Field label="Заметки">
                    <textarea value={notes} onChange={e => setNotes(e.target.value)} placeholder="Комментарий о сотруднике…" rows={3} style={{ width: '100%', boxSizing: 'border-box', resize: 'vertical', border: '1px solid var(--border)', borderRadius: 'var(--radius-sm)', padding: '10px 12px', fontFamily: 'var(--font-sans)', fontSize: 14, color: 'var(--text)', outline: 'none', background: 'var(--bg-card)' }} />
                  </Field>
                </React.Fragment>
              ) : (
                <React.Fragment>
                  <Field label="Логин" required><TextField value={login} onChange={setLogin} placeholder="ivanov" mono /></Field>
                  <Field label={editing ? 'Новый пароль' : 'Пароль'} required={!editing}><TextField value={password} onChange={setPassword} placeholder="••••••••" /></Field>
                  <Field label="Telegram тег">
                    <div style={{ display: 'flex', alignItems: 'center', border: '1px solid var(--border)', borderRadius: 'var(--radius-sm)', background: 'var(--bg-card)', overflow: 'hidden' }}>
                      <span style={{ padding: '10px 4px 10px 12px', color: 'var(--text-dim)', fontFamily: 'var(--font-mono)', fontSize: 14 }}>@</span>
                      <input value={tg} onChange={e => setTg(e.target.value.replace(/^@/, ''))} placeholder="owner" style={{ flex: 1, border: 'none', outline: 'none', background: 'transparent', fontFamily: 'var(--font-mono)', fontSize: 14, color: 'var(--text)', padding: '10px 12px 10px 0' }} />
                    </div>
                  </Field>
                  <Field label="Телефон"><TextField value={phone} onChange={v => setPhone(formatPhone(v))} placeholder="+7 (___) ___-__-__" mono /></Field>
                  <Field label="Позиция">
                    <PickerTrigger label={mPosition} onClick={() => setPicker({ title: 'Позиция', value: mPosition, options: D.MANAGER_POSITIONS.map(p => ({ value: p, label: p })), allowCustom: true, customPlaceholder: 'Своя позиция', onPick: setMPosition })} />
                  </Field>
                  <Field label="Способ оплаты"><TextField value={payDest} onChange={setPayDest} placeholder="Сбербанк, карта и т.д." /></Field>
                </React.Fragment>
              )}
            </div>
          </div>

          <div style={{ padding: '14px 22px', borderTop: '1px solid var(--border)', display: 'flex', alignItems: 'center', gap: 10 }}>
            {editing && (
              <React.Fragment>
                <Tip width={260} text="Удаление безвозвратно: запись сотрудника и вся его история будут стёрты без возможности восстановления.">
                  <button onClick={() => { setShown(false); setTimeout(() => onDelete && onDelete(staff), 200); }} style={{ width: 38, height: 38, borderRadius: 'var(--radius-sm)', border: '1px solid #E6C9C4', background: 'var(--bg-card)', cursor: 'pointer', color: 'var(--coral)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flex: 'none', transition: 'background var(--dur-fast) var(--ease)' }} onMouseEnter={e => { e.currentTarget.style.background = 'var(--coral-bg)'; }} onMouseLeave={e => { e.currentTarget.style.background = 'var(--bg-card)'; }}>
                    <Icon name="trash-2" size={17} />
                  </button>
                </Tip>
                {staff.status !== 'fired' && <Tip width={280} text="Увольнение сохраняет все данные сотрудника, но исключает его из аналитики и работы: он пропадает из списков назначения, расчётов зарплат и активной статистики. Запись остаётся в архиве."><Button variant="secondary" icon="user-x" onClick={() => { setShown(false); setTimeout(() => onFire && onFire(staff), 200); }}>Уволить</Button></Tip>}
              </React.Fragment>
            )}
            <div style={{ flex: 1 }} />
            <Button variant="ghost" onClick={close}>Отмена</Button>
            <Button variant="primary" icon={editing ? 'check' : 'add-student'} onClick={() => canSave && finish()} style={canSave ? {} : { opacity: 0.5, cursor: 'not-allowed' }}>{editing ? 'Сохранить' : 'Создать'}</Button>
          </div>
        </aside>
      </div>
      {rateModal && <RateChangeModal staff={staff} oldRate={origRate} newRate={parseInt((rate || '0').replace(/\D/g, ''), 10) || 0} onConfirm={confirmRate} onCancel={() => setRateModal(false)} />}
    </div>
  );
}

Object.assign(window, { AddStaffModal });
