/* global React, Icon, Button, PickerTrigger, SlidePicker, Field, TextField, RangeCalendar, Overline, ModalLayer */
// Schools.ArtemenkoCRM — Выплата зарплаты (slide-in)
// Модель: выплата = неизменяемый снимок занятий. Сервер платит ТОЛЬКО за ещё не оплаченные
// занятия периода; ставка берётся на дату занятия. Правая панель — серверная правда (превью).

const MON_SH = ['янв', 'фев', 'мар', 'апр', 'мая', 'июн', 'июл', 'авг', 'сен', 'окт', 'ноя', 'дек'];
const isoNow = () => window.APP_TODAY_ISO || (() => { const d = new Date(); return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`; })();
const fmtIso = (s) => { if (!s) return '—'; const [y, m, d] = s.split('-'); return `${+d} ${MON_SH[+m - 1]} ${y}`; };
const payHourFmt = (h) => `${String(Math.floor(h)).padStart(2, '0')}:${h % 1 ? '30' : '00'}`;
const payRub = (n) => new Intl.NumberFormat('ru-RU').format(n) + ' ₽';
const payLessonTime = (l) => l.time || (l.start != null ? payHourFmt(l.start) + '–' + payHourFmt(l.end) : '');

// Одна строка серверного скелетона (не прыгающий layout).
function SkelRow() {
  const bar = (w, h) => <span className="om-skel" style={{ display: 'block', height: h, width: w, borderRadius: 4, background: 'var(--bg-soft)' }} />;
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 11, padding: '10px 0', borderTop: '1px solid var(--border)' }}>
      <span className="om-skel" style={{ width: 8, height: 8, borderRadius: '50%', background: 'var(--bg-soft)', flex: 'none' }} />
      <div style={{ width: 76, flex: 'none', display: 'flex', flexDirection: 'column', gap: 5 }}>{bar(44, 12)}{bar(52, 10)}</div>
      <div style={{ flex: 1, minWidth: 0 }}>{bar('72%', 13)}</div>
      <div style={{ flex: 'none' }}>{bar(56, 13)}</div>
    </div>
  );
}

// Правая панель «Занятия за период» — СЕРВЕРНАЯ правда. 4 состояния: idle / loading / empty / list.
function PayoutLessonsPanel({ pv }) {
  const LS = (window.CRM_DATA && window.CRM_DATA.LESSON_STATUS) || {};
  const status = pv.status;
  const data = pv.data;
  const toPay = data ? data.toPay : [];
  const total = data ? data.sum : 0;
  const mixed = new Set(toPay.map(l => l.pay)).size > 1;
  const allPaid = status === 'ready' && data.totalCount > 0 && toPay.length === 0;   // занятия были, но закрыты
  const noLessons = status === 'ready' && data.totalCount === 0;                       // занятий не было вовсе

  return (
    <div style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', background: 'var(--bg)' }}>
      <div style={{ padding: '18px 20px 12px', borderBottom: '1px solid var(--border)', flex: 'none' }}>
        <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', gap: 10 }}>
          <Overline style={{ whiteSpace: 'nowrap' }}>Занятия к оплате</Overline>
          {status === 'ready' && toPay.length > 0 && <span style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--text-dim)' }}>{toPay.length}</span>}
        </div>
        {status === 'ready' && toPay.length > 0 && (
          <div style={{ fontSize: 12.5, color: 'var(--text-dim)', marginTop: 4 }}>К выплате за занятия <b style={{ color: 'var(--green)', fontFamily: 'var(--font-mono)' }}>{payRub(total)}</b>{mixed && <span style={{ marginLeft: 6, color: 'var(--gold-ink)', fontWeight: 600 }}>· ставки по дате</span>}</div>
        )}
        {status === 'ready' && data.coveredCount > 0 && toPay.length > 0 && (
          <div style={{ fontSize: 11.5, color: 'var(--text-dim)', marginTop: 3 }}>{data.coveredCount} из {data.totalCount} уже оплачено ранее — в расчёт не входят</div>
        )}
      </div>

      <div style={{ flex: 1, minHeight: 0, overflowY: 'auto', overflowX: 'hidden', padding: '4px 20px 18px' }}>
        {status === 'idle' && (
          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', minHeight: 180, textAlign: 'center', padding: '0 12px' }}>
            <span style={{ width: 46, height: 46, borderRadius: 'var(--radius-md)', background: 'var(--bg-soft)', color: 'var(--text-dim)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', marginBottom: 12 }}><Icon name="calendar" size={22} strokeWidth={1.6} /></span>
            <div style={{ fontSize: 13, color: 'var(--text-dim)', lineHeight: 1.5 }}>Выберите период слева —<br />здесь появятся занятия к оплате.</div>
          </div>
        )}
        {status === 'loading' && (
          <div style={{ paddingTop: 6 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, color: 'var(--text-dim)', fontSize: 12.5, padding: '2px 0 8px' }}>
              <span className="om-spin"><Icon name="loader" size={14} /></span>Загружаем занятия за период…
            </div>
            <SkelRow /><SkelRow /><SkelRow /><SkelRow />
          </div>
        )}
        {noLessons && (
          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', minHeight: 180, textAlign: 'center', padding: '0 12px' }} className="om-fade-in">
            <span style={{ width: 46, height: 46, borderRadius: 'var(--radius-md)', background: 'var(--bg-soft)', color: 'var(--text-dim)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', marginBottom: 12 }}><Icon name="calendar-x" size={22} strokeWidth={1.6} /></span>
            <div style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--text-secondary)' }}>За период занятий не было</div>
          </div>
        )}
        {allPaid && (
          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', minHeight: 180, textAlign: 'center', padding: '0 12px' }} className="om-fade-in">
            <span style={{ width: 46, height: 46, borderRadius: 'var(--radius-md)', background: 'var(--green-bg)', color: 'var(--green-ink)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', marginBottom: 12 }}><Icon name="check-circle" size={24} /></span>
            <div style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--green-ink)' }}>Все занятия за период уже оплачены</div>
            <div style={{ fontSize: 12, color: 'var(--text-dim)', marginTop: 4 }}>{data.totalCount} зан. закрыты предыдущими выплатами</div>
          </div>
        )}
        {status === 'ready' && toPay.length > 0 && toPay.map((l, i) => {
          const s = LS[l.status] || {};
          return (
            <div key={i} className="om-row-in" style={{ display: 'flex', alignItems: 'center', gap: 11, padding: '10px 0', borderTop: i ? '1px solid var(--border)' : 'none' }}>
              <span title={s.label} style={{ width: 8, height: 8, borderRadius: '50%', background: s.dot || 'var(--text-dim)', flex: 'none' }} />
              <div style={{ width: 76, flex: 'none' }}>
                <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--text)', whiteSpace: 'nowrap' }}>{l.dateLabel}</div>
                <div style={{ fontSize: 11.5, color: 'var(--text-dim)', fontFamily: 'var(--font-mono)', whiteSpace: 'nowrap' }}>{payLessonTime(l)}</div>
              </div>
              <span style={{ flex: 1, minWidth: 0, fontSize: 13.5, color: 'var(--text)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{l.who}{l.group && <span style={{ fontSize: 9, fontWeight: 700, padding: '1px 5px', borderRadius: 3, background: 'var(--bg-soft)', color: 'var(--text-dim)', marginLeft: 6 }}>ГР</span>}</span>
              <span style={{ fontFamily: 'var(--font-mono)', fontSize: 13, fontWeight: 600, color: 'var(--green)', flex: 'none' }}>{payRub(l.pay)}</span>
            </div>
          );
        })}
      </div>
    </div>
  );
}

function AddPayoutModal({ onClose, onCreate, payout, prefillPeriod }) {
  const { PAYMENT_METHODS } = window.CRM_DATA;
  const [shown, setShown] = React.useState(false);
  const [picker, setPicker] = React.useState(null);

  const tId = payout ? (payout.teacherId != null ? payout.teacherId : payout.id) : null;
  const staffObj = (window.CRM_DATA.STAFF || []).find(s => s.id === tId) || null;

  // Умный дефолт периода: prefillPeriod (из «Доплатить») → последний месяц с неоплаченными.
  const initialRange = React.useMemo(() => {
    if (prefillPeriod && prefillPeriod.start && prefillPeriod.end) return prefillPeriod;
    if (staffObj && window.lastUnpaidPeriod) return window.lastUnpaidPeriod(staffObj);
    return null;
  }, []);
  const [range, setRange] = React.useState(initialRange);       // {start,end} ISO
  const [rangeCal, setRangeCal] = React.useState(false);

  // Серверное превью периода: { status: idle|loading|ready, data }.
  const [pv, setPv] = React.useState({ status: 'idle', data: null });

  // Корректировка (премия/удержание).
  const [adjMode, setAdjMode] = React.useState('none');         // none | bonus | deduct
  const [adjAmount, setAdjAmount] = React.useState('');
  const [adjNote, setAdjNote] = React.useState('');

  const [when, setWhen] = React.useState('now');                // now | schedule
  const [payDate, setPayDate] = React.useState(isoNow());
  const [dateCal, setDateCal] = React.useState(false);
  const [method, setMethod] = React.useState(PAYMENT_METHODS[0] || null);
  const [comment, setComment] = React.useState('');
  const rangeRef = React.useRef(null);
  const dateRef = React.useRef(null);

  React.useEffect(() => { const t = setTimeout(() => setShown(true), 10); return () => clearTimeout(t); }, []);
  React.useEffect(() => {
    const h = (e) => {
      if (rangeRef.current && !rangeRef.current.contains(e.target)) setRangeCal(false);
      if (dateRef.current && !dateRef.current.contains(e.target)) setDateCal(false);
    };
    document.addEventListener('mousedown', h); return () => document.removeEventListener('mousedown', h);
  }, []);
  const close = () => { setShown(false); setTimeout(onClose, 200); };

  // Дергаем серверное превью при каждом изменении периода (debounce 300мс).
  React.useEffect(() => {
    if (!range || !range.start || !range.end || tId == null || !window.fetchPayoutPreview) { setPv({ status: 'idle', data: null }); return; }
    setPv({ status: 'loading', data: null });
    let cancelled = false;
    const t = setTimeout(() => {
      window.fetchPayoutPreview(tId, range.start, range.end)
        .then(res => { if (!cancelled) setPv({ status: 'ready', data: res }); })
        .catch(() => { if (!cancelled) setPv({ status: 'idle', data: null }); });
    }, 300);
    return () => { cancelled = true; clearTimeout(t); };
  }, [range && range.start, range && range.end, tId]);

  const ready = pv.status === 'ready';
  const toPay = ready ? pv.data.toPay : [];
  const calc = ready ? pv.data.sum : 0;                          // расчёт по занятиям
  const rateSet = Array.from(new Set(toPay.map(l => l.pay)));
  const singleRate = rateSet.length === 1 ? rateSet[0] : null;

  // Корректировка → знаковая сумма + итог.
  const adjNum = parseInt((adjAmount || '0').replace(/\D/g, ''), 10) || 0;
  const signed = adjMode === 'bonus' ? adjNum : adjMode === 'deduct' ? -adjNum : 0;
  const total = calc + signed;
  const deductTooBig = adjMode === 'deduct' && adjNum > calc;    // итог ушёл бы в минус
  const reasonMissing = adjMode !== 'none' && adjNum > 0 && !adjNote.trim();
  const pureBonus = ready && calc === 0 && adjMode === 'bonus' && adjNum > 0;   // выплата только из премии

  const rangeLabel = range ? `${fmtIso(range.start)} – ${fmtIso(range.end)}` : 'Выберите период';
  const canSave = ready && total > 0 && !deductTooBig && !reasonMissing && (calc > 0 || pureBonus);
  const disabledReason = !ready ? 'Выберите период — дождитесь расчёта занятий'
    : deductTooBig ? 'Удержание больше расчёта — итог не может быть отрицательным'
    : reasonMissing ? 'Укажите причину корректировки'
    : total <= 0 ? 'Нет занятий к оплате и нет премии'
    : '';

  const submit = (attr) => onCreate({
    payoutId: payout ? payout.id : null,
    teacher: payout ? payout.teacher : '',
    period: range, lessons: toPay.length, rate: singleRate || 0,
    amount: total, status: when === 'now' ? 'paid' : 'planned',
    payDate: when === 'schedule' ? payDate : isoNow(), method, comment: comment.trim(),
    adjustmentRubles: signed, adjustmentNote: signed ? adjNote.trim() : '',
    expenseAttr: attr || 'period',
    // Замороженная разбивка: ровно те занятия, за которые платим (toPay), по ставке на дату.
    lessonsDetail: toPay.map(l => ({ dateISO: l.dateISO, dateLabel: l.dateLabel, time: payLessonTime(l), who: l.who, group: !!l.group, amount: l.pay, status: l.status })),
  });
  const finish = (attr) => { setPicker(null); setShown(false); setTimeout(() => submit(attr), 200); };
  // Платим за ПРОШЛЫЙ месяц? → спросим, в каком месяце учесть расход.
  const [pastWarn, setPastWarn] = React.useState(false);
  const payISOnow = when === 'schedule' ? payDate : isoNow();
  const periodM = (range && range.start) ? (+range.start.slice(5, 7) - 1) : null;
  const periodY = (range && range.start) ? (+range.start.slice(0, 4)) : null;
  const payM = +payISOnow.slice(5, 7) - 1, payY = +payISOnow.slice(0, 4);
  const isPastPeriod = periodM != null && (periodY < payY || (periodY === payY && periodM < payM));
  const tryFinish = () => { if (!canSave) return; if (isPastPeriod) setPastWarn(true); else finish('period'); };

  const dateBtn = (label, onClick, active) => (
    <button onClick={onClick}
      onMouseEnter={e => { if (!active) e.currentTarget.style.borderColor = 'var(--border-strong)'; }}
      onMouseLeave={e => { if (!active) e.currentTarget.style.borderColor = 'var(--border)'; }}
      style={{ display: 'inline-flex', alignItems: 'center', gap: 8, width: '100%', justifyContent: 'flex-start', padding: '10px 13px', cursor: 'pointer', background: 'var(--bg-card)', border: '1px solid ' + (active ? 'var(--brand)' : 'var(--border)'), borderRadius: 'var(--radius-sm)', boxShadow: active ? 'var(--shadow-focus)' : 'none', fontFamily: 'var(--font-sans)', fontSize: 14, fontWeight: 500, color: 'var(--text)', transition: 'border-color var(--dur-fast) var(--ease)' }}>
      <Icon name="calendar" size={15} style={{ color: 'var(--text-dim)' }} />{label}
    </button>
  );

  // Сегмент-переключатель (общий стиль).
  const segment = (opts, val, onPick) => (
    <div style={{ display: 'inline-flex', background: 'var(--bg-soft)', borderRadius: 'var(--radius-sm)', padding: 3, gap: 2, width: '100%' }}>
      {opts.map(o => (
        <button key={o.id} onClick={() => onPick(o.id)}
          onMouseEnter={e => { if (val !== o.id) e.currentTarget.style.background = 'var(--bg-card)'; }}
          onMouseLeave={e => { if (val !== o.id) e.currentTarget.style.background = 'transparent'; }}
          style={{ flex: 1, padding: '7px 6px', border: 'none', borderRadius: 5, cursor: 'pointer', fontFamily: 'var(--font-sans)', fontSize: 13, fontWeight: 600, background: val === o.id ? 'var(--bg-card)' : 'transparent', color: val === o.id ? (o.color || 'var(--brand-ink)') : 'var(--text-dim)', boxShadow: val === o.id ? 'var(--shadow-xs)' : 'none', transition: 'background var(--dur-fast) var(--ease)' }}>{o.label}</button>
      ))}
    </div>
  );

  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)} />
        </div>
        <aside style={{
          width: 'min(880px, 100vw)', 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(--green-bg)', color: 'var(--green-ink)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flex: 'none' }}>
              <Icon name="wallet" size={20} />
            </span>
            <div style={{ flex: 1, minWidth: 0 }}>
              <h2 style={{ fontSize: 18, fontWeight: 700, letterSpacing: '-0.3px', margin: 0, color: 'var(--text)' }}>Выплата зарплаты</h2>
              <div style={{ fontSize: 13, color: 'var(--text-dim)', marginTop: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{payout ? payout.teacher : 'Преподаватель'}</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, minHeight: 0, display: 'flex' }}>
          <div style={{ width: 400, flex: 'none', overflowY: 'auto', overflowX: 'hidden', padding: '20px 22px', display: 'flex', flexDirection: 'column', gap: 16, borderRight: '1px solid var(--border)' }}>
            <Field label="Период начислений">
              <div ref={rangeRef} style={{ position: 'relative' }}>
                {dateBtn(rangeLabel, () => setRangeCal(o => !o), rangeCal)}
                {rangeCal && <RangeCalendar value={range} maxISO={isoNow()} onApply={(r) => { setRange(r); setRangeCal(false); }} onClose={() => setRangeCal(false)} />}
              </div>
              <div style={{ fontSize: 11.5, color: 'var(--text-dim)', marginTop: 5 }}>Занятия к оплате подставятся автоматически — только не оплаченные ранее</div>
            </Field>

            {/* Сводка расчёта — read-only, моно (вместо редактируемых полей) */}
            <div style={{ border: '1px solid var(--border)', background: 'var(--bg-soft)', borderRadius: 'var(--radius-md)', padding: '13px 15px' }}>
              <div style={{ fontSize: 11, fontWeight: 700, letterSpacing: '0.05em', textTransform: 'uppercase', color: 'var(--text-dim)', marginBottom: 8 }}>Расчёт по занятиям</div>
              {!ready ? (
                <div style={{ fontFamily: 'var(--font-mono)', fontSize: 13, color: 'var(--text-dim)' }}>{pv.status === 'loading' ? 'считаем…' : 'выберите период'}</div>
              ) : (
                <React.Fragment>
                  <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, flexWrap: 'wrap', fontFamily: 'var(--font-mono)', fontSize: 13, color: 'var(--text-secondary)' }}>
                    <span>Занятий: <b style={{ color: 'var(--text)' }}>{toPay.length}</b></span>
                    <span style={{ color: 'var(--border-strong)' }}>·</span>
                    <span>Ставка: <b style={{ color: 'var(--text)' }}>{singleRate != null ? payRub(singleRate) : 'по дате занятия'}</b></span>
                  </div>
                  <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', gap: 10, marginTop: 8, paddingTop: 8, borderTop: '1px solid var(--border)' }}>
                    <span style={{ fontSize: 12.5, color: 'var(--text-dim)' }}>Расчёт</span>
                    <span style={{ fontFamily: 'var(--font-mono)', fontSize: 16, fontWeight: 700, color: calc > 0 ? 'var(--green)' : 'var(--text-dim)' }}>{payRub(calc)}</span>
                  </div>
                </React.Fragment>
              )}
            </div>

            {/* Корректировка (премия / удержание) */}
            <Field label="Корректировка">
              {segment([
                { id: 'none', label: 'Без' },
                { id: 'bonus', label: 'Премия', color: 'var(--green-ink)' },
                { id: 'deduct', label: 'Удержание', color: 'var(--coral)' },
              ], adjMode, (id) => { setAdjMode(id); if (id === 'none') { setAdjAmount(''); setAdjNote(''); } })}
              {adjMode !== 'none' && (
                <div className="om-fade-in" style={{ marginTop: 12, display: 'flex', flexDirection: 'column', gap: 12 }}>
                  <div>
                    <label style={{ display: 'block', fontSize: 12, fontWeight: 600, color: 'var(--text-secondary)', marginBottom: 5 }}>Сумма {adjMode === 'bonus' ? 'премии' : 'удержания'} (₽)</label>
                    <div style={{ position: 'relative' }}>
                      <span style={{ position: 'absolute', left: 13, top: '50%', transform: 'translateY(-50%)', fontFamily: 'var(--font-mono)', fontSize: 15, fontWeight: 700, color: adjMode === 'bonus' ? 'var(--green)' : 'var(--coral)', pointerEvents: 'none' }}>{adjMode === 'bonus' ? '+' : '−'}</span>
                      <input value={adjAmount} onChange={e => setAdjAmount(e.target.value.replace(/\D/g, ''))} placeholder="0" inputMode="numeric"
                        style={{ width: '100%', boxSizing: 'border-box', borderRadius: 'var(--radius-sm)', padding: '11px 13px 11px 28px', outline: 'none', background: 'var(--bg-card)', fontFamily: 'var(--font-mono)', fontSize: 14, color: 'var(--text)',
                          border: '1px solid ' + (deductTooBig ? 'var(--coral)' : 'var(--border)'), boxShadow: deductTooBig ? '0 0 0 3px var(--coral-bg)' : 'none', transition: 'border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease)' }} />
                    </div>
                    {deductTooBig && <div style={{ fontSize: 11.5, color: 'var(--coral)', marginTop: 5, fontWeight: 600 }}>Удержание больше расчёта — итог не может быть отрицательным</div>}
                  </div>
                  <div>
                    <label style={{ display: 'block', fontSize: 12, fontWeight: 600, color: 'var(--text-secondary)', marginBottom: 5 }}>Причина {adjNum > 0 && <span style={{ color: 'var(--coral)' }}>*</span>}</label>
                    <input value={adjNote} onChange={e => setAdjNote(e.target.value)} placeholder={adjMode === 'bonus' ? 'Например, премия за пробные занятия' : 'Например, аванс, выданный ранее'}
                      style={{ width: '100%', boxSizing: 'border-box', borderRadius: 'var(--radius-sm)', padding: '11px 13px', outline: 'none', background: 'var(--bg-card)', fontFamily: 'var(--font-sans)', fontSize: 14, color: 'var(--text)',
                        border: '1px solid ' + (reasonMissing ? 'var(--coral)' : 'var(--border)'), boxShadow: reasonMissing ? '0 0 0 3px var(--coral-bg)' : 'none', transition: 'border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease)' }} />
                  </div>
                </div>
              )}
            </Field>

            {pureBonus && (
              <div className="om-fade-in" style={{ border: '1px solid #E7CFA3', background: 'var(--gold-soft)', borderRadius: 'var(--radius-sm)', padding: '11px 13px', 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 }}>Выплата состоит только из премии — занятий к оплате нет.</span>
              </div>
            )}

            <Field label="Когда выплатить">
              {segment([{ id: 'now', label: 'Сейчас' }, { id: 'schedule', label: 'Запланировать' }], when, setWhen)}
            </Field>

            {when === 'schedule' && (
              <div className="om-fade-in">
                <Field label="Дата выплаты">
                  <div ref={dateRef} style={{ position: 'relative' }}>
                    {dateBtn(fmtIso(payDate), () => setDateCal(o => !o), dateCal)}
                    {dateCal && <RangeCalendar single value={{ start: payDate, end: payDate }} onApply={(r) => setPayDate(r.start)} onClose={() => setDateCal(false)} />}
                  </div>
                </Field>
              </div>
            )}

            <Field label="Способ оплаты">
              <PickerTrigger label={method} placeholder="Не указан" onClick={() => setPicker({ title: 'Способ оплаты', value: method, options: PAYMENT_METHODS.map(m => ({ value: m, label: m })), onPick: setMethod })} />
            </Field>

            <Field label="Комментарий">
              <textarea value={comment} onChange={e => setComment(e.target.value)} placeholder="Необязательно…" rows={2} 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>
          </div>

          <PayoutLessonsPanel pv={pv} />
          </div>

          <div style={{ padding: '14px 22px', borderTop: '1px solid var(--border)', display: 'flex', alignItems: 'center', gap: 12 }}>
            <div style={{ flex: 1, minWidth: 0 }}>
              {signed !== 0 ? (
                <div style={{ fontFamily: 'var(--font-mono)', fontSize: 13, color: 'var(--text-secondary)', display: 'flex', alignItems: 'baseline', gap: 6, flexWrap: 'wrap' }}>
                  <span>Расчёт {new Intl.NumberFormat('ru-RU').format(calc)}</span>
                  <span style={{ color: signed > 0 ? 'var(--green)' : 'var(--coral)', fontWeight: 700 }}>{signed > 0 ? '+' : '−'} {adjMode === 'bonus' ? 'Премия' : 'Удержание'} {new Intl.NumberFormat('ru-RU').format(adjNum)}</span>
                  <span>=</span>
                  <span style={{ fontSize: 16, fontWeight: 700, color: total >= 0 ? 'var(--green)' : 'var(--coral)' }}>{new Intl.NumberFormat('ru-RU').format(total)} ₽</span>
                </div>
              ) : (
                <div style={{ fontFamily: 'var(--font-mono)', fontSize: 16, fontWeight: 700, color: total > 0 ? 'var(--green)' : 'var(--text-dim)' }}>{new Intl.NumberFormat('ru-RU').format(total)} ₽</div>
              )}
            </div>
            <Button variant="ghost" onClick={close}>Отмена</Button>
            <span title={canSave ? '' : disabledReason}>
              <Button variant="primary" icon={when === 'now' ? 'check' : 'calendar'} onClick={tryFinish} style={canSave ? {} : { opacity: 0.5, cursor: 'not-allowed', boxShadow: 'none' }}>{when === 'now' ? 'Выплатить' : 'Запланировать'}</Button>
            </span>
          </div>
          {pastWarn && (() => {
            const MN = ['январе', 'феврале', 'марте', 'апреле', 'мае', 'июне', 'июле', 'августе', 'сентябре', 'октябре', 'ноябре', 'декабре'];
            return (
              <ModalLayer z={95}>
                <div onClick={() => setPastWarn(false)} 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: 'hidden' }}>
                  <div style={{ padding: '18px 22px 14px', display: 'flex', alignItems: 'flex-start', gap: 12 }}>
                    <span style={{ width: 40, height: 40, borderRadius: 'var(--radius-md)', background: 'var(--gold-soft)', color: 'var(--gold-ink)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flex: 'none' }}><Icon name="alert-triangle" size={20} /></span>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <h3 style={{ fontSize: 17, fontWeight: 700, margin: 0, color: 'var(--text)' }}>Выплата за прошлый период</h3>
                      <div style={{ fontSize: 13, color: 'var(--text-secondary)', marginTop: 4, lineHeight: 1.45 }}>Период начисления — <b style={{ color: 'var(--text)' }}>{MON_SH[periodM]} {periodY}</b>, а выплата проходит в <b style={{ color: 'var(--text)' }}>{MN[payM]} {payY}</b>. В каком месяце учесть этот расход?</div>
                    </div>
                  </div>
                  <div style={{ padding: '0 22px 18px', display: 'flex', flexDirection: 'column', gap: 10 }}>
                    <button onClick={() => finish('period')} style={{ display: 'flex', alignItems: 'center', gap: 11, width: '100%', textAlign: 'left', padding: '13px 14px', borderRadius: 'var(--radius-sm)', border: '1px solid var(--brand)', background: 'var(--brand-soft)', cursor: 'pointer', fontFamily: 'var(--font-sans)' }}>
                      <Icon name="calendar" size={18} style={{ color: 'var(--brand-ink)', flex: 'none' }} />
                      <span><span style={{ display: 'block', fontSize: 14, fontWeight: 700, color: 'var(--brand-ink)' }}>В месяце начисления — {MN[periodM]}</span><span style={{ display: 'block', fontSize: 12, color: 'var(--text-secondary)' }}>расход попадёт в {MN[periodM]} {periodY} (рекомендуется)</span></span>
                    </button>
                    <button onClick={() => finish('payment')} style={{ display: 'flex', alignItems: 'center', gap: 11, width: '100%', textAlign: 'left', padding: '13px 14px', borderRadius: 'var(--radius-sm)', border: '1px solid var(--border)', background: 'var(--bg-card)', cursor: 'pointer', fontFamily: 'var(--font-sans)' }}
                      onMouseEnter={e => { e.currentTarget.style.background = 'var(--bg-soft)'; }} onMouseLeave={e => { e.currentTarget.style.background = 'var(--bg-card)'; }}>
                      <Icon name="wallet" size={18} style={{ color: 'var(--text-dim)', flex: 'none' }} />
                      <span><span style={{ display: 'block', fontSize: 14, fontWeight: 700, color: 'var(--text)' }}>В месяце выплаты — {MN[payM]}</span><span style={{ display: 'block', fontSize: 12, color: 'var(--text-secondary)' }}>расход попадёт в {MN[payM]} {payY} (по факту оплаты)</span></span>
                    </button>
                    <button onClick={() => setPastWarn(false)} style={{ alignSelf: 'center', marginTop: 2, border: 'none', background: 'none', cursor: 'pointer', color: 'var(--text-dim)', fontSize: 13, fontWeight: 600, fontFamily: 'var(--font-sans)' }}>Отмена</button>
                  </div>
                </div>
              </ModalLayer>
            );
          })()}
        </aside>
      </div>
    </div>
  );
}

Object.assign(window, { AddPayoutModal });
