// Modal components: BookingModal, SecondOpinionModal
const { useState: muS, useEffect: muE, useRef: muR } = React;

// ============ MODAL SHELL ============
const Modal = ({ open, onClose, children, title, subtitle, width = 560 }) => {
  muE(() => {
    if (open) {
      document.body.classList.add('modal-open');
      const onKey = (e) => { if (e.key === 'Escape') onClose(); };
      document.addEventListener('keydown', onKey);
      return () => {
        document.body.classList.remove('modal-open');
        document.removeEventListener('keydown', onKey);
      };
    }
  }, [open, onClose]);

  if (!open) return null;

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" style={{ maxWidth: width }} onClick={(e) => e.stopPropagation()}>
        <button className="modal__close" onClick={onClose} aria-label="Закрыть">
          <Icon name="close" size={20} />
        </button>
        {title && (
          <div className="modal__head">
            <h3 className="modal__title">{title}</h3>
            {subtitle && <p className="modal__sub">{subtitle}</p>}
          </div>
        )}
        <div className="modal__body">
          {children}
        </div>
      </div>

      <style>{`
        .modal-overlay {
          position: fixed;
          inset: 0;
          background: oklch(0.18 0.04 255 / 0.45);
          backdrop-filter: blur(4px);
          z-index: 100;
          display: flex;
          align-items: center;
          justify-content: center;
          padding: 24px;
          animation: fadeIn .15s ease;
        }
        .modal {
          background: #fff;
          border-radius: var(--r-lg);
          width: 100%;
          max-height: calc(100vh - 48px);
          overflow-y: auto;
          position: relative;
          box-shadow: var(--shadow-lg);
          animation: modalIn .25s cubic-bezier(.22,.61,.36,1);
        }
        @keyframes modalIn {
          from { opacity: 0; transform: translateY(20px) scale(0.98); }
          to { opacity: 1; transform: translateY(0) scale(1); }
        }
        .modal__close {
          position: absolute;
          top: 18px; right: 18px;
          width: 36px; height: 36px;
          border-radius: 999px;
          background: var(--navy-100);
          color: var(--ink-700);
          display: inline-flex;
          align-items: center;
          justify-content: center;
          transition: background .15s ease;
          z-index: 2;
        }
        .modal__close:hover { background: var(--navy-200); }
        .modal__head { padding: 32px 32px 0; }
        .modal__title { font-size: 24px; font-weight: 600; letter-spacing: -0.02em; line-height: 1.15; padding-right: 50px; }
        .modal__sub { font-size: 14.5px; color: var(--ink-500); margin-top: 8px; max-width: 440px; line-height: 1.5; }
        .modal__body { padding: 24px 32px 32px; }
      `}</style>
    </div>
  );
};

// ============ BOOKING MODAL ============
const BookingModal = ({ open, onClose }) => {
  const [step, setStep] = muS(1);
  const [data, setData] = muS({
    direction: '',
    doctor: '',
    date: '',
    time: '',
    name: '',
    phone: '',
    comment: '',
  });
  const [submitted, setSubmitted] = muS(false);

  muE(() => {
    if (open) {
      setStep(1);
      setSubmitted(false);
      setData({ direction: '', doctor: '', date: '', time: '', name: '', phone: '', comment: '' });
    }
  }, [open]);

  const set = (patch) => setData((d) => ({ ...d, ...patch }));

  const dates = muR(generateDates(10)).current;
  const times = ['09:00', '10:30', '12:00', '14:00', '15:30', '17:00'];

  const filteredDoctors = data.direction
    ? DATA.doctors.filter(d => d.tags.some(t => t.toLowerCase().includes(data.direction.toLowerCase().split(' ')[0])))
    : DATA.doctors;

  const canNext1 = data.direction;
  const canNext2 = data.date && data.time;
  const canSubmit = data.name.trim() && data.phone.replace(/\D/g, '').length >= 10;

  const handleSubmit = (e) => {
    e.preventDefault();
    if (!canSubmit) return;
    if (window.NZ_API) {
      NZ_API.createAppointment({
        name: data.name, phone: data.phone,
        direction: data.direction, doctor: data.doctor,
        date: data.date, time: data.time, comment: data.comment,
      }).catch(() => {});
    }
    setSubmitted(true);
  };

  return (
    <Modal
      open={open}
      onClose={onClose}
      width={580}
      title={submitted ? 'Заявка отправлена' : 'Запись на приём'}
      subtitle={submitted ? '' : 'Заполните форму — администратор свяжется с вами в течение 15 минут для подтверждения времени'}
    >
      {submitted ? (
        <div className="bm-success">
          <div className="bm-success__icon"><Icon name="check" size={32} strokeWidth={2} /></div>
          <p className="bm-success__text">
            Спасибо, {data.name.split(' ')[0]}! Мы получили заявку на <strong>{data.direction}</strong>, {data.date} в {data.time}.
            Администратор позвонит вам на номер <strong>{data.phone}</strong>.
          </p>
          <button className="btn btn-primary" onClick={onClose}>Закрыть</button>
        </div>
      ) : (
        <>
          <div className="bm-steps">
            {[1, 2, 3].map((s) => (
              <div key={s} className={`bm-step ${step >= s ? 'is-done' : ''} ${step === s ? 'is-active' : ''}`}>
                <span className="bm-step__num">{s}</span>
                <span className="bm-step__label">
                  {s === 1 ? 'Направление' : s === 2 ? 'Дата и время' : 'Контакты'}
                </span>
              </div>
            ))}
          </div>

          {step === 1 && (
            <div className="bm-pane">
              <label className="bm-label">Выберите направление</label>
              <div className="bm-chips">
                {DATA.directions.slice(0, 8).map((d) => (
                  <button
                    key={d.id}
                    className={`bm-chip ${data.direction === d.name ? 'is-active' : ''}`}
                    onClick={() => set({ direction: d.name, doctor: '' })}
                  >
                    <Icon name={d.icon} size={16} />
                    {d.name}
                  </button>
                ))}
              </div>

              <label className="bm-label" style={{ marginTop: 20 }}>Врач (необязательно)</label>
              <div className="bm-doctors">
                <button
                  className={`bm-doctor ${!data.doctor ? 'is-active' : ''}`}
                  onClick={() => set({ doctor: '' })}
                >
                  Любой доступный
                </button>
                {filteredDoctors.slice(0, 4).map((d) => (
                  <button
                    key={d.id}
                    className={`bm-doctor ${data.doctor === d.fullName ? 'is-active' : ''}`}
                    onClick={() => set({ doctor: d.fullName })}
                  >
                    {d.fullName} <span>· {d.specs[0]}</span>
                  </button>
                ))}
              </div>
            </div>
          )}

          {step === 2 && (
            <div className="bm-pane">
              <label className="bm-label">Дата приёма</label>
              <div className="bm-dates">
                {dates.map((d) => (
                  <button
                    key={d.iso}
                    className={`bm-date ${data.date === d.label ? 'is-active' : ''}`}
                    onClick={() => set({ date: d.label })}
                  >
                    <span className="bm-date__dow">{d.dow}</span>
                    <span className="bm-date__day">{d.day}</span>
                    <span className="bm-date__month">{d.month}</span>
                  </button>
                ))}
              </div>

              <label className="bm-label" style={{ marginTop: 20 }}>Время</label>
              <div className="bm-times">
                {times.map((t) => (
                  <button
                    key={t}
                    className={`bm-time ${data.time === t ? 'is-active' : ''}`}
                    onClick={() => set({ time: t })}
                  >{t}</button>
                ))}
              </div>
            </div>
          )}

          {step === 3 && (
            <form className="bm-pane" onSubmit={handleSubmit}>
              <div className="field">
                <label>Ваше имя</label>
                <input
                  type="text"
                  placeholder="Имя Фамилия"
                  value={data.name}
                  onChange={(e) => set({ name: e.target.value })}
                  required
                />
              </div>
              <div className="field" style={{ marginTop: 14 }}>
                <label>Телефон</label>
                <input
                  type="tel"
                  placeholder="+7 (___) ___-__-__"
                  value={data.phone}
                  onChange={(e) => set({ phone: formatPhone(e.target.value) })}
                  required
                />
              </div>
              <div className="field" style={{ marginTop: 14 }}>
                <label>Комментарий <span style={{ color: 'var(--ink-400)', fontWeight: 400 }}>(необязательно)</span></label>
                <textarea
                  rows={3}
                  placeholder="Кратко опишите, что беспокоит"
                  value={data.comment}
                  onChange={(e) => set({ comment: e.target.value })}
                />
              </div>

              <div className="bm-summary">
                <div className="bm-summary__row"><span>Направление</span><span>{data.direction}</span></div>
                {data.doctor && <div className="bm-summary__row"><span>Врач</span><span>{data.doctor}</span></div>}
                <div className="bm-summary__row"><span>Дата и время</span><span>{data.date}, {data.time}</span></div>
              </div>

              <p className="bm-policy">
                Отправляя заявку, вы соглашаетесь с <a href="#">политикой обработки персональных данных</a>.
              </p>
            </form>
          )}

          <div className="bm-actions">
            {step > 1 && (
              <button className="btn btn-secondary" onClick={() => setStep(step - 1)}>
                <Icon name="arrowL" size={16} /> Назад
              </button>
            )}
            <div style={{ flex: 1 }} />
            {step < 3 && (
              <button
                className="btn btn-primary"
                disabled={step === 1 ? !canNext1 : !canNext2}
                onClick={() => setStep(step + 1)}
              >
                Далее <Icon name="arrow" size={16} />
              </button>
            )}
            {step === 3 && (
              <button
                className="btn btn-primary"
                disabled={!canSubmit}
                onClick={handleSubmit}
              >
                Отправить заявку
              </button>
            )}
          </div>
        </>
      )}

      <style>{`
        .bm-steps {
          display: flex;
          gap: 8px;
          margin-bottom: 24px;
        }
        .bm-step {
          display: flex;
          align-items: center;
          gap: 8px;
          padding: 8px 14px;
          border-radius: var(--r-full);
          background: var(--navy-100);
          color: var(--ink-500);
          font-size: 13px;
          font-weight: 500;
          flex: 1;
        }
        .bm-step__num {
          width: 22px; height: 22px;
          border-radius: 999px;
          background: #fff;
          color: var(--ink-500);
          display: inline-flex;
          align-items: center;
          justify-content: center;
          font-size: 12px;
          font-weight: 600;
        }
        .bm-step.is-active {
          background: var(--navy-800);
          color: #fff;
        }
        .bm-step.is-active .bm-step__num { background: var(--accent); color: #fff; }
        .bm-step.is-done:not(.is-active) {
          background: oklch(0.62 0.13 160 / 0.14);
          color: var(--success);
        }
        .bm-step.is-done:not(.is-active) .bm-step__num { background: var(--success); color: #fff; }

        .bm-pane { animation: fadeUp .2s ease both; }
        .bm-label { display: block; font-size: 13px; font-weight: 500; color: var(--ink-700); margin-bottom: 10px; }
        .bm-chips { display: flex; flex-wrap: wrap; gap: 8px; }
        .bm-chip {
          display: inline-flex;
          align-items: center;
          gap: 6px;
          padding: 8px 14px;
          border-radius: var(--r-full);
          background: #fff;
          border: 1px solid var(--border-strong);
          color: var(--ink-900);
          font-size: 13.5px;
          font-weight: 500;
          transition: border-color .15s ease, background .15s ease, color .15s ease;
        }
        .bm-chip:hover { border-color: var(--navy-700); }
        .bm-chip.is-active { background: var(--navy-800); border-color: var(--navy-800); color: #fff; }
        .bm-chip.is-active svg { color: #fff; }
        .bm-chip svg { color: var(--navy-700); }

        .bm-doctors { display: flex; flex-direction: column; gap: 6px; }
        .bm-doctor {
          text-align: left;
          padding: 12px 14px;
          border-radius: var(--r-sm);
          border: 1px solid var(--border);
          background: #fff;
          font-size: 14px;
          color: var(--ink-900);
          transition: border-color .15s ease, background .15s ease;
        }
        .bm-doctor span { color: var(--ink-500); }
        .bm-doctor:hover { border-color: var(--border-strong); }
        .bm-doctor.is-active { border-color: var(--navy-700); background: var(--navy-50); }

        .bm-dates {
          display: grid;
          grid-template-columns: repeat(5, 1fr);
          gap: 6px;
        }
        .bm-date {
          padding: 12px 4px;
          border-radius: var(--r-sm);
          border: 1px solid var(--border-strong);
          background: #fff;
          display: flex;
          flex-direction: column;
          gap: 2px;
          align-items: center;
          transition: border-color .15s ease, background .15s ease;
        }
        .bm-date:hover { border-color: var(--navy-700); }
        .bm-date.is-active { background: var(--navy-800); border-color: var(--navy-800); color: #fff; }
        .bm-date__dow { font-size: 11px; color: var(--ink-500); text-transform: uppercase; letter-spacing: 0.04em; }
        .bm-date.is-active .bm-date__dow { color: rgba(255,255,255,0.7); }
        .bm-date__day { font-size: 20px; font-weight: 600; line-height: 1; }
        .bm-date__month { font-size: 11px; color: var(--ink-500); }
        .bm-date.is-active .bm-date__month { color: rgba(255,255,255,0.7); }

        .bm-times {
          display: grid;
          grid-template-columns: repeat(6, 1fr);
          gap: 6px;
        }
        .bm-time {
          padding: 10px 0;
          border-radius: var(--r-sm);
          border: 1px solid var(--border-strong);
          background: #fff;
          font-size: 13.5px;
          font-weight: 500;
          transition: border-color .15s ease, background .15s ease, color .15s ease;
        }
        .bm-time:hover { border-color: var(--navy-700); }
        .bm-time.is-active { background: var(--navy-800); border-color: var(--navy-800); color: #fff; }

        .bm-summary {
          margin-top: 20px;
          padding: 14px 16px;
          background: var(--navy-50);
          border-radius: var(--r-sm);
          border: 1px solid var(--border);
        }
        .bm-summary__row {
          display: flex;
          justify-content: space-between;
          gap: 10px;
          padding: 4px 0;
          font-size: 13.5px;
        }
        .bm-summary__row span:first-child { color: var(--ink-500); }
        .bm-summary__row span:last-child { font-weight: 500; color: var(--ink-900); }

        .bm-policy {
          font-size: 12px;
          color: var(--ink-500);
          margin-top: 14px;
          line-height: 1.5;
        }
        .bm-policy a { color: var(--navy-700); text-decoration: underline; }

        .bm-actions {
          display: flex;
          gap: 10px;
          margin-top: 24px;
        }
        .bm-actions .btn[disabled] { opacity: 0.5; cursor: not-allowed; }

        .bm-success {
          text-align: center;
          padding: 20px 8px 0;
        }
        .bm-success__icon {
          width: 64px; height: 64px;
          border-radius: 999px;
          background: oklch(0.62 0.13 160 / 0.14);
          color: var(--success);
          display: inline-flex;
          align-items: center;
          justify-content: center;
          margin-bottom: 20px;
        }
        .bm-success__text {
          font-size: 15px;
          color: var(--ink-700);
          margin-bottom: 24px;
          max-width: 380px;
          line-height: 1.5;
          margin-left: auto;
          margin-right: auto;
        }
      `}</style>
    </Modal>
  );
};

// ============ SECOND OPINION MODAL ============
const SecondOpinionModal = ({ open, onClose }) => {
  const [files, setFiles] = muS([]);
  const [data, setData] = muS({ name: '', phone: '', email: '', condition: '', message: '' });
  const [drag, setDrag] = muS(false);
  const [submitted, setSubmitted] = muS(false);
  const fileInput = muR(null);

  muE(() => {
    if (open) {
      setFiles([]);
      setData({ name: '', phone: '', email: '', condition: '', message: '' });
      setSubmitted(false);
    }
  }, [open]);

  const addFiles = (incoming) => {
    const arr = Array.from(incoming).map(f => ({
      name: f.name,
      size: f.size,
      type: f.type || 'file',
    }));
    setFiles((prev) => [...prev, ...arr].slice(0, 12));
  };

  const removeFile = (idx) => setFiles((prev) => prev.filter((_, i) => i !== idx));

  const set = (patch) => setData((d) => ({ ...d, ...patch }));

  const canSubmit = data.name.trim() && data.phone.replace(/\D/g, '').length >= 10 && data.condition;

  const handleSubmit = (e) => {
    e.preventDefault();
    if (!canSubmit) return;
    if (window.NZ_API) {
      NZ_API.createSecondOpinion({
        name: data.name, phone: data.phone, email: data.email,
        condition: data.condition, message: data.message,
        files: files.map(f => f.name),
      }).catch(() => {});
    }
    setSubmitted(true);
  };

  const formatSize = (n) => {
    if (n < 1024) return `${n} B`;
    if (n < 1024 * 1024) return `${(n / 1024).toFixed(0)} KB`;
    return `${(n / 1024 / 1024).toFixed(1)} MB`;
  };

  return (
    <Modal
      open={open}
      onClose={onClose}
      width={620}
      title={submitted ? 'Документы получены' : 'Получить второе мнение'}
      subtitle={submitted ? '' : 'Загрузите снимки, выписки и анализы. Эксперты НАЦЗДРАВ изучат документы и подготовят независимое заключение в течение 3-7 дней.'}
    >
      {submitted ? (
        <div className="bm-success">
          <div className="bm-success__icon"><Icon name="check" size={32} strokeWidth={2} /></div>
          <p className="bm-success__text">
            Спасибо! Мы получили {files.length} {pluralFiles(files.length)}. Координатор свяжется с вами на номер <strong>{data.phone}</strong> в течение 24 часов, чтобы подтвердить состав консилиума.
          </p>
          <button className="btn btn-primary" onClick={onClose}>Закрыть</button>
        </div>
      ) : (
        <form onSubmit={handleSubmit}>
          {/* Upload */}
          <div
            className={`so-drop ${drag ? 'is-drag' : ''}`}
            onDragOver={(e) => { e.preventDefault(); setDrag(true); }}
            onDragLeave={() => setDrag(false)}
            onDrop={(e) => {
              e.preventDefault();
              setDrag(false);
              addFiles(e.dataTransfer.files);
            }}
            onClick={() => fileInput.current && fileInput.current.click()}
          >
            <input
              type="file"
              ref={fileInput}
              multiple
              hidden
              onChange={(e) => addFiles(e.target.files)}
            />
            <Icon name="upload" size={28} className="so-drop__icon" />
            <div>
              <div className="so-drop__title">Перетащите файлы или нажмите для выбора</div>
              <div className="so-drop__sub">Поддерживаются PDF, JPG, PNG, DICOM. До 12 файлов, по 50 MB каждый.</div>
            </div>
          </div>

          {files.length > 0 && (
            <div className="so-files">
              {files.map((f, i) => (
                <div key={i} className="so-file">
                  <Icon name="paper" size={18} />
                  <span className="so-file__name">{f.name}</span>
                  <span className="so-file__size">{formatSize(f.size)}</span>
                  <button type="button" className="so-file__remove" onClick={() => removeFile(i)} aria-label="Удалить">
                    <Icon name="close" size={14} />
                  </button>
                </div>
              ))}
            </div>
          )}

          {/* Fields */}
          <div className="so-fields">
            <div className="field">
              <label>Ваше имя</label>
              <input
                type="text"
                placeholder="Имя Фамилия"
                value={data.name}
                onChange={(e) => set({ name: e.target.value })}
                required
              />
            </div>
            <div className="field">
              <label>Телефон</label>
              <input
                type="tel"
                placeholder="+7 (___) ___-__-__"
                value={data.phone}
                onChange={(e) => set({ phone: formatPhone(e.target.value) })}
                required
              />
            </div>
            <div className="field">
              <label>Email <span style={{ color: 'var(--ink-400)', fontWeight: 400 }}>(необязательно)</span></label>
              <input
                type="email"
                placeholder="name@example.com"
                value={data.email}
                onChange={(e) => set({ email: e.target.value })}
              />
            </div>
            <div className="field">
              <label>Направление / диагноз</label>
              <select value={data.condition} onChange={(e) => set({ condition: e.target.value })} required>
                <option value="">Выберите...</option>
                {DATA.directions.map(d => (
                  <option key={d.id} value={d.name}>{d.name}</option>
                ))}
                <option value="Другое">Другое / не определено</option>
              </select>
            </div>
          </div>

          <div className="field" style={{ marginTop: 14 }}>
            <label>Опишите ситуацию</label>
            <textarea
              rows={3}
              placeholder="Какой вопрос вы хотите задать консилиуму, что вас беспокоит, какие диагнозы уже ставили"
              value={data.message}
              onChange={(e) => set({ message: e.target.value })}
            />
          </div>

          <p className="bm-policy">
            Документы передаются по защищённому каналу. Отправляя заявку, вы соглашаетесь с <a href="#">политикой обработки персональных данных</a>.
          </p>

          <div className="bm-actions">
            <div style={{ flex: 1 }} />
            <button type="submit" className="btn btn-primary" disabled={!canSubmit}>
              Отправить на консилиум
            </button>
          </div>
        </form>
      )}

      <style>{`
        .so-drop {
          padding: 28px 22px;
          border: 2px dashed var(--border-strong);
          border-radius: var(--r-md);
          background: var(--navy-50);
          display: flex;
          align-items: center;
          gap: 16px;
          cursor: pointer;
          transition: border-color .15s ease, background .15s ease;
          margin-bottom: 16px;
        }
        .so-drop:hover, .so-drop.is-drag {
          border-color: var(--navy-700);
          background: var(--navy-100);
        }
        .so-drop__icon { color: var(--navy-700); flex-shrink: 0; }
        .so-drop__title { font-size: 15px; font-weight: 600; color: var(--ink-900); }
        .so-drop__sub { font-size: 13px; color: var(--ink-500); margin-top: 2px; }

        .so-files {
          display: flex;
          flex-direction: column;
          gap: 6px;
          margin-bottom: 16px;
        }
        .so-file {
          display: flex;
          align-items: center;
          gap: 10px;
          padding: 10px 12px;
          background: #fff;
          border: 1px solid var(--border);
          border-radius: var(--r-sm);
          font-size: 13.5px;
        }
        .so-file svg { color: var(--navy-600); }
        .so-file__name { flex: 1; color: var(--ink-900); font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
        .so-file__size { color: var(--ink-500); font-size: 12.5px; }
        .so-file__remove {
          width: 24px; height: 24px;
          border-radius: 999px;
          background: var(--navy-100);
          color: var(--ink-500);
          display: inline-flex;
          align-items: center;
          justify-content: center;
        }
        .so-file__remove:hover { background: var(--danger); color: #fff; }

        .so-fields {
          display: grid;
          grid-template-columns: 1fr 1fr;
          gap: 14px;
        }
        @media (max-width: 540px) {
          .so-fields { grid-template-columns: 1fr; }
        }
      `}</style>
    </Modal>
  );
};

// ============ HELPERS ============
function generateDates(count) {
  const out = [];
  const dows = ['ВС', 'ПН', 'ВТ', 'СР', 'ЧТ', 'ПТ', 'СБ'];
  const months = ['янв', 'фев', 'мар', 'апр', 'мая', 'июн', 'июл', 'авг', 'сен', 'окт', 'ноя', 'дек'];
  const now = new Date();
  for (let i = 0; i < count; i++) {
    const d = new Date(now);
    d.setDate(now.getDate() + i);
    const day = d.getDate();
    const month = months[d.getMonth()];
    out.push({
      iso: d.toISOString().slice(0, 10),
      dow: dows[d.getDay()],
      day,
      month,
      label: `${day} ${month}`,
    });
  }
  return out;
}

function formatPhone(v) {
  const digits = v.replace(/\D/g, '').slice(0, 11);
  if (!digits) return '';
  const d = digits.startsWith('8') ? '7' + digits.slice(1) : digits;
  const p = d.padEnd(11, ' ').split('');
  let out = '+' + p[0];
  if (digits.length > 1) out += ' (' + p.slice(1, 4).join('').trim();
  if (digits.length > 4) out += ') ' + p.slice(4, 7).join('').trim();
  if (digits.length > 7) out += '-' + p.slice(7, 9).join('').trim();
  if (digits.length > 9) out += '-' + p.slice(9, 11).join('').trim();
  return out.trim();
}

function pluralFiles(n) {
  const last = n % 10;
  const teens = n % 100;
  if (teens >= 11 && teens <= 14) return 'файлов';
  if (last === 1) return 'файл';
  if (last >= 2 && last <= 4) return 'файла';
  return 'файлов';
}

Object.assign(window, { Modal, BookingModal, SecondOpinionModal });
