// screen-client.jsx — карточка клиента (статус, абонементы, долг, телефоны) +
// действия: «Продажа» (СБП-ссылка на оплату) и «Заявление ПЭП».
(() => {
  const { useState, useEffect, useMemo } = React;
  const { fmtMoney, fmtDate, initials, telHref } = window.M;

  function fio(c) {
    return [c.last_name, c.first_name, c.middle_name].filter(Boolean).join(' ').trim()
      || c.full_name || '';
  }
  function monthValue(offset) {
    // Локальный календарь, без toISOString(): в UTC+5 ночью 1-го числа
    // toISOString() откатывал дату на прошлый месяц → backend отклонял
    // begin_month «раньше текущего месяца».
    const d = new Date(); d.setDate(1); d.setMonth(d.getMonth() + offset);
    return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-01`;
  }
  function monthLabel(offset) {
    const d = new Date(); d.setDate(1); d.setMonth(d.getMonth() + offset);
    return d.toLocaleDateString('ru-RU', { month: 'long', year: 'numeric' });
  }

  // Каналы связи клиента — что есть для отправки ссылок (договор/заявление).
  // Источник данных тот же, что и backend sign.clientChannels: телефон → SMS,
  // email → Email, привязка мессенджера → MAX/Telegram.
  function clientPhones(c) {
    return Array.isArray(c.phones) ? c.phones.filter(Boolean) : (c.phone ? [c.phone] : []);
  }
  const CHANNELS = [
    { key: 'sms', label: 'SMS', has: (c) => clientPhones(c).length > 0 },
    { key: 'email', label: 'Email', has: (c) => !!(c.email && String(c.email).trim()) },
    { key: 'max', label: 'MAX', has: (c) => !!(c.messenger_links && c.messenger_links.max) },
    { key: 'telegram', label: 'Telegram', has: (c) => !!(c.messenger_links && c.messenger_links.tg) },
  ];

  // ── Абонемент (строка) ───────────────────────────────────
  function SubRow({ sub }) {
    const total = Number(sub.visits_total) || 0;
    const left = sub.visits_left != null ? sub.visits_left : Math.max(0, total - (sub.visits_used || 0));
    const debt = Math.max(0, Number(sub.total_price || 0) - Number(sub.amount_paid || 0));
    const group = (sub.assigned_groups || [])[0];
    return (
      <div className="list-line" style={{ alignItems: 'flex-start' }}>
        <div className="grow">
          <div style={{ fontWeight: 600 }}>{sub.type_name || 'Абонемент'}</div>
          <div className="subtle" style={{ marginTop: 2 }}>
            осталось {left}{total ? '/' + total : ''}
            {sub.end_date ? ' · до ' + fmtDate(sub.end_date) : ''}
            {group && group.discipline ? ' · ' + group.discipline : ''}
          </div>
          <div style={{ marginTop: 6, display: 'flex', gap: 6, flexWrap: 'wrap' }}>
            {sub.is_frozen && <span className="badge info">Заморожен</span>}
            {debt > 0
              ? <span className="badge danger">Долг {fmtMoney(debt)}</span>
              : <span className="badge ok">Оплачен</span>}
          </div>
        </div>
      </div>
    );
  }

  // ── Карточка клиента ─────────────────────────────────────
  window.ClientScreen = function ClientScreen({ clientId, onBack }) {
    const st = window.useAsync(() => window.api.clients.get(clientId), [clientId]);
    const { data: c, loading, error, reload } = st;
    const [sale, setSale] = useState(false);
    const [appl, setAppl] = useState(false);
    const [sign, setSign] = useState(false);

    if (loading) return <div className="screen"><Spinner /></div>;
    if (error) return (
      <div className="screen">
        <div className="empty"><span className="empty-emoji">⚠️</span>{error}
          <div style={{ marginTop: 14 }}>
            <button className="btn btn-ghost btn-sm" onClick={reload}>Повторить</button>
          </div>
        </div>
      </div>
    );

    const phones = Array.isArray(c.phones) ? c.phones.filter(Boolean) : (c.phone ? [c.phone] : []);
    const subs = c.active_subscriptions || [];
    const totalDebt = subs.reduce((a, s) => a + Math.max(0, Number(s.total_price || 0) - Number(s.amount_paid || 0)), 0);

    return (
      <div className="screen">
        {/* Шапка */}
        <div className="card">
          <div className="card-row">
            <div className="avatar" style={{ width: 54, height: 54, fontSize: 20 }}>{initials(fio(c))}</div>
            <div className="grow">
              <div style={{ fontWeight: 700, fontSize: 17 }} className="ellipsis">{fio(c)}</div>
              <div style={{ marginTop: 4, display: 'flex', gap: 6, flexWrap: 'wrap' }}>
                {c.status_name && <span className="badge">{c.status_name}</span>}
                {c.discount_percent > 0 && <span className="badge accent">Скидка {c.discount_percent}%</span>}
                {totalDebt > 0 && <span className="badge danger">Долг {fmtMoney(totalDebt)}</span>}
              </div>
            </div>
          </div>

          {phones.length > 0 && (
            <div style={{ marginTop: 12 }}>
              {phones.map((p, i) => (
                <div key={i} className="row-between" style={{ padding: '8px 0', borderTop: '1px solid var(--border)' }}>
                  <span className="mono">{p}</span>
                  <a className="btn btn-sm btn-ghost" href={telHref(p)} style={{ width: 'auto' }}>
                    <Icon name="phone" size={16} /> Позвонить
                  </a>
                </div>
              ))}
            </div>
          )}

          {/* Каналы связи — какие доступны для отправки ссылок на договор/заявление */}
          <div style={{ marginTop: 12, paddingTop: 12, borderTop: '1px solid var(--border)' }}>
            <div className="subtle" style={{ marginBottom: 8 }}>Каналы для договоров и заявлений</div>
            <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
              {CHANNELS.map((ch) => {
                const on = ch.has(c);
                return (
                  <span key={ch.key} className="badge" style={{
                    display: 'inline-flex', alignItems: 'center', gap: 4,
                    background: on ? 'var(--accent-soft)' : 'var(--bg-2)',
                    color: on ? 'var(--text)' : 'var(--text-3)',
                    border: `1px solid ${on ? 'var(--accent)' : 'var(--border-2)'}`,
                    opacity: on ? 1 : 0.7,
                  }}>
                    <Icon name={on ? 'check' : 'x'} size={12} /> {ch.label}
                  </span>
                );
              })}
            </div>
            {c.email && <div className="subtle mono" style={{ marginTop: 8 }}>{c.email}</div>}
          </div>
        </div>

        {/* Действия */}
        <button className="btn btn-primary" style={{ marginBottom: 10 }} onClick={() => setSale(true)}>
          <Icon name="card" size={18} /> Продажа
        </button>
        <div className="btn-row" style={{ marginBottom: 14 }}>
          <button className="btn" onClick={() => setSign(true)}>
            <Icon name="edit" size={17} /> Договор
          </button>
          <button className="btn" onClick={() => setAppl(true)}>
            <Icon name="file" size={17} /> Заявление
          </button>
        </div>

        {/* Абонементы */}
        <div className="section-title">Абонементы</div>
        <div className="card" style={{ padding: '2px 14px' }}>
          {subs.length === 0
            ? <div className="muted" style={{ padding: '14px 0' }}>Нет активных абонементов</div>
            : subs.map((s) => <SubRow key={s.id} sub={s} />)}
        </div>

        {/* Итоги */}
        <div className="card">
          <div className="row-between"><span className="muted">Оплачено</span>
            <span className="amount">{fmtMoney(c.total_paid || 0)}</span></div>
          <hr className="hr" />
          <div className="row-between"><span className="muted">Посещений всего</span>
            <span className="amount">{c.visits_count || 0}</span></div>
        </div>

        {sale && <SaleSheet client={c} onClose={() => setSale(false)} onDone={reload} />}
        {sign && <SignSendSheet client={c} onClose={() => setSign(false)} />}
        {appl && <ApplicationSheet client={c} onClose={() => setAppl(false)} />}
      </div>
    );
  };

  // ── Продажа: СБП-ссылка на оплату ────────────────────────
  function SaleSheet({ client, onClose, onDone }) {
    const [types, setTypes] = useState(null);
    const [typeId, setTypeId] = useState('');
    const [monthOff, setMonthOff] = useState(0);
    const [benId, setBenId] = useState(String(client.id));
    const [preview, setPreview] = useState(null);
    const [previewing, setPreviewing] = useState(false);
    const [creating, setCreating] = useState(false);
    const [link, setLink] = useState(null);
    const [err, setErr] = useState(null);
    const [sending, setSending] = useState('');   // ключ канала в процессе отправки
    const [sent, setSent] = useState({});          // { sms:true, email:true, ... }

    // Список бенефициаров: сам клиент + его дети.
    const beneficiaries = useMemo(() => {
      const list = [{ id: client.id, label: fio(client) + ' (сам)' }];
      (client.children || []).forEach((k) => {
        if (k && k.active !== false) list.push({ id: k.id, label: 'Ребёнок: ' + fio(k) });
      });
      return list;
    }, [client]);

    useEffect(() => {
      window.api.subTypes.list()
        .then((rows) => setTypes((rows || []).filter((t) => t.active !== false)))
        .catch((e) => { setTypes([]); setErr(e.message); });
    }, []);

    // Превью суммы при выборе типа/бенефициара.
    useEffect(() => {
      if (!typeId) { setPreview(null); return; }
      setPreviewing(true);
      window.api.yookassa.previewPaymentLink({ subscription_type_id: typeId, beneficiary_client_id: benId })
        .then(setPreview)
        .catch((e) => { setPreview(null); setErr(e.message); })
        .finally(() => setPreviewing(false));
    }, [typeId, benId]);

    async function create() {
      if (!typeId) { setErr('Выберите абонемент'); return; }
      setCreating(true); setErr(null);
      try {
        const body = {
          client_id: client.id,
          subscription_type_id: Number(typeId),
          begin_month: monthValue(monthOff),
        };
        if (String(benId) !== String(client.id)) body.beneficiary_client_id = Number(benId);
        const l = await window.api.yookassa.createPaymentLink(body);
        if (!l || !l.confirmation_url) throw new Error('Юкасса не вернула ссылку — попробуйте ещё раз');
        setLink(l);
        // НЕ дёргаем onDone здесь: reload карточки переводит экран в Spinner и
        // размонтирует этот Sheet до показа ссылки. Обновляем карточку при закрытии.
      } catch (e) {
        setErr(e.message || 'Не удалось создать ссылку');
      } finally { setCreating(false); }
    }

    // Закрытие: сначала обновляем карточку клиента, затем закрываем лист.
    function finish() { onDone && onDone(); onClose(); }

    // Каналы доставки ссылки — что реально доступно по карточке клиента.
    const linkChannels = useMemo(() => {
      if (!link) return [];
      const phone = clientPhones(client)[0];
      const out = [];
      if (phone) out.push({ key: 'sms', label: 'SMS', icon: 'message', sub: phone });
      if (client.email && String(client.email).trim())
        out.push({ key: 'email', label: 'Email', icon: 'mail', sub: String(client.email).trim() });
      if (client.messenger_links && client.messenger_links.max && client.messenger_links.max.chat_id)
        out.push({ key: 'max', label: 'MAX', icon: 'send', sub: 'привязка' });
      if (client.messenger_links && client.messenger_links.tg && client.messenger_links.tg.chat_id)
        out.push({ key: 'telegram', label: 'Telegram', icon: 'send', sub: 'привязка' });
      return out;
    }, [link, client]);

    async function deliver(key) {
      if (!link || sending) return;
      const text = `Оплата абонемента «${link.description || preview?.type?.name || ''}». Ссылка действует 15 минут: ${link.confirmation_url}`;
      setSending(key);
      try {
        if (key === 'sms') await window.api.sms.sendToClient(client.id, text);
        else if (key === 'email') await window.api.yookassa.sendLinkEmail(link.id);
        else if (key === 'max') await window.api.max.send(client.messenger_links.max.chat_id, text);
        else if (key === 'telegram') await window.api.telegram.send(client.messenger_links.tg.chat_id, text);
        setSent((s) => ({ ...s, [key]: true }));
        window.toast('Ссылка отправлена', 'ok');
      } catch (e) {
        window.toast(e.message || 'Не удалось отправить', 'err');
      } finally { setSending(''); }
    }

    async function share() {
      try {
        if (navigator.share) await navigator.share({ title: 'Оплата абонемента', url: link.confirmation_url });
        else { await navigator.clipboard.writeText(link.confirmation_url); window.toast('Ссылка скопирована', 'ok'); }
      } catch {}
    }

    async function copy() {
      try { await navigator.clipboard.writeText(link.confirmation_url); window.toast('Ссылка скопирована', 'ok'); }
      catch { window.toast('Не удалось скопировать', 'err'); }
    }

    // Экран после создания ссылки.
    if (link) {
      return (
        <Sheet title="Ссылка на оплату готова" onClose={finish}
          footer={<button className="btn btn-primary" onClick={finish}>Готово</button>}>
          <div className="card" style={{ background: 'var(--success-soft)', border: 'none' }}>
            <div className="row-between">
              <span className="muted">Сумма</span>
              <span className="amount" style={{ fontSize: 18 }}>{fmtMoney(link.amount || preview?.amount)}</span>
            </div>
            {link.description && <div className="subtle" style={{ marginTop: 4 }}>{link.description}</div>}
          </div>

          <div className="field">
            <label>Ссылка СБП / карта</label>
            <div className="input ellipsis" onClick={copy}
              style={{ display: 'flex', alignItems: 'center', cursor: 'pointer' }}>
              {link.confirmation_url}
            </div>
            <div className="subtle" style={{ marginTop: 6 }}>Действует 15 минут</div>
          </div>
          <div className="btn-row" style={{ marginBottom: 6 }}>
            <button className="btn" onClick={copy}><Icon name="link" size={16} /> Копировать</button>
            <button className="btn" onClick={share}><Icon name="send" size={16} /> Поделиться</button>
          </div>

          <div className="section-title" style={{ marginTop: 14 }}>Отправить клиенту</div>
          {linkChannels.length === 0
            ? <div className="subtle">Нет доступных каналов (нет телефона, email и привязок мессенджеров) — скопируйте ссылку и передайте вручную.</div>
            : <div className="stack">
                {linkChannels.map((ch) => (
                  <button key={ch.key} className={'btn' + (sent[ch.key] ? ' btn-primary' : '')}
                    disabled={!!sending} onClick={() => deliver(ch.key)}
                    style={{ justifyContent: 'flex-start', gap: 8 }}>
                    <Icon name={sent[ch.key] ? 'check' : ch.icon} size={18} />
                    <span>{sending === ch.key ? 'Отправка…' : (sent[ch.key] ? 'Отправлено: ' + ch.label : 'Отправить в ' + ch.label)}</span>
                    {ch.sub && <span className="subtle mono" style={{ marginLeft: 'auto', fontSize: 12, maxWidth: '45%', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{ch.sub}</span>}
                  </button>
                ))}
              </div>}

          <div className="subtle" style={{ marginTop: 12 }}>
            После оплаты абонемент и чек создадутся автоматически, появятся в карточке и в ЛК клиента.
          </div>
        </Sheet>
      );
    }

    return (
      <Sheet title="Продажа абонемента" onClose={onClose}
        footer={<>
          <button className="btn btn-ghost" onClick={onClose} disabled={creating}>Отмена</button>
          <button className="btn btn-primary" onClick={create} disabled={!typeId || creating}>
            {creating ? 'Создание…' : 'Создать ссылку'}
          </button>
        </>}>
        <div className="subtle" style={{ marginBottom: 12 }}>
          Клиент: <b style={{ color: 'var(--text)' }}>{fio(client)}</b>
        </div>

        {beneficiaries.length > 1 && (
          <div className="field">
            <label>Кому абонемент</label>
            <select className="input" value={benId} onChange={(e) => setBenId(e.target.value)}>
              {beneficiaries.map((b) => <option key={b.id} value={b.id}>{b.label}</option>)}
            </select>
          </div>
        )}

        <div className="field">
          <label>Абонемент</label>
          {types == null
            ? <div className="muted">Загрузка…</div>
            : <select className="input" value={typeId} onChange={(e) => setTypeId(e.target.value)}>
                <option value="">— выберите —</option>
                {types.map((t) => (
                  <option key={t.id} value={t.id}>{t.name} · {fmtMoney(t.price)}</option>
                ))}
              </select>}
        </div>

        <div className="field">
          <label>Месяц начала</label>
          <select className="input" value={monthOff} onChange={(e) => setMonthOff(Number(e.target.value))}>
            <option value={0}>{monthLabel(0)}</option>
            <option value={1}>{monthLabel(1)}</option>
          </select>
        </div>

        {typeId && (
          <div className="card" style={{ marginBottom: 0, background: 'var(--surface-2)' }}>
            <div className="row-between">
              <span className="muted">К оплате</span>
              <span className="amount" style={{ fontSize: 18 }}>
                {previewing ? '…' : fmtMoney(preview?.amount)}
              </span>
            </div>
            {preview && preview.discount_percent > 0 && (
              <div className="subtle" style={{ marginTop: 4 }}>
                с учётом скидки {preview.discount_percent}% (база {fmtMoney(preview.type?.price)})
              </div>
            )}
          </div>
        )}

        {err && <div className="badge danger" style={{ display: 'block', padding: '10px 12px', marginTop: 12 }}>{err}</div>}
      </Sheet>
    );
  }

  // ── Документ на подпись (акцепт/договор) ─────────────────
  // Переиспользует sign-сервис: список шаблонов → отправка ссылки+кода клиенту
  // (как desktop SignSendModal). Клиент подписывает ПЭП на sign.impulsekb.ru.
  function SignSendSheet({ client, onClose }) {
    const [templates, setTemplates] = useState(null);
    const [templateId, setTemplateId] = useState('');
    const [channels, setChannels] = useState(null);
    const [channel, setChannel] = useState('sms');
    const [sending, setSending] = useState(false);
    const [err, setErr] = useState(null);

    useEffect(() => {
      window.api.sign.templates.list({ active: 'true' })
        .then((r) => (r.items || []).filter((t) => t.current_version_no != null))
        .then(setTemplates)
        .catch((e) => { setTemplates([]); setErr(e.message); });
      window.api.sign.clientChannels(client.id)
        .then((r) => {
          const ch = r.channels || {};
          setChannels(ch);
          if (!ch.sms) { const f = ['email', 'max', 'telegram'].find((k) => ch[k]); if (f) setChannel(f); }
        })
        .catch(() => setChannels({}));
    }, [client.id]);

    const noChannels = channels && Object.keys(channels).filter((k) => channels[k]).length === 0;

    async function send() {
      if (!templateId) { setErr('Выберите документ'); return; }
      if (!channels || !channels[channel]) { setErr('Нет контакта для выбранного канала'); return; }
      setSending(true); setErr(null);
      try {
        const r = await window.api.sign.sendToClient({
          client_id: client.id, template_id: Number(templateId), channel, contacts: channels,
        });
        window.toast(`Документ отправлен через ${CH_LABEL[r.channel || channel]}`, 'ok');
        onClose();
      } catch (e) { setErr(e.message || 'Ошибка отправки'); } finally { setSending(false); }
    }

    return (
      <Sheet title="Документ на подпись (ПЭП)" onClose={onClose}
        footer={<>
          <button className="btn btn-ghost" onClick={onClose} disabled={sending}>Отмена</button>
          <button className="btn btn-primary" onClick={send} disabled={!templateId || sending || noChannels}>
            {sending ? 'Отправка…' : 'Отправить'}
          </button>
        </>}>
        <div className="badge info" style={{ display: 'block', padding: '12px 14px', marginBottom: 14, fontWeight: 400, borderRadius: 12, lineHeight: 1.45 }}>
          Клиент получит ссылку и одноразовый код, подпишет акцепт/договор простой электронной подписью.
          Заверённая копия придёт ему тем же каналом и сохранится в карточке.
        </div>
        <div className="field">
          <label>Документ</label>
          {templates == null
            ? <div className="muted">Загрузка…</div>
            : templates.length === 0
              ? <div className="subtle" style={{ color: 'var(--danger)' }}>Нет активных шаблонов. Создайте их в CRM → Настройки → Документы и подписи.</div>
              : <select className="input" value={templateId} onChange={(e) => setTemplateId(e.target.value)}>
                  <option value="">— выберите —</option>
                  {templates.map((t) => <option key={t.id} value={t.id}>{t.title}</option>)}
                </select>}
        </div>
        <div className="field">
          <label>Канал доставки</label>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 8 }}>
            {CH_ORDER.map((k) => {
              const enabled = !!(channels && channels[k]); const active = channel === k;
              return (
                <button key={k} type="button" disabled={!enabled} onClick={() => enabled && setChannel(k)}
                  style={{ padding: '10px 4px', borderRadius: 10, fontSize: 13, fontWeight: 600,
                    border: `2px solid ${active && enabled ? 'var(--accent)' : 'var(--border-2)'}`,
                    background: active && enabled ? 'var(--accent-soft)' : (enabled ? 'var(--surface)' : 'var(--bg-2)'),
                    color: enabled ? 'var(--text)' : 'var(--text-3)' }}>
                  {CH_LABEL[k]}
                </button>
              );
            })}
          </div>
          {noChannels && <div className="subtle" style={{ color: 'var(--danger)', marginTop: 6 }}>У клиента нет ни одного канала связи.</div>}
        </div>
        {err && <div className="badge danger" style={{ display: 'block', padding: '10px 12px', marginTop: 8 }}>{err}</div>}
      </Sheet>
    );
  }

  // ── Заявление ПЭП ────────────────────────────────────────
  const APP_TYPES = [
    { key: 'sick', title: 'Заморозка по болезни' },
    { key: 'vacation', title: 'Заморозка на отпуск' },
    { key: 'place_hold', title: 'Сохранение места' },
    { key: 'refund', title: 'Возврат денег' },
  ];
  const CH_LABEL = { sms: 'SMS', email: 'Email', max: 'MAX', telegram: 'Telegram' };
  const CH_ORDER = ['sms', 'email', 'max', 'telegram'];
  const REL_OPTIONS = [
    { value: 'parent', label: 'Родитель / законный представитель' },
    { value: 'guardian', label: 'Опекун' },
    { value: 'proxy', label: 'Представитель по доверенности' },
  ];

  function ApplicationSheet({ client, onClose }) {
    const [type, setType] = useState(null);
    const [channels, setChannels] = useState(null);
    const [channel, setChannel] = useState('sms');
    const [beneficiary, setBeneficiary] = useState('self');
    const [relation, setRelation] = useState('parent');
    const [sending, setSending] = useState(false);
    const [err, setErr] = useState(null);

    const relatives = useMemo(() => {
      const map = new Map();
      const add = (arr, src) => (arr || [])
        .filter((r) => r && r.active !== false && r.id !== client.id)
        .forEach((r) => { if (!map.has(r.id)) map.set(r.id, { ...r, _src: src }); });
      add(client.children, 'child');
      add(client.parents, 'parent');
      add(client.spouses, 'spouse');
      return Array.from(map.values());
    }, [client]);

    useEffect(() => {
      window.api.sign.clientChannels(client.id)
        .then((r) => {
          const ch = r.channels || {};
          setChannels(ch);
          if (!ch.sms) { const f = ['email', 'max', 'telegram'].find((k) => ch[k]); if (f) setChannel(f); }
        })
        .catch(() => setChannels({}));
    }, [client.id]);

    function relName(r) {
      return [r.last_name, r.first_name, r.middle_name].filter(Boolean).join(' ').trim() || `Клиент #${r.id}`;
    }

    async function send() {
      if (!type) { setErr('Выберите тип заявления'); return; }
      if (!channels || !channels[channel]) { setErr('Нет контакта для выбранного канала'); return; }
      setSending(true); setErr(null);
      try {
        const body = { client_id: client.id, application_type: type, channel, contacts: channels };
        if (beneficiary !== 'self') {
          body.beneficiary_relation = relation;
          body.operator_locked = true;
          body.beneficiary_client_id = Number(beneficiary);
        }
        const r = await window.api.sign.applications.initiate(body);
        window.toast(`Заявление отправлено через ${CH_LABEL[r.channel || channel]}`, 'ok');
        onClose();
      } catch (e) {
        setErr(e.message || 'Ошибка отправки');
      } finally { setSending(false); }
    }

    const noChannels = channels && Object.keys(channels).filter((k) => channels[k]).length === 0;

    return (
      <Sheet title="Электронное заявление (ПЭП)" onClose={onClose}
        footer={<>
          <button className="btn btn-ghost" onClick={onClose} disabled={sending}>Отмена</button>
          <button className="btn btn-primary" onClick={send} disabled={!type || sending || noChannels}>
            {sending ? 'Отправка…' : 'Отправить'}
          </button>
        </>}>
        <div className="badge info" style={{ display: 'block', padding: '12px 14px', marginBottom: 14, fontWeight: 400, borderRadius: 12, lineHeight: 1.45 }}>
          Клиент получит ссылку, сам заполнит и подпишет заявление кодом. Применять заморозку/возврат
          вручную нужно после получения подписанного заявления.
        </div>

        <div className="field">
          <label>Тип заявления</label>
          <div className="stack">
            {APP_TYPES.map((t) => (
              <button key={t.key} type="button" className="btn"
                style={{ justifyContent: 'flex-start',
                  borderColor: type === t.key ? 'var(--accent)' : 'var(--border-2)',
                  background: type === t.key ? 'var(--accent-soft)' : 'var(--surface)' }}
                onClick={() => setType(t.key)}>
                {t.title}
              </button>
            ))}
          </div>
        </div>

        {relatives.length > 0 && (
          <div className="field">
            <label>За кого подаётся</label>
            <select className="input" value={beneficiary} onChange={(e) => setBeneficiary(e.target.value)}>
              <option value="self">От своего имени</option>
              {relatives.map((r) => (
                <option key={r.id} value={r.id}>
                  {r._src === 'child' || r.is_child ? 'За ребёнка: ' : 'За связанного: '}{relName(r)}
                </option>
              ))}
            </select>
          </div>
        )}

        {beneficiary !== 'self' && (
          <div className="field">
            <label>Тип представительства</label>
            <select className="input" value={relation} onChange={(e) => setRelation(e.target.value)}>
              {REL_OPTIONS.map((o) => <option key={o.value} value={o.value}>{o.label}</option>)}
            </select>
          </div>
        )}

        <div className="field">
          <label>Канал доставки</label>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 8 }}>
            {CH_ORDER.map((k) => {
              const enabled = !!(channels && channels[k]);
              const active = channel === k;
              return (
                <button key={k} type="button" disabled={!enabled}
                  onClick={() => enabled && setChannel(k)}
                  style={{ padding: '10px 4px', borderRadius: 10, fontSize: 13, fontWeight: 600,
                    border: `2px solid ${active && enabled ? 'var(--accent)' : 'var(--border-2)'}`,
                    background: active && enabled ? 'var(--accent-soft)' : (enabled ? 'var(--surface)' : 'var(--bg-2)'),
                    color: enabled ? 'var(--text)' : 'var(--text-3)' }}>
                  {CH_LABEL[k]}
                </button>
              );
            })}
          </div>
          {noChannels && <div className="subtle" style={{ color: 'var(--danger)', marginTop: 6 }}>
            У клиента нет ни одного канала связи.</div>}
        </div>

        {err && <div className="badge danger" style={{ display: 'block', padding: '10px 12px', marginTop: 8 }}>{err}</div>}
      </Sheet>
    );
  }
})();
