/* global React */
/* hotfix15 + Part C.2.5 TASK 6: 학생 재배정 모달.
 *   mode='student' | 'class'
 *   targetId = 'u_stXXX' | 'stXXX' | classId
 *   - 활성 강사 목록 드롭다운 (원장·부원장·강사)
 *   - 사유 선택: teacher_changed | teacher_retired | class_dissolved | manual
 *   - 학생 재배정 시 unassigned 알림 자동 resolved 처리
 *
 *  전역 진입점: window.openReassignModal(studentId) — 어느 페이지든 GlobalReassignModalMount
 *               컴포넌트가 마운트돼 있으면 모달이 뜸 (CustomEvent 기반).
 *
 *  Phase 3: API POST /students/:id/reassign + 알림 자동 발송. */
(function () {
  const { useState, useEffect } = React;

  function _normalizeStudentId(id) {
    if (!id) return null;
    return id.startsWith('u_') ? id.slice(2) : id;
  }

  /* hotfix18: 학년 bucket 추출 — 학생 grade ('중2') ↔ 클래스 name ('중등 정규반') 매칭 */
  function _gradeBucket(grade) {
    if (!grade) return null;
    if (grade.startsWith('초')) return '초등';
    if (grade.startsWith('중')) return '중등';
    if (grade.startsWith('고')) return '고등';
    return null;
  }
  function _classGradeBucket(cls) {
    if (!cls || !cls.name) return null;
    if (cls.name.indexOf('초등') >= 0) return '초등';
    if (cls.name.indexOf('중등') >= 0) return '중등';
    if (cls.name.indexOf('고등') >= 0) return '고등';
    return null;
  }
  const _DAY_KO = { 1: '월', 2: '화', 3: '수', 4: '목', 5: '금', 6: '토', 7: '일' };
  function _formatClassSchedule(cls) {
    if (!cls) return '';
    return _DAY_KO[cls.day_of_week] + ' ' + (cls.start_time || '') + '~' + (cls.end_time || '');
  }

  function StudentReassignModal({ mode = 'student', targetId, onClose, onSuccess }) {
    const [target, setTarget] = useState(null);
    const [teachers, setTeachers] = useState([]);
    const [selectedTeacherId, setSelectedTeacherId] = useState('');
    const [reason, setReason] = useState('teacher_changed');
    const [processing, setProcessing] = useState(false);
    const [error, setError] = useState('');
    /* hotfix18: 현재 강의 + 새 강의 드롭다운 (cascade) */
    const [activeEnrollment, setActiveEnrollment] = useState(null);
    const [classOptions, setClassOptions] = useState([]);
    const [selectedClassId, setSelectedClassId] = useState('');

    useEffect(() => {
      let cancelled = false;
      async function load() {
        try {
          if (mode === 'student') {
            const sid = _normalizeStudentId(targetId);
            const student = (window.studentsMock || []).find(s => s.id === sid);
            if (!student) { setError('학생을 찾을 수 없습니다: ' + targetId); return; }
            if (cancelled) return;
            setTarget(student);
            if (student.unassigned_reason === 'teacher_retired') setReason('teacher_retired');
            /* hotfix18: 학생의 active enrollment lookup (현재 강의 표시용) */
            if (typeof window.getActiveEnrollment === 'function') {
              const ae = window.getActiveEnrollment(sid);
              if (!cancelled) setActiveEnrollment(ae);
            }
          } else {
            const cls = (window.classesMock || []).find(c => c.id === targetId);
            if (!cls) { setError('클래스를 찾을 수 없습니다: ' + targetId); return; }
            if (cancelled) return;
            setTarget(cls);
          }
          /* 강사 목록 — getAllStaff('active') 활용. 원장/부원장/강사 (role_id 1·2·3) */
          if (typeof window.getAllStaff === 'function') {
            const all = await window.getAllStaff('active');
            if (cancelled) return;
            setTeachers(all.filter(s => s.role_id === 1 || s.role_id === 2 || s.role_id === 3));
          }
        } catch (e) {
          if (!cancelled) setError(e.message || String(e));
        }
      }
      load();
      return () => { cancelled = true; };
    }, [mode, targetId]);

    /* hotfix18: 새 강사 선택 → 그 강사 담당 클래스 목록 (정렬 + edge case 메타) */
    useEffect(() => {
      if (mode !== 'student' || !selectedTeacherId) {
        setClassOptions([]);
        setSelectedClassId('');
        return;
      }
      if (typeof window.getClassesByTeacher !== 'function') return;
      const tid = selectedTeacherId.replace(/^u_/, '');
      const classes = window.getClassesByTeacher(tid) || [];
      const studentBucket = target ? _gradeBucket(target.grade) : null;
      const currentDay = activeEnrollment && activeEnrollment.class ? activeEnrollment.class.day_of_week : null;
      const currentStart = activeEnrollment && activeEnrollment.class ? activeEnrollment.class.start_time : null;
      const enriched = classes.map(c => {
        const cap = (typeof window.getClassCapacity === 'function')
          ? window.getClassCapacity(c.id)
          : { current: 0, max: c.capacity || 0, available: (c.capacity || 0) };
        const gradeMatch = studentBucket && _classGradeBucket(c) === studentBucket;
        const dayMatch = currentDay !== null && c.day_of_week === currentDay;
        const timeMatch = currentStart && c.start_time === currentStart;
        return { cls: c, capacity: cap, gradeMatch, dayMatch, timeMatch, isFull: cap.available === 0 };
      });
      enriched.sort((a, b) => {
        /* 1. 학년 매칭 → 2. 요일 매칭 → 3. 시간 매칭 → 4. 정원 여유 → 5. 가나다 */
        if (a.gradeMatch !== b.gradeMatch) return a.gradeMatch ? -1 : 1;
        if (a.dayMatch !== b.dayMatch) return a.dayMatch ? -1 : 1;
        if (a.timeMatch !== b.timeMatch) return a.timeMatch ? -1 : 1;
        if (a.isFull !== b.isFull) return a.isFull ? 1 : -1;
        return (a.cls.name || '').localeCompare(b.cls.name || '');
      });
      setClassOptions(enriched);
      setSelectedClassId('');
    }, [selectedTeacherId, target, activeEnrollment, mode]);

    useEffect(() => {
      const prev = document.body.style.overflow;
      document.body.style.overflow = 'hidden';
      return () => { document.body.style.overflow = prev; };
    }, []);

    useEffect(() => { if (window.lucide) window.lucide.createIcons(); });

    async function onSave() {
      if (!selectedTeacherId) { setError('새 담당 강사를 선택하세요'); return; }
      if (mode === 'student' && !selectedClassId) { setError('새 강의를 선택하세요'); return; }
      setError(''); setProcessing(true);
      try {
        if (mode === 'student') {
          const sid = _normalizeStudentId(targetId);
          /* hotfix18: newClassId 함께 전달 → reassignStudent 가 enrollment row 발급 + history 기록 */
          await window.reassignStudent(sid, selectedTeacherId, reason, {
            previous_teacher_id: target.primary_teacher_id ? 'u_' + target.primary_teacher_id : null,
            newClassId: selectedClassId,
          });
          /* 미배정 알림 자동 resolved 처리 */
          const notis = window.mockNotifications || [];
          const studentUid = 'u_' + sid;
          const related = notis.filter(n =>
            n.type === 'student_unassigned' && !n.resolved_at &&
            Array.isArray(n.related_user_ids) && n.related_user_ids.indexOf(studentUid) >= 0
          );
          related.forEach(n => {
            const remaining = (n.related_user_ids || []).filter(uid => {
              if (uid === studentUid) return false;
              const remSid = uid.slice(2);
              const s = (window.studentsMock || []).find(x => x.id === remSid);
              return s && (!s.primary_teacher_id || s.unassigned_since);
            });
            if (remaining.length === 0 && typeof window.markNotificationResolved === 'function') {
              window.markNotificationResolved(n.id);
            }
          });
        } else {
          await window.reassignClass(targetId, selectedTeacherId, reason);
        }
        if (typeof onSuccess === 'function') onSuccess();
        onClose(true);
      } catch (e) {
        setError(e.message || String(e));
        setProcessing(false);
      }
    }

    /* hotfix28.2: ModalShell wrapping — Portal + ESC + scroll lock + role="dialog" + focus trap. */
    const _Shell = window.ModalShell;
    if (!target) {
      const body = (
        <React.Fragment>
          <div className="modal-body" style={{padding: 32, textAlign: 'center', color: 'var(--fg-muted)'}}>
            {error || '로딩 중…'}
          </div>
          {error && (
            <div className="modal-footer">
              <button className="btn-secondary" onClick={() => onClose(false)}>닫기</button>
            </div>
          )}
        </React.Fragment>
      );
      return _Shell ? (
        <_Shell open onClose={() => onClose(false)} size="md">{body}</_Shell>
      ) : (
        <div className="modal-overlay" onMouseDown={e => e.target === e.currentTarget && onClose(false)}>
          <div className="modal-content modal-md">{body}</div>
        </div>
      );
    }

    /* 표시용 메타 — hotfix16.7: 현재 담당이 퇴직 강사인 경우 "(퇴직)" 태그 표시 */
    let prevTeacherName = null;
    let prevTeacherIsRetired = false;
    if (mode === 'student' && target.primary_teacher_id) {
      const tu = (window.mockUsers || {})['u_' + target.primary_teacher_id];
      prevTeacherName = tu ? tu.name : target.primary_teacher_id;
      prevTeacherIsRetired = !!(tu && tu.staff_status === 'retired');
    }
    const prevFromMeta = (target.unassigned_metadata && target.unassigned_metadata.previous_teacher_name) || null;

    const ROLE_LABEL = { 1: '원장', 2: '부원장', 3: '선생', 4: '조교' };
    const REASON_OPTS = [
      ['teacher_changed', '강사 변경'],
      ['teacher_retired', '강사 퇴직'],
      ['class_dissolved', '반 폐지'],
      ['manual',          '기타'],
    ];

    /* hotfix16 TASK 7-B: 명칭 정리 — 학생 단위는 "학생 1명 이동" 시나리오로 한정 */
    const _title = mode === 'student' ? '학생 강의 변경' : '클래스 강사 변경';
    /* hotfix28.2: ModalShell wrapping — title prop 으로 header 자동. */
    const _MainShell = _Shell || (function _Fallback(p) {
      return (
        <div className="modal-overlay" onMouseDown={e => e.target === e.currentTarget && p.onClose()}>
          <div className="modal-content modal-md">
            <div className="modal-header">
              <h3>{p.title}</h3>
              <button className="modal-close" onClick={p.onClose} aria-label="닫기">×</button>
            </div>
            {p.children}
          </div>
        </div>
      );
    });
    return (
      <_MainShell open onClose={() => onClose(false)} size="md" title={_title}>
        <React.Fragment>
          <div className="modal-body">
            {mode === 'student' && (
              <div className="hint-text" style={{marginBottom: 12, padding: '8px 12px', background: '#EFF6FF', borderRadius: 4, color: '#1E40AF', fontSize: 12}}>
                💡 이 학생을 다른 강사가 담당하는 강의로 옮깁니다. 여러 학생을 한 번에 이동하려면 강의 단위 재배정을 사용하세요.
              </div>
            )}
            {mode === 'student' ? (
              <div className="reassign-target-info">
                <div className="reassign-row">
                  <span className="rg-label">학생</span>
                  <span className="rg-value"><strong>{target.name}</strong> · {target.grade || '—'} · {target.school || '—'}</span>
                </div>
                <div className="reassign-row">
                  <span className="rg-label">현재 담당</span>
                  <span className="rg-value">
                    {prevTeacherName ? (
                      <>
                        {prevTeacherName} 선생님
                        {prevTeacherIsRetired && (
                          <span className="rg-retired-tag" title="퇴직 처리된 강사 — 새 강사로 변경 필요">
                            🔒 퇴직
                          </span>
                        )}
                      </>
                    ) : (
                      <span className="rg-tag-warning">⚠️ 미배정</span>
                    )}
                  </span>
                </div>
                {prevFromMeta && (
                  <div className="reassign-row">
                    <span className="rg-label">이전 담당</span>
                    <span className="rg-value">
                      {prevFromMeta}
                      {target.unassigned_reason === 'teacher_retired' && <span className="rg-dim"> (퇴직)</span>}
                    </span>
                  </div>
                )}
                {target.unassigned_since && (
                  <div className="reassign-row">
                    <span className="rg-label">미배정 시작</span>
                    <span className="rg-value">{target.unassigned_since}</span>
                  </div>
                )}
                {/* hotfix18: 현재 active enrollment 의 클래스 표시 */}
                {activeEnrollment && activeEnrollment.class && (
                  <div className="reassign-row">
                    <span className="rg-label">현재 강의</span>
                    <span className="rg-value">
                      {activeEnrollment.class.name} · {_formatClassSchedule(activeEnrollment.class)}
                    </span>
                  </div>
                )}
              </div>
            ) : (
              <div className="reassign-target-info">
                <div className="reassign-row">
                  <span className="rg-label">클래스</span>
                  <span className="rg-value"><strong>{target.name}</strong></span>
                </div>
                <div className="reassign-row">
                  <span className="rg-label">현재 담당</span>
                  <span className="rg-value">{target.teacher_id || '—'}</span>
                </div>
              </div>
            )}

            <div className="form-row" style={{marginTop: 16}}>
              <label>새 담당 강사 <span className="required">*</span></label>
              <select value={selectedTeacherId} onChange={e => setSelectedTeacherId(e.target.value)}>
                <option value="">선택하세요</option>
                {teachers.map(t => (
                  <option key={t.id} value={t.id}>
                    {t.name} ({ROLE_LABEL[t.role_id] || '직원'})
                  </option>
                ))}
              </select>
              {teachers.length === 0 && (
                <span className="help-text">활성 강사가 없습니다.</span>
              )}
            </div>

            {/* hotfix18: 새 강의 드롭다운 (강사 선택 후 활성). 학년 매칭/요일/시간/정원 정렬. */}
            {mode === 'student' && (
              <div className="form-row">
                <label>새 강의 <span className="required">*</span></label>
                <select
                  value={selectedClassId}
                  onChange={e => setSelectedClassId(e.target.value)}
                  disabled={!selectedTeacherId || classOptions.length === 0}
                >
                  <option value="">
                    {!selectedTeacherId
                      ? '강사를 먼저 선택하세요'
                      : classOptions.length === 0
                        ? '⚠ 이 강사는 담당 강의가 없습니다'
                        : '선택하세요'}
                  </option>
                  {classOptions.map(opt => {
                    const prefix = !opt.gradeMatch ? '[⚠ 학년 다름] ' : '';
                    const suffix = opt.isFull ? ' [정원 초과]' : '';
                    return (
                      <option key={opt.cls.id} value={opt.cls.id} disabled={opt.isFull}>
                        {prefix + opt.cls.name + ' · ' + _formatClassSchedule(opt.cls) + suffix}
                      </option>
                    );
                  })}
                </select>
                {selectedTeacherId && classOptions.length === 0 && (
                  <span className="help-text" style={{color: 'var(--danger, #DC2626)'}}>
                    이 강사는 담당 강의가 없습니다. 다른 강사를 선택하세요.
                  </span>
                )}
              </div>
            )}

            <div className="form-row">
              <label>변경 사유</label>
              <select value={reason} onChange={e => setReason(e.target.value)}>
                {REASON_OPTS.map(([v, l]) => <option key={v} value={v}>{l}</option>)}
              </select>
            </div>

            {error && <div className="error-message">{error}</div>}
          </div>
          <div className="modal-footer">
            <button className="btn-secondary" onClick={() => onClose(false)} disabled={processing}>취소</button>
            <button
              className="btn-primary"
              onClick={onSave}
              disabled={processing || !selectedTeacherId || (mode === 'student' && !selectedClassId)}
            >
              {processing ? '처리 중…' : '재배정'}
            </button>
          </div>
        </React.Fragment>
      </_MainShell>
    );
  }

  /* 전역 진입점 — TopBar 알림 / 학생 목록 배지 / 학생 상세 등에서 호출.
     hotfix16.7: pending 큐 + auto-replay — Mount 가 아직 listener 등록 안 됐어도
     첫 호출이 유실되지 않음 (Bug 1 intermittent 첫 클릭 무반응 해소). */
  if (!window.__c200ReassignPending) window.__c200ReassignPending = [];
  if (!window.__c200ReassignListenerCount) window.__c200ReassignListenerCount = 0;

  window.openReassignModal = function (targetId, mode) {
    const detail = { mode: mode || 'student', targetId: targetId };
    if (window.__c200ReassignListenerCount > 0) {
      window.dispatchEvent(new CustomEvent('c200-open-reassign-modal', { detail }));
    } else {
      /* Mount 미준비 — 큐에 쌓고 Mount 가 등록 시 즉시 처리 */
      window.__c200ReassignPending.push(detail);
    }
  };

  /* 글로벌 마운트 — admin 페이지 어디든 한 번 마운트하면 어디서든 openReassignModal 호출 가능 */
  function GlobalReassignModalMount() {
    const [state, setState] = useState(null);
    useEffect(() => {
      function onOpen(e) { setState(e.detail); }
      window.addEventListener('c200-open-reassign-modal', onOpen);
      window.__c200ReassignListenerCount++;
      /* pending 큐 flush — listener 등록 직전 호출됐던 openReassignModal 처리 */
      if (Array.isArray(window.__c200ReassignPending) && window.__c200ReassignPending.length > 0) {
        const queued = window.__c200ReassignPending.shift();
        if (queued) setState(queued);
        window.__c200ReassignPending = [];
      }
      return () => {
        window.removeEventListener('c200-open-reassign-modal', onOpen);
        window.__c200ReassignListenerCount = Math.max(0, window.__c200ReassignListenerCount - 1);
      };
    }, []);
    if (!state) return null;
    return (
      <StudentReassignModal
        mode={state.mode}
        targetId={state.targetId}
        onClose={() => setState(null)}
        onSuccess={() => {
          /* 페이지 별 갱신 훅 */
          if (typeof window.reloadStudentsList === 'function') window.reloadStudentsList();
          window.dispatchEvent(new CustomEvent('c200-students-reassigned'));
        }}
      />
    );
  }

  window.StudentReassignModal = StudentReassignModal;
  window.GlobalReassignModalMount = GlobalReassignModalMount;
})();
