/* global React, Icon, UI, LessonHighData */
(function () {
const { useState, useEffect, useMemo, useRef } = React;
const Dj = LessonHighData;

// ============================================================
// JournalPage — 강사 전용 일지 작성 페이지
// 회원당 1페이지. "오늘 수업" 카드가 상단 포커스, 과거 일지는 아래로 타임라인.
// 패드/태블릿 가로모드 + 데스크톱 모두 대응.
// ============================================================
function Journal({ memberId, onClose, onOpenMember, onSendLink }) {
  const m = Dj.getMember(memberId);
  if (!m) return null;
  const t = Dj.getTeacher(m.teacherId);

  // 회원의 과거 일지 (최신순)
  const pastNotes = useMemo(() => {
    return Dj.lessonNotes
      .filter(n => n.memberId === memberId)
      .sort((a, b) => b.date.localeCompare(a.date));
  }, [memberId]);

  // 오늘 수업 메타 (mock — 오늘 = 2025-11-20, 회원의 오늘 예약 찾기)
  const todayReservation = useMemo(() => {
    return Dj.reservations.find(r => r.memberId === memberId && r.dow === 3 && r.type === 'lesson')
      || Dj.reservations.find(r => r.memberId === memberId && r.type === 'lesson');
  }, [memberId]);
  const room = todayReservation ? Dj.getRoom(todayReservation.roomId) : null;

  // 작성 중 일지 상태
  const initialFields = useMemo(() => {
    const fields = {};
    Dj.settings.lessonFormFields.forEach(f => { fields[f.id] = ''; });
    return fields;
  }, []);
  const [fieldValues, setFieldValues] = useState(initialFields);
  const [internalNote, setInternalNote] = useState('');
  const [memberMessage, setMemberMessage] = useState('');
  const [externalLink, setExternalLink] = useState('');
  const [savedAt, setSavedAt] = useState(null);
  // I2 — Today's media drafts
  const [draftMedia, setDraftMedia] = useState([]);
  const [recording, setRecording] = useState(null); // { secs, max }
  // Live recording timer
  useEffect(() => {
    if (!recording) return;
    if (recording.secs >= recording.max) {
      // auto-stop, commit
      setDraftMedia(d => [...d, { id: 'r' + Date.now(), kind: 'audio', durationSec: recording.secs, caption: '오늘 녹음', takenAt: formatTime(new Date()) }]);
      setRecording(null);
      return;
    }
    const t = setTimeout(() => setRecording(r => r ? { ...r, secs: r.secs + 1 } : r), 1000);
    return () => clearTimeout(t);
  }, [recording]);

  function startRec() { setRecording({ secs: 0, max: Dj.mediaPolicy?.maxAudioSec || 90 }); }
  function stopRec() {
    if (!recording) return;
    setDraftMedia(d => [...d, { id: 'r' + Date.now(), kind: 'audio', durationSec: recording.secs, caption: '오늘 녹음', takenAt: formatTime(new Date()) }]);
    setRecording(null);
  }
  function addPhoto() {
    setDraftMedia(d => [...d, { id: 'p' + Date.now(), kind: 'photo', caption: '악보 메모', takenAt: formatTime(new Date()) }]);
  }
  function removeMedia(id) { setDraftMedia(d => d.filter(m => m.id !== id)); }

  // 자동 저장 표시 (실제 저장 X, 표시만)
  useEffect(() => {
    const hasContent = Object.values(fieldValues).some(v => v) || internalNote || memberMessage;
    if (!hasContent) return;
    const t = setTimeout(() => {
      setSavedAt(new Date());
    }, 1200);
    return () => clearTimeout(t);
  }, [fieldValues, internalNote, memberMessage]);

  // Esc 닫기
  useEffect(() => {
    const onKey = (e) => { if (e.key === 'Escape') onClose && onClose(); };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [onClose]);

  const todayCardRef = useRef(null);
  // 마운트 후 오늘 카드로 포커스
  useEffect(() => {
    todayCardRef.current?.querySelector('input, textarea')?.focus();
  }, [memberId]);

  return (
    <div className="journal-page">
      {/* 상단 바 */}
      <header className="journal-top">
        <button className="journal-back" onClick={onClose} title="닫기 (Esc)">
          <Icon.ChevLeft size={18}/>
          <span>일정으로</span>
        </button>

        <div className="journal-breadcrumb">
          <span className="t-caption">수업일지</span>
          <Icon.ChevRight size={12} style={{ color: 'var(--text-tertiary)' }}/>
          <button
            className="journal-breadcrumb__member"
            onClick={() => onOpenMember && onOpenMember(memberId)}
            title="회원 상세 열기"
          >
            <UI.Avatar name={m.name} tone={m.tone} size="sm"/>
            <span>{m.name}</span>
          </button>
        </div>

        <div className="journal-top__right">
          {savedAt && (
            <span className="t-caption journal-saved">
              <Icon.Check size={12}/>
              <span>{formatTime(savedAt)} 자동 저장됨</span>
            </span>
          )}
          <UI.Button icon={Icon.Send} variant="ghost" onClick={() => window.toast && window.toast('회원 화면 미리보기 — 와이드 창이 열림')}>미리보기</UI.Button>
          <UI.Button icon={Icon.Check} variant="primary" onClick={() => window.toast && window.toast('일지 저장 + 회원에게 알림톡 발송 완료', { tone: 'success' })}>저장 + 알림톡 발송</UI.Button>
        </div>
      </header>

      {/* 본문 — 좌: 회원 카드 (sticky) / 우: 일지 타임라인 */}
      <div className="journal-body">
        <aside className="journal-rail">
          <div className="journal-rail__inner">
            <div className="row" style={{ gap: 10, marginBottom: 12 }}>
              <UI.Avatar name={m.name} tone={m.tone} size="lg"/>
              <div className="col" style={{ gap: 0, flex: 1 }}>
                <div className="t-h3" style={{ marginBottom: 2 }}>{m.name}</div>
                <div className="t-caption">{m.birth || '—'} · {t.name} 선생님</div>
              </div>
            </div>

            <div className="journal-rail__divider"/>

            <RailRow label="음역대" value={m.range || '—'} mono/>
            <RailRow label="레슨 목표" value={m.goal || '—'} multiline/>
            <RailRow
              label="수업권"
              value={
                m.passType === 'SESSION'
                  ? <span><span className="t-mono num" style={{ fontWeight: 600 }}>{m.remaining}</span>
                      <span style={{ color: 'var(--text-tertiary)' }}> / {m.total}회</span></span>
                  : '기간권'
              }
            />
            <RailRow
              label="다음 결제"
              value={m.nextDue
                ? <span className="t-mono num">{Dj.formatDate(m.nextDue, { short: true })} · {Dj.formatMoney(m.amount)}</span>
                : '—'}
            />

            <div className="journal-rail__divider"/>

            {m.additionalContact && (
              <RailRow
                label="추가 알림 수신자"
                value={
                  <div className="col" style={{ gap: 0 }}>
                    <span style={{ fontSize: 13, fontWeight: 600 }}>{m.additionalContact.name}</span>
                    <span className="t-caption t-mono num">{m.additionalContact.phone}</span>
                    <span className="t-caption" style={{ fontSize: 11 }}>관계: {m.additionalContact.relation}</span>
                  </div>
                }
              />
            )}

            <div className="journal-rail__divider"/>

            <div className="t-micro" style={{ marginBottom: 8 }}>이번 주 일정</div>
            <ul className="journal-rail__sched">
              {Dj.reservations.filter(r => r.memberId === memberId).map(r => (
                <li key={r.id} className={`journal-sched-row ${r.dow === 3 ? 'is-today' : ''}`}>
                  <span className="journal-sched-row__day">{Dj.dayNames[r.dow]}</span>
                  <span className="journal-sched-row__time t-mono num">{Dj.formatTime(r.start)}</span>
                  <span className="journal-sched-row__room">{Dj.getRoom(r.roomId)?.name}</span>
                </li>
              ))}
            </ul>
          </div>
        </aside>

        {/* 우측 — 일지 타임라인 */}
        <main className="journal-main">
          <div className="journal-main__inner">

            {/* 오늘 수업 카드 — 편집 가능, 포커스 */}
            <article ref={todayCardRef} className="journal-card is-today">
              <header className="journal-card__head">
                <div className="row" style={{ gap: 10 }}>
                  <span className="journal-marker is-today"/>
                  <div className="col" style={{ gap: 0 }}>
                    <div className="row" style={{ gap: 8 }}>
                      <span className="t-h2" style={{ margin: 0 }}>오늘 수업</span>
                      <UI.Badge tone="accent" dot>작성 중</UI.Badge>
                    </div>
                    <div className="t-caption">
                      {Dj.formatDate(Dj.TODAY)}
                      {todayReservation && (
                        <span> · <span className="t-mono num">{Dj.formatTime(todayReservation.start)}–{Dj.formatTime(todayReservation.end)}</span> · {room?.name}</span>
                      )}
                    </div>
                  </div>
                </div>
                <div className="row" style={{ gap: 8 }}>
                  <UI.Button size="sm" variant="ghost" icon={Icon.Eye} onClick={() => window.toast && window.toast('회원 모바일 일지 화면 미리보기')}>회원 화면 미리보기</UI.Button>
                </div>
              </header>

              <div className="journal-card__body">
                {/* 정형 필드 */}
                <div className="col" style={{ gap: 16 }}>
                  {Dj.settings.lessonFormFields.map(f => (
                    <div key={f.id} className="field journal-field">
                      <label className="field__label">
                        {f.label}
                        {f.required && <span style={{ color: 'var(--status-danger)', marginLeft: 4 }}>*</span>}
                      </label>
                      {f.type === 'longtext' ? (
                        <textarea
                          className="textarea"
                          rows={3}
                          placeholder={f.placeholder || ''}
                          value={fieldValues[f.id] || ''}
                          onChange={(e) => setFieldValues(v => ({ ...v, [f.id]: e.target.value }))}
                        />
                      ) : f.type === 'select' ? (
                        <select
                          className="select"
                          value={fieldValues[f.id] || ''}
                          onChange={(e) => setFieldValues(v => ({ ...v, [f.id]: e.target.value }))}
                        >
                          <option value="">선택…</option>
                          {f.options.map(o => <option key={o} value={o}>{o}</option>)}
                        </select>
                      ) : (
                        <input
                          className="input"
                          placeholder={f.placeholder || ''}
                          value={fieldValues[f.id] || ''}
                          onChange={(e) => setFieldValues(v => ({ ...v, [f.id]: e.target.value }))}
                        />
                      )}
                      {f.hint && <div className="t-caption" style={{ fontSize: 11, marginTop: 4, lineHeight: 1.45 }}>{f.hint}</div>}
                    </div>
                  ))}
                </div>

                <div className="divider" style={{ margin: '8px 0' }}/>

                {/* 강사 내부 메모 — 회원에게 절대 노출되지 않음 */}
                <div className="field">
                  <div className="row" style={{ marginBottom: 6, gap: 6, alignItems: 'center' }}>
                    <Icon.Lock size={12} style={{ color: 'var(--text-tertiary)' }}/>
                    <label className="field__label" style={{ marginBottom: 0 }}>
                      강사 내부 메모
                      <span className="muted" style={{ fontWeight: 400, marginLeft: 6 }}>강사·원장만 열람</span>
                    </label>
                  </div>
                  <textarea
                    className="textarea"
                    rows={4}
                    placeholder="컨디션·태도·다음 시간 어조 등 솔직한 내부 기록. 회원은 절대 볼 수 없습니다."
                    value={internalNote}
                    onChange={(e) => setInternalNote(e.target.value)}
                  />
                </div>

                {/* 회원에게 한마디 — 입력 시만 회원에게 노출 */}
                <div className="field">
                  <div className="row" style={{ marginBottom: 6, gap: 6, alignItems: 'center' }}>
                    <Icon.Eye size={12} style={{ color: 'var(--accent-default)' }}/>
                    <label className="field__label" style={{ marginBottom: 0 }}>
                      회원에게 한마디
                      <span className="muted" style={{ fontWeight: 400, marginLeft: 6 }}>선택 · 입력한 경우에만 회원 일지에 표시</span>
                    </label>
                  </div>
                  <textarea
                    className="textarea"
                    rows={3}
                    placeholder="예) 오늘 후렴 끊음 안정 좋았어요! 다음 시간에 브릿지 이어서 가봅시다 🎤"
                    value={memberMessage}
                    onChange={(e) => setMemberMessage(e.target.value)}
                  />
                  <div className="t-caption" style={{ fontSize: 11, marginTop: 4, lineHeight: 1.45 }}>
                    회원 본인과 추가 알림 수신자(폰 등록 시)가 모바일 일지에서 그대로 읽게 됩니다.
                  </div>
                </div>

                {/* I2 · 미디어 슬롯 (audio + photo) */}
                <div className="journal-media">
                  <div className="row" style={{ marginBottom: 8 }}>
                    <span className="t-micro">오늘 녹음 · 사진</span>
                    <span className="t-caption" style={{ marginLeft: 'auto', fontSize: 11 }}>
                      녹음 ≤ {Dj.mediaPolicy?.maxAudioSec || 90}초 · 사진 ≤ {Dj.mediaPolicy?.maxPhotoCount || 5}장 · 1년 보관
                    </span>
                  </div>

                  {recording && (
                    <div className="journal-rec">
                      <span className="journal-rec__pulse"/>
                      <span className="journal-rec__label">REC · 녹음중</span>
                      <span className="t-mono num journal-rec__time">
                        {String(Math.floor(recording.secs / 60)).padStart(2,'0')}:{String(recording.secs % 60).padStart(2,'0')}
                      </span>
                      <div className="journal-rec__bar">
                        <div className="journal-rec__fill" style={{ width: `${(recording.secs / recording.max) * 100}%` }}/>
                      </div>
                      <span className="t-mono num" style={{ fontSize: 11, color: 'var(--text-tertiary)' }}>/ {String(Math.floor(recording.max / 60)).padStart(2,'0')}:{String(recording.max % 60).padStart(2,'0')}</span>
                      <UI.Button size="sm" variant="danger" onClick={stopRec}>정지 · 첨부</UI.Button>
                    </div>
                  )}

                  <div className="journal-media__row">
                    {draftMedia.map(md => (
                      <div key={md.id} className="journal-media__tile">
                        {md.kind === 'audio' ? (
                          <div className="journal-media__audio">
                            <Icon.Mobile size={12}/>
                            <span className="t-mono num" style={{ fontSize: 11, fontWeight: 600 }}>
                              {String(Math.floor(md.durationSec / 60)).padStart(2,'0')}:{String(md.durationSec % 60).padStart(2,'0')}
                            </span>
                          </div>
                        ) : (
                          <div className="journal-media__photo"><Icon.Eye size={14}/></div>
                        )}
                        <span className="journal-media__cap">{md.caption}</span>
                        <button className="journal-media__x" onClick={() => removeMedia(md.id)} title="제거"><Icon.X size={10}/></button>
                      </div>
                    ))}
                    {!recording && (
                      <button className="journal-media__add journal-media__add--rec" onClick={startRec}>
                        <span className="journal-media__rec-dot"/>
                        <span>녹음 시작</span>
                      </button>
                    )}
                    <button className="journal-media__add" onClick={addPhoto}>
                      <Icon.Plus size={14}/>
                      <span>사진</span>
                    </button>
                  </div>

                  <div className="t-caption" style={{ fontSize: 11, marginTop: 8 }}>
                    저장 시 회원 모바일 「녹음 · 진도」에 자동 추가 · 녹음은 강사만 볼 수 있으며 학원 설정의 보관 정책을 따릅니다.
                  </div>
                </div>

                {/* 외부 링크 */}
                <div className="field">
                  <label className="field__label">
                    외부 링크
                    <span className="muted" style={{ fontWeight: 400, marginLeft: 6 }}>선택</span>
                  </label>
                  <input
                    className="input"
                    placeholder="유튜브, 드라이브, 녹음 파일 등"
                    value={externalLink}
                    onChange={(e) => setExternalLink(e.target.value)}
                  />
                </div>
              </div>
            </article>

            {/* 과거 일지 — 읽기 전용 타임라인 */}
            {pastNotes.length > 0 && (
              <div className="journal-past-label">
                <div className="journal-past-label__line"/>
                <span className="t-micro">과거 수업일지 · {pastNotes.length}건</span>
                <div className="journal-past-label__line"/>
              </div>
            )}

            {pastNotes.map(n => (
              <PastNote key={n.id} note={n} teacher={Dj.getTeacher(n.teacherId)}/>
            ))}

            {pastNotes.length === 0 && (
              <div className="journal-empty">
                <Icon.Note size={28} style={{ color: 'var(--text-tertiary)' }}/>
                <div className="t-body-strong">아직 과거 일지가 없습니다</div>
                <div className="t-caption">오늘 일지를 저장하면 여기에 차곡차곡 쌓입니다.</div>
              </div>
            )}

            <div style={{ height: 80 }}/>
          </div>
        </main>
      </div>
    </div>
  );
}

// ============================================================
// 과거 일지 카드 — 읽기 전용
// ============================================================
function PastNote({ note, teacher }) {
  return (
    <article className="journal-card is-past">
      <header className="journal-card__head">
        <div className="row" style={{ gap: 10 }}>
          <span className="journal-marker"/>
          <div className="col" style={{ gap: 0 }}>
            <div className="row" style={{ gap: 8 }}>
              <span className="t-body-strong">{Dj.formatDate(note.date, { short: true })}</span>
              {note.memberMessage
                ? <UI.Badge tone="success" dot>회원에게 한마디 있음</UI.Badge>
                : <UI.Badge tone="neutral">내부 기록만</UI.Badge>}
            </div>
            <div className="t-caption">{teacher?.name} 선생님</div>
          </div>
        </div>
        <UI.Button size="sm" variant="ghost" icon={Icon.Edit} onClick={() => window.toast && window.toast('이전 일지 편집 모드 — 수정 후 "저장" 클릭')}>편집</UI.Button>
      </header>

      <div className="journal-card__body">
        <div className="journal-past-fields">
          {Object.entries(note.fields).map(([k, v]) => (
            <div key={k} className="journal-past-field">
              <div className="t-micro">{k}</div>
              <div style={{ fontSize: 14, lineHeight: 1.55 }}>{v}</div>
            </div>
          ))}
        </div>
        {note.media && note.media.length > 0 && (
          <div className="journal-past-media">
            {note.media.map(md => (
              <div key={md.id} className="journal-past-media__tile">
                {md.kind === 'audio' ? (
                  <React.Fragment>
                    <span className="journal-past-media__play">▶</span>
                    <span className="t-mono num" style={{ fontSize: 11, fontWeight: 600 }}>
                      {String(Math.floor(md.durationSec / 60)).padStart(2,'0')}:{String(md.durationSec % 60).padStart(2,'0')}
                    </span>
                  </React.Fragment>
                ) : (
                  <span className="journal-past-media__photo"><Icon.Eye size={14}/></span>
                )}
                <span className="journal-past-media__cap">{md.caption}</span>
              </div>
            ))}
          </div>
        )}
        {note.internalNote && (
          <div className="journal-past-memo">
            <div className="t-micro" style={{ marginBottom: 4, display: 'flex', alignItems: 'center', gap: 4 }}>
              <Icon.Lock size={10}/>
              <span>강사 내부 메모 · 강사·원장만</span>
            </div>
            <div style={{ fontSize: 13, lineHeight: 1.6 }}>{note.internalNote}</div>
          </div>
        )}
        {note.memberMessage && (
          <div className="journal-past-memo is-shared">
            <div className="t-micro" style={{ marginBottom: 4, display: 'flex', alignItems: 'center', gap: 4 }}>
              <Icon.Eye size={10}/>
              <span>회원에게 한마디 · 회원 화면 공개</span>
            </div>
            <div style={{ fontSize: 13, lineHeight: 1.6 }}>{note.memberMessage}</div>
          </div>
        )}
      </div>
    </article>
  );
}

// ============================================================
// 좌측 회원 정보 행
// ============================================================
function RailRow({ label, value, mono, multiline }) {
  return (
    <div className="journal-rail__row">
      <div className="t-micro">{label}</div>
      <div className={`journal-rail__val ${mono ? 't-mono num' : ''} ${multiline ? 'is-multi' : ''}`}>
        {value}
      </div>
    </div>
  );
}

function formatTime(d) {
  const h = String(d.getHours()).padStart(2, '0');
  const m = String(d.getMinutes()).padStart(2, '0');
  return `${h}:${m}`;
}

window.JournalPage = { Journal };
})();
