/* global React, ReactDOM, Icon, Button, Dropdown, Overline, RangeCalendar */
// Schools.ArtemenkoCRM — Единая «Карточка занятия» (create / view / edit).
// Один компонент на 3 режима, общий для карточки КЛИЕНТА и карточки ПРЕПОДА.
//
// Денежная модель (утверждено, НЕ менять):
//  • Цена занятия для КЛИЕНТА (amount) ≠ выплата ПРЕПОДУ (ставка). Это независимые деньги.
//  • Разовая цена одного занятия (скидка/наценка) НЕ меняет обычную цену пары (teacherPrices).
//  • Надбавка преподу за занятие (teacherBonusRubles) входит в расчёт выплаты, но это НЕ премия
//    за период (та ставится при формировании выплаты). Видна только тем, кто видит деньги препода.
//  • Проведённое/пропущенное занятие — деньги уже списаны: цену/надбавку/время менять нельзя.

const LC_MONTHS = ['янв', 'фев', 'мар', 'апр', 'мая', 'июн', 'июл', 'авг', 'сен', 'окт', 'ноя', 'дек'];
const LC_WDAYS = ['понедельник', 'вторник', 'среда', 'четверг', 'пятница', 'суббота', 'воскресенье'];
const lcRub = (n) => new Intl.NumberFormat('ru-RU').format(Math.round(n || 0)) + ' ₽';
const lcDateLabel = (iso) => { const p = String(iso || '').split('-'); return p.length === 3 ? `${+p[2]} ${LC_MONTHS[+p[1] - 1]} ${p[0]}` : (iso || '—'); };
const lcWeekday = (iso) => { const p = String(iso || '').split('-'); if (p.length !== 3) return ''; return LC_WDAYS[(new Date(+p[0], +p[1] - 1, +p[2]).getDay() + 6) % 7]; };
// Нормализуем время: принимаем «9:00» и «09:00» → «09:00».
const lcNormTime = (t) => { const m = String(t || '').trim().match(/^(\d{1,2}):(\d{2})$/); if (!m) return String(t || '').trim(); return String(+m[1]).padStart(2, '0') + ':' + m[2]; };
const lcValidTime = (t) => /^([01]?\d|2[0-3]):[0-5]\d$/.test(String(t || '').trim());
// «Будущее» — по дате И ВРЕМЕНИ: занятие сегодня, но позже «сейчас» = будущее → только «Запланировано».
// Раньше сравнивали только дату → сегодня-вечернее считалось прошедшим. Невалидное/пустое время → конец дня.
const lcIsFutureDT = (iso, t) => { const nt = lcNormTime(t); return new Date((iso || '') + 'T' + (lcValidTime(nt) ? nt : '23:59') + ':00').getTime() > Date.now(); };

// Календарь-поповер: портал во fixed-обёртку у триггера, чтобы не обрезался прокруткой модалки.
function LcCalPop({ triggerRef, value, onApply, onClose }) {
  const [rect, setRect] = React.useState(null);
  React.useEffect(() => {
    if (triggerRef.current) setRect(triggerRef.current.getBoundingClientRect());
  }, []);
  if (!rect) return null;
  const top = Math.min(rect.bottom, window.innerHeight - 372);
  const left = Math.min(rect.left, window.innerWidth - 316);
  return ReactDOM.createPortal(
    <div style={{ position: 'fixed', top, left, width: 0, height: 0, zIndex: 10000 }}>
      <RangeCalendar single value={value} onApply={onApply} onClose={onClose} />
    </div>,
    document.body
  );
}

function LessonCard({ context, client, staff, students, teachers, lesson, showTeacherMoney = true, onSave, onClose }) {
  const todayISO = window.APP_TODAY_ISO || '2026-05-31';
  const LS = (window.CRM_DATA && window.CRM_DATA.LESSON_STATUS) || {};
  const STAFF = (window.CRM_DATA && window.CRM_DATA.STAFF) || [];
  const priceFor = window.priceFor || (() => window.DEFAULT_LESSON_PRICE || 1800);
  const hasPriceFor = window.hasPriceFor || (() => true);

  const isCreate = !lesson;
  // Занятие «редактируемо», если запланировано (в будущем). Проведённое/пропущенное/отменённое —
  // read-only по деньгам и времени (тему/ДЗ править можно всегда).
  const readOnly = !!lesson && lesson.status !== 'planned';

  // ---- Контрагент: в карточке клиента выбираем ПРЕПОДА, в карточке препода — УЧЕНИКА. ----
  const teacherList = context === 'client'
    ? ((teachers && teachers.length) ? teachers : (client && client.teacher ? [client.teacher] : []))
    : [staff.name];
  const studentList = context === 'staff' ? (students || []) : (client ? [client] : []);

  // ---- Начальные значения ----
  const initTeacher = context === 'client'
    ? (lesson ? lesson.teacher : (teacherList[0] || 'Не назначен'))
    : staff.name;
  const initStudent = context === 'staff'
    ? (lesson ? (studentList.find(s => s.id === lesson.clientId) || studentList.find(s => s.child === lesson.who) || studentList[0]) : studentList[0])
    : client;
  const initType = lesson
    ? (lesson.status === 'planned' ? 'future' : lesson.status === 'noshow' ? 'noshow' : lesson.status === 'cancelled' ? 'cancelled' : 'normal')
    : (lcIsFutureDT(todayISO, '17:00') ? 'future' : 'normal'); // новое занятие сегодня-вечером = «Запланировано»

  const [dateISO, setDateISO] = React.useState(lesson ? lesson.dateISO : todayISO);
  const [time, setTime] = React.useState(lesson ? (lesson.time || '17:00') : '17:00');
  const [teacher, setTeacher] = React.useState(initTeacher);
  const [studentId, setStudentId] = React.useState(initStudent ? initStudent.id : null);
  const [type, setType] = React.useState(initType);

  const resolvedClient = context === 'staff' ? (studentList.find(s => s.id === studentId) || initStudent) : client;
  const who = context === 'staff' ? (resolvedClient ? resolvedClient.child : (lesson ? lesson.who : '')) : (client ? client.child : '');
  const normalPrice = resolvedClient ? priceFor(resolvedClient, teacher) : (window.DEFAULT_LESSON_PRICE || 1800);
  const pairHasPrice = resolvedClient ? hasPriceFor(resolvedClient, teacher) : false;

  const initAmount = lesson ? (lesson.amount != null ? lesson.amount : normalPrice) : normalPrice;
  const [priceMode, setPriceMode] = React.useState(initAmount === normalPrice ? 'normal' : initAmount < normalPrice ? 'discount' : 'markup');
  const [priceDelta, setPriceDelta] = React.useState(initAmount === normalPrice ? '' : String(Math.abs(initAmount - normalPrice)));

  const [bonusVal, setBonusVal] = React.useState(lesson && lesson.teacherBonusRubles ? String(lesson.teacherBonusRubles) : '');
  const [bonusNote, setBonusNote] = React.useState((lesson && lesson.bonusNote) || '');
  // Штраф за неявку (noshow): по умолчанию = стоимость занятия; можно изменить (0 = без штрафа).
  const [penaltyTouched, setPenaltyTouched] = React.useState(false);
  const [penaltyVal, setPenaltyVal] = React.useState(lesson && lesson.status === 'noshow' && lesson.penalty != null ? String(lesson.penalty) : '');

  const [topic, setTopic] = React.useState((lesson && lesson.topic) || '');
  const [homework, setHomework] = React.useState((lesson && lesson.homework) || '');

  const [shown, setShown] = React.useState(false);
  const [cal, setCal] = React.useState(false);
  const dateRef = React.useRef(null);
  React.useEffect(() => { const t = setTimeout(() => setShown(true), 10); return () => clearTimeout(t); }, []);
  React.useEffect(() => {
    if (!cal) return;
    const h = (e) => { if (dateRef.current && !dateRef.current.contains(e.target) && !e.target.closest('.om-fade-in')) setCal(false); };
    const t = setTimeout(() => document.addEventListener('mousedown', h), 0);
    return () => { clearTimeout(t); document.removeEventListener('mousedown', h); };
  }, [cal]);
  const close = () => { setShown(false); setTimeout(onClose, 190); };

  const future = lcIsFutureDT(dateISO, time);
  const clampType = (f) => setType(t => (f && (t === 'normal' || t === 'noshow')) ? 'future' : (!f && t === 'future') ? 'normal' : t);
  // Смена даты/времени клампит статус: будущее → только Запланировано/Отменено; прошлое → без «Запланировано».
  const setDate = (iso) => { setDateISO(iso); clampType(lcIsFutureDT(iso, time)); };

  const delta = parseInt((priceDelta || '0').replace(/\D/g, ''), 10) || 0;
  const amount = priceMode === 'normal' ? normalPrice : priceMode === 'discount' ? Math.max(0, normalPrice - delta) : normalPrice + delta;
  const discountTooBig = priceMode === 'discount' && delta > normalPrice;
  const bonusNum = showTeacherMoney ? (parseInt((bonusVal || '0').replace(/\D/g, ''), 10) || 0) : 0;
  // Штраф за неявку: по умолчанию = стоимость занятия (не дефолт из настроек); ввод пользователя переопределяет.
  const penaltyNum = type === 'noshow' ? (penaltyTouched ? (parseInt((penaltyVal || '0').replace(/\D/g, ''), 10) || 0) : amount) : 0;

  // ——— Деньги ПРЕПОДА за это занятие ———
  // Ставка берётся НА ДАТУ занятия (история ставок): у существующего — с сервера (teacherRateRubles),
  // у нового/при смене даты — считаем локально тем же rateOn по выбранному преподу. Итог = ставка + надбавка.
  // lesson.payout != null → занятие уже в активной выплате: снимок заморожен, надбавку менять нельзя.
  const teacherStaff = (window.CRM_DATA.STAFF || []).find(s => s.role === 'teacher' && s.name === teacher);
  const localRate = teacherStaff ? (window.rateOn ? window.rateOn(teacherStaff, dateISO) : (teacherStaff.rate || 0)) : null;
  // Занятия из карточки ПРЕПОДА приходят без поля teacher (препод там фиксирован) — иначе проверка
  // «это тот же слот, что сохранён» не срабатывала и ставка бралась локальным фолбэком.
  const lessonTeacher = lesson ? (lesson.teacher || (context === 'staff' ? staff.name : null)) : null;
  const sameSlotAsSaved = lesson && lesson.dateISO === dateISO && lessonTeacher === teacher;
  const rateRub = (sameSlotAsSaved && lesson.teacherRateRubles != null) ? lesson.teacherRateRubles : localRate;
  const payoutInfo = lesson ? (lesson.payout || null) : null;
  const bonusLocked = !!payoutInfo; // в активной выплате — бэк запретит правку надбавки

  const noCounterparty = context === 'staff' ? studentList.length === 0 : teacherList.length === 0;
  const canSave = readOnly ? true : (!noCounterparty && !discountTooBig && lcValidTime(time));
  const saveHint = noCounterparty
    ? (context === 'staff' ? 'У преподавателя нет учеников — сначала закрепите ученика' : 'Назначьте преподавателя ученику')
    : discountTooBig ? 'Скидка больше обычной цены'
    : !lcValidTime(time) ? 'Время в формате ЧЧ:ММ' : '';

  const save = () => {
    if (!canSave) return;
    onSave({
      id: lesson ? lesson.id : undefined,
      clientId: resolvedClient ? resolvedClient.id : (lesson ? lesson.clientId : null),
      who, teacher,
      dateISO, time: lcNormTime(time),
      type,
      amount,
      penalty: penaltyNum, // штраф за неявку (₽); 0 = без штрафа
      teacherBonusRubles: showTeacherMoney ? bonusNum : (lesson ? (lesson.teacherBonusRubles || 0) : 0),
      bonusNote: showTeacherMoney ? (bonusNum > 0 ? bonusNote.trim() : '') : (lesson ? (lesson.bonusNote || '') : ''),
      topic: topic.trim(), homework: homework.trim(),
    });
    close();
  };

  // ---- Общие стили ----
  const lbl = { display: 'block', fontSize: 12, fontWeight: 600, color: 'var(--text-secondary)', marginBottom: 6 };
  const inp = (extra) => ({ width: '100%', boxSizing: 'border-box', border: '1px solid var(--border-strong)', borderRadius: 'var(--radius-sm)', padding: '10px 12px', fontSize: 14, color: 'var(--text)', outline: 'none', background: 'var(--bg-card)', fontFamily: 'var(--font-sans)', ...(extra || {}) });
  const roBox = { border: '1px solid var(--border)', background: 'var(--bg-soft)', borderRadius: 'var(--radius-sm)', padding: '10px 12px', fontSize: 14, color: 'var(--text-secondary)' };

  // Сегмент-переключатель.
  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 => {
        const on = val === o.id;
        return (
          <button key={o.id} type="button" disabled={o.disabled} title={o.disabled ? o.hint : ''} onClick={() => !o.disabled && onPick(o.id)}
            onMouseEnter={e => { if (!on && !o.disabled) e.currentTarget.style.background = 'var(--bg-card)'; }}
            onMouseLeave={e => { if (!on) e.currentTarget.style.background = 'transparent'; }}
            style={{ flex: 1, padding: '7px 6px', border: 'none', borderRadius: 5, cursor: o.disabled ? 'not-allowed' : 'pointer', fontFamily: 'var(--font-sans)', fontSize: 12.5, fontWeight: 600, opacity: o.disabled ? 0.4 : 1, background: on ? 'var(--bg-card)' : 'transparent', color: on ? (o.color || 'var(--brand-ink)') : 'var(--text-dim)', boxShadow: on ? 'var(--shadow-xs)' : 'none', transition: 'background var(--dur-fast) var(--ease)', whiteSpace: 'nowrap' }}>{o.label}</button>
        );
      })}
    </div>
  );

  // Статус-сегмент: будущее по дате → только Запланировано/Отменено.
  const statusOpts = [
    { id: 'normal', label: 'Проведено', disabled: future, hint: 'Для будущего времени — только «Запланировано»' },
    { id: 'noshow', label: 'Не пришёл', disabled: future, hint: 'Для будущего времени — только «Запланировано»' },
    { id: 'cancelled', label: 'Отменено', disabled: false },
    { id: 'future', label: 'Запланировано', disabled: !future, hint: 'Прошедшее занятие станет «Проведено» или «В долг»' },
  ];

  // Read-only статус занятия (проведённое) — чип из карты статусов.
  const roStatus = lesson ? (LS[lesson.status] || {}) : {};

  const subjectFor = (tName) => {
    const st = STAFF.find(s => s.name === tName && s.role === 'teacher');
    const subs = (st && st.subjects) || [];
    const dirs = (resolvedClient && resolvedClient.directions && resolvedClient.directions.length) ? resolvedClient.directions : (resolvedClient && resolvedClient.direction ? [resolvedClient.direction] : []);
    return subs.find(x => dirs.includes(x)) || subs[0] || null;
  };

  const cpValue = context === 'client' ? teacher : studentId;
  const cpOptions = context === 'client'
    ? teacherList.map(t => { const subj = subjectFor(t); return { value: t, label: (subj ? subj + ' · ' : '') + t }; })
    : studentList.map(s => ({ value: s.id, label: s.child }));
  const cpOnChange = context === 'client' ? (v) => setTeacher(v) : (v) => setStudentId(v);

  const headerCtx = context === 'client'
    ? (client ? client.child : 'Ученик')
    : staff.name;
  const headerSub = lesson ? `${headerCtx} · ${lcDateLabel(dateISO)}, ${lcWeekday(dateISO)}` : headerCtx;

  return (
    <div style={{ position: 'fixed', inset: 0, zIndex: 90, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 24 }}>
      <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 className="om-sheet-up" style={{ position: 'relative', width: 440, maxWidth: '100%', maxHeight: '92vh', background: 'var(--bg-card)', borderRadius: 'var(--radius-lg)', boxShadow: 'var(--shadow-lg)', display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
        {/* Шапка */}
        <div style={{ padding: '16px 20px', borderBottom: '1px solid var(--border)', display: 'flex', alignItems: 'center', gap: 12, flex: 'none' }}>
          <span style={{ width: 38, height: 38, borderRadius: 'var(--radius-md)', background: 'var(--brand-soft)', color: 'var(--brand-ink)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flex: 'none' }}><Icon name="calendar" size={19} /></span>
          <div style={{ flex: 1, minWidth: 0 }}>
            <h3 style={{ fontSize: 17, fontWeight: 700, margin: 0, color: 'var(--text)' }}>{isCreate ? 'Новое занятие' : 'Занятие'}</h3>
            <div style={{ fontSize: 12.5, color: 'var(--text-dim)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{headerSub}</div>
          </div>
          <button onClick={close} title="Закрыть" style={{ width: 32, height: 32, 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="17" height="17" 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, overflowY: 'auto', overflowX: 'hidden', padding: '18px 20px', display: 'flex', flexDirection: 'column', gap: 16 }}>
          {readOnly && (
            <div style={{ display: 'flex', gap: 9, alignItems: 'flex-start', border: '1px solid var(--border)', background: 'var(--bg-soft)', borderRadius: 'var(--radius-sm)', padding: '10px 12px' }}>
              <Icon name="lock" size={15} style={{ color: 'var(--text-dim)', flex: 'none', marginTop: 1 }} />
              <span style={{ fontSize: 12.5, color: 'var(--text-secondary)', lineHeight: 1.45 }}>Занятие проведено — деньги уже учтены, цену изменить нельзя. Можно уточнить тему и домашнее задание.</span>
            </div>
          )}

          {/* Дата + Время */}
          <div style={{ display: 'flex', gap: 12 }}>
            <div style={{ flex: 1, minWidth: 0 }}>
              <label style={lbl}>Дата</label>
              {readOnly ? (
                <div style={{ ...roBox, fontFamily: 'var(--font-mono)' }}>{lcDateLabel(dateISO)}</div>
              ) : (
                <div ref={dateRef} style={{ position: 'relative' }}>
                  <button type="button" onClick={() => setCal(o => !o)}
                    onMouseEnter={e => { if (!cal) e.currentTarget.style.borderColor = 'var(--border-strong)'; }} onMouseLeave={e => { if (!cal) e.currentTarget.style.borderColor = 'var(--border)'; }}
                    style={{ display: 'inline-flex', alignItems: 'center', gap: 8, width: '100%', justifyContent: 'flex-start', padding: '10px 12px', cursor: 'pointer', background: 'var(--bg-card)', border: '1px solid ' + (cal ? 'var(--brand)' : 'var(--border-strong)'), borderRadius: 'var(--radius-sm)', boxShadow: cal ? 'var(--shadow-focus)' : 'none', fontFamily: 'var(--font-mono)', fontSize: 14, color: 'var(--text)' }}>
                    <Icon name="calendar" size={15} style={{ color: 'var(--text-dim)', flex: 'none' }} />{lcDateLabel(dateISO)}
                  </button>
                  {cal && <LcCalPop triggerRef={dateRef} value={{ start: dateISO, end: dateISO }} onApply={(r) => { setDate(r.start); setCal(false); }} onClose={() => setCal(false)} />}
                </div>
              )}
            </div>
            <div style={{ width: 112, flex: 'none' }}>
              <label style={lbl}>Время</label>
              {readOnly ? (
                <div style={{ ...roBox, fontFamily: 'var(--font-mono)' }}>{lcNormTime(time) || '—'}</div>
              ) : (
                <input value={time} onChange={e => setTime(e.target.value)} onBlur={() => { const nt = lcNormTime(time); setTime(nt); clampType(lcIsFutureDT(dateISO, nt)); }} placeholder="17:00" inputMode="numeric"
                  style={inp({ fontFamily: 'var(--font-mono)', borderColor: (time && !lcValidTime(time)) ? 'var(--coral)' : 'var(--border-strong)' })} />
              )}
            </div>
          </div>

          {/* Предмет и преподаватель / Ученик */}
          <div>
            <label style={lbl}>{context === 'client' ? 'Предмет и преподаватель' : 'Ученик'}</label>
            {readOnly || noCounterparty ? (
              <div style={roBox}>{context === 'client' ? ((subjectFor(teacher) ? subjectFor(teacher) + ' · ' : '') + (teacher || '—')) : (who || 'нет учеников')}</div>
            ) : (
              <Dropdown value={cpValue} options={cpOptions} onChange={cpOnChange} width="100%" searchable={cpOptions.length > 6} placeholder={context === 'client' ? 'Преподаватель' : 'Ученик'} />
            )}
          </div>

          {/* Статус */}
          <div>
            <label style={lbl}>Статус</label>
            {readOnly ? (
              <div style={{ display: 'inline-flex', alignItems: 'center', gap: 8, padding: '9px 13px', borderRadius: 'var(--radius-sm)', border: '1px solid var(--border)', background: 'var(--bg-soft)', fontSize: 13.5, fontWeight: 600, color: roStatus.fg || 'var(--text)' }}>
                <span style={{ width: 8, height: 8, borderRadius: '50%', background: roStatus.dot || roStatus.bd || 'var(--text-dim)' }} />{roStatus.label || '—'}
              </div>
            ) : (
              <React.Fragment>
                {segment(statusOpts, type, setType)}
                {type === 'normal' && (
                  <div style={{ fontSize: 11.5, color: 'var(--text-dim)', marginTop: 6 }}>Спишется с баланса — станет «Оплачено» или «В долг».</div>
                )}
                {type === 'noshow' && (
                  <div className="om-fade-in" style={{ marginTop: 10 }}>
                    <label style={{ ...lbl, marginBottom: 5 }}>Штраф за неявку (₽)</label>
                    <input value={penaltyTouched ? penaltyVal : String(amount)} onChange={e => { setPenaltyTouched(true); setPenaltyVal(e.target.value.replace(/\D/g, '')); }} placeholder="0 — без штрафа" inputMode="numeric" style={inp({ fontFamily: 'var(--font-mono)' })} />
                    <div style={{ fontSize: 11, color: 'var(--text-dim)', marginTop: 5 }}>По умолчанию равен стоимости занятия ({lcRub(amount)}). Поставьте 0 — без штрафа.</div>
                  </div>
                )}
              </React.Fragment>
            )}
          </div>

          {/* ——— Стоимость занятия (деньги КЛИЕНТА) ——— */}
          <div style={{ borderTop: '1px solid var(--border)', paddingTop: 15 }}>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10, marginBottom: 10 }}>
              <Overline style={{ fontSize: 12 }}>Стоимость занятия</Overline>
              <span style={{ fontSize: 12, color: 'var(--text-dim)' }}>обычная: <b style={{ fontFamily: 'var(--font-mono)', fontWeight: 600, color: 'var(--text-secondary)' }}>{lcRub(normalPrice)}</b></span>
            </div>
            {!pairHasPrice && !readOnly && (
              <div style={{ fontSize: 11.5, color: 'var(--coral)', marginBottom: 8 }}>Обычная цена пары не задана — используется значение по умолчанию. Задайте её в карточке клиента.</div>
            )}
            {readOnly ? (
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10, ...roBox }}>
                <span style={{ fontSize: 13, color: 'var(--text-dim)' }}>Разовая цена</span>
                <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
                  {amount !== normalPrice && <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, fontWeight: 700, padding: '2px 7px', borderRadius: 4, background: amount < normalPrice ? 'var(--green-bg)' : 'var(--gold-soft)', color: amount < normalPrice ? 'var(--green-ink)' : 'var(--gold-ink)' }}>{amount < normalPrice ? '−' : '+'}{lcRub(Math.abs(amount - normalPrice))}</span>}
                  <b style={{ fontFamily: 'var(--font-mono)', fontSize: 15, fontWeight: 700, color: 'var(--text)' }}>{lcRub(amount)}</b>
                </span>
              </div>
            ) : (
              <React.Fragment>
                {segment([
                  { id: 'normal', label: 'Обычная' },
                  { id: 'discount', label: 'Скидка', color: 'var(--green-ink)' },
                  { id: 'markup', label: 'Наценка', color: 'var(--gold-ink)' },
                ], priceMode, (id) => { setPriceMode(id); if (id === 'normal') setPriceDelta(''); })}
                {priceMode !== 'normal' && (
                  <div className="om-fade-in" style={{ marginTop: 10 }}>
                    <label style={{ ...lbl, marginBottom: 5 }}>Размер {priceMode === 'discount' ? 'скидки' : 'наценки'} (₽)</label>
                    <div style={{ position: 'relative', width: '100%' }}>
                      <span style={{ position: 'absolute', left: 12, top: '50%', transform: 'translateY(-50%)', fontFamily: 'var(--font-mono)', fontSize: 15, fontWeight: 700, color: priceMode === 'discount' ? 'var(--green)' : 'var(--gold-ink)', pointerEvents: 'none' }}>{priceMode === 'discount' ? '−' : '+'}</span>
                      <input value={priceDelta} onChange={e => setPriceDelta(e.target.value.replace(/\D/g, ''))} placeholder="0" inputMode="numeric" autoFocus
                        style={inp({ fontFamily: 'var(--font-mono)', paddingLeft: 26, borderColor: discountTooBig ? 'var(--coral)' : 'var(--border-strong)', boxShadow: discountTooBig ? '0 0 0 3px var(--coral-bg)' : 'none' })} />
                    </div>
                    {discountTooBig
                      ? <div style={{ fontSize: 11.5, color: 'var(--coral)', marginTop: 6, fontWeight: 600 }}>Скидка больше обычной цены — цена не может быть отрицательной.</div>
                      : <div style={{ fontSize: 12, color: 'var(--text-secondary)', marginTop: 7 }}>Разовая цена: <b style={{ fontFamily: 'var(--font-mono)', color: 'var(--text)' }}>{lcRub(amount)}</b> <span style={{ color: 'var(--text-dim)' }}>({priceMode === 'discount' ? '−' : '+'}{lcRub(delta)} к обычной)</span></div>}
                  </div>
                )}
                <div style={{ fontSize: 11, color: 'var(--text-dim)', marginTop: priceMode === 'normal' ? 9 : 8, lineHeight: 1.45 }}>Цена разовая — только для этого занятия. Обычная цена пары не меняется.</div>
              </React.Fragment>
            )}
          </div>

          {/* ——— Надбавка преподавателю за это занятие (деньги ПРЕПОДА) — постоянное поле ——— */}
          {showTeacherMoney && (
            <div style={{ border: '1px solid var(--border)', borderRadius: 'var(--radius-md)', background: 'var(--bg-soft)', padding: '12px 14px' }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
                <Icon name="wallet" size={15} style={{ color: 'var(--gold-ink)', flex: 'none' }} />
                <Overline style={{ fontSize: 11.5, flex: 1 }}>Надбавка преподавателю за занятие</Overline>
                {!readOnly && !bonusLocked && <span style={{ fontSize: 11, color: 'var(--text-dim)' }}>необязательно</span>}
              </div>

              {/* Сколько получит преподаватель: ставка НА ДАТУ занятия + надбавка = итог */}
              <div style={{ display: 'flex', flexDirection: 'column', gap: 5, padding: '9px 11px', background: 'var(--bg-card)', border: '1px solid var(--border)', borderRadius: 'var(--radius-sm)', marginBottom: 10 }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', gap: 10, fontSize: 12.5 }}>
                  <span style={{ color: 'var(--text-dim)' }}>Ставка на {lcDateLabel(dateISO)}</span>
                  <span style={{ fontFamily: 'var(--font-mono)', color: 'var(--text)' }}>{rateRub == null ? '—' : lcRub(rateRub)}</span>
                </div>
                <div style={{ display: 'flex', justifyContent: 'space-between', gap: 10, fontSize: 12.5 }}>
                  <span style={{ color: 'var(--text-dim)' }}>Надбавка за занятие</span>
                  <span style={{ fontFamily: 'var(--font-mono)', color: bonusNum ? 'var(--gold-ink)' : 'var(--text-dim)' }}>{bonusNum ? '+' + lcRub(bonusNum) : '—'}</span>
                </div>
                <div style={{ height: 1, background: 'var(--border)', margin: '2px 0' }} />
                <div style={{ display: 'flex', justifyContent: 'space-between', gap: 10, fontSize: 13 }}>
                  <b style={{ color: 'var(--text)' }}>Преподавателю за занятие</b>
                  <b style={{ fontFamily: 'var(--font-mono)', color: 'var(--gold-ink)' }}>{rateRub == null ? '—' : lcRub(rateRub + bonusNum)}</b>
                </div>
              </div>

              {payoutInfo && (
                <div style={{ display: 'flex', alignItems: 'flex-start', gap: 7, padding: '8px 10px', background: 'var(--green-bg, var(--bg-soft))', border: '1px solid var(--border)', borderRadius: 'var(--radius-sm)', marginBottom: 10 }}>
                  <Icon name="check-circle" size={14} style={{ color: 'var(--green)', flex: 'none', marginTop: 1 }} />
                  <div style={{ fontSize: 11.5, color: 'var(--text-secondary)', lineHeight: 1.45 }}>
                    Учтено в выплате за {lcDateLabel(payoutInfo.periodStart)} – {lcDateLabel(payoutInfo.periodEnd)}
                    {payoutInfo.status === 'paid' ? (payoutInfo.payDate ? ' · выплачено ' + lcDateLabel(payoutInfo.payDate) : ' · выплачено') : ' · выплата запланирована'}
                    {' · '}<b style={{ fontFamily: 'var(--font-mono)' }}>{lcRub(payoutInfo.amountRubles)}</b>. Надбавку менять нельзя — сначала сторнируйте выплату.
                  </div>
                </div>
              )}

              <div style={{ fontSize: 11, color: 'var(--text-dim)', marginBottom: 10, lineHeight: 1.45 }}>Доплата преподавателю именно за это занятие (сверх его ставки). Не влияет на цену для клиента. Отдельно от премии за период.</div>
              {(readOnly || bonusLocked) ? (
                <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10 }}>
                  <span style={{ fontSize: 13, color: 'var(--text-dim)' }}>{bonusNum ? (lesson.bonusNote || 'Надбавка за занятие') : 'Без надбавки'}</span>
                  <b style={{ fontFamily: 'var(--font-mono)', fontSize: 14, fontWeight: 700, color: bonusNum ? 'var(--gold-ink)' : 'var(--text-dim)' }}>{bonusNum ? '+' + lcRub(bonusNum) : '—'}</b>
                </div>
              ) : (
                <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
                  <div style={{ position: 'relative', width: '100%' }}>
                    <span style={{ position: 'absolute', left: 12, top: '50%', transform: 'translateY(-50%)', fontFamily: 'var(--font-mono)', fontSize: 15, fontWeight: 700, color: 'var(--gold-ink)', pointerEvents: 'none' }}>+</span>
                    <input value={bonusVal} onChange={e => setBonusVal(e.target.value.replace(/\D/g, ''))} placeholder="0 — без надбавки" inputMode="numeric" style={inp({ fontFamily: 'var(--font-mono)', paddingLeft: 26 })} />
                  </div>
                  <input value={bonusNote} onChange={e => setBonusNote(e.target.value)} placeholder="Причина (необязательно)" style={inp({ fontSize: 13.5 })} />
                </div>
              )}
            </div>
          )}

          {/* Тема / Домашнее задание */}
          <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            <div>
              <label style={lbl}>Тема занятия</label>
              <input value={topic} onChange={e => setTopic(e.target.value)} placeholder="Необязательно" style={inp()} />
            </div>
            <div>
              <label style={lbl}>Домашнее задание</label>
              <textarea value={homework} onChange={e => setHomework(e.target.value)} placeholder="Необязательно" rows={2} style={inp({ resize: 'vertical', fontSize: 13.5 })} />
            </div>
          </div>
        </div>

        {/* Футер */}
        <div style={{ padding: '13px 20px', borderTop: '1px solid var(--border)', display: 'flex', alignItems: 'center', gap: 12, flex: 'none' }}>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 11, color: 'var(--text-dim)', fontWeight: 600, letterSpacing: '0.03em', textTransform: 'uppercase' }}>Для клиента</div>
            <div style={{ fontFamily: 'var(--font-mono)', fontSize: 17, fontWeight: 700, color: 'var(--text)', lineHeight: 1.15 }}>{lcRub(amount)}</div>
            {showTeacherMoney && rateRub != null && <div style={{ fontSize: 11.5, color: 'var(--text-dim)', marginTop: 1, whiteSpace: 'nowrap' }}>преподу за занятие: <b style={{ fontFamily: 'var(--font-mono)', color: 'var(--gold-ink)', whiteSpace: 'nowrap' }}>{lcRub(rateRub + bonusNum)}</b>{bonusNum > 0 ? ' (' + lcRub(rateRub) + ' + ' + lcRub(bonusNum) + ')' : ''}</div>}
          </div>
          <Button variant="ghost" onClick={close}>{readOnly ? 'Закрыть' : 'Отмена'}</Button>
          <span title={canSave ? '' : saveHint}>
            <Button variant="primary" icon={isCreate ? 'plus' : 'check'} onClick={save} style={canSave ? {} : { opacity: 0.5, cursor: 'not-allowed', boxShadow: 'none' }}>{isCreate ? 'Добавить' : 'Сохранить'}</Button>
          </span>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { LessonCard });
