// 이 파일이 하는 일: (멘토 전용) 학생별 코스 진도 현황을 보고,
// 학생들의 전체 제출물을 테이블로 확인해 피드백을 남긴다.
import { useEffect, useState } from 'react';
import client from '../api/client';
import MentorCodingSection from '../components/MentorCodingSection';
import Card from '../components/Card';
import Badge from '../components/Badge';
import { COURSE_CATEGORIES, ALL_COURSES } from '../courseCatalog';

// 학생 한 명의 진도 카드.
// 학습 포인트: 서버는 "완료한 slug 목록"만 주고, 전체 코스 수·카테고리별 집계는
// 프론트가 카탈로그(courseCatalog)로 계산한다 — 데이터의 주인이 각자 다르다.
function StudentProgressCard({ student }) {
  const done = new Set(student.completedSlugs);
  const total = ALL_COURSES.length;
  const doneCount = ALL_COURSES.filter((c) => done.has(c.slug)).length;
  const percent = total === 0 ? 0 : Math.round((doneCount / total) * 100);

  // 비밀번호 재설정 폼 상태 — 학생이 비밀번호를 잊었을 때 멘토가 대신 바꿔 준다.
  const [resetOpen, setResetOpen] = useState(false);
  const [newPassword, setNewPassword] = useState('');
  const [resetMessage, setResetMessage] = useState('');
  const [resetError, setResetError] = useState('');
  const [resetting, setResetting] = useState(false);

  async function resetPassword(e) {
    e.preventDefault();
    setResetError('');
    setResetMessage('');
    if (newPassword.length < 8) {
      setResetError('8자 이상으로 정해 주세요.');
      return;
    }
    setResetting(true);
    try {
      await client.post(`/mentor/users/${student.userId}/reset-password`, { newPassword });
      setResetMessage(`재설정 완료 — 학생에게 직접 알려주고, 로그인 후 바꾸게 하세요.`);
      setNewPassword('');
    } catch {
      setResetError('재설정 중 문제가 생겼어요.');
    } finally {
      setResetting(false);
    }
  }

  return (
    <div className="card" style={{ height: '100%' }}>
      <div className="assign-title-row">
        <span className="assign-title">{student.name}</span>
        <span className="badge badge-primary">
          {student.track === 'DESIGN' ? '디자인' : '개발'}
        </span>
        <span className="muted" style={{ fontSize: 12.5 }}>@{student.username}</span>
      </div>
      <div className="stat-row" style={{ margin: '10px 0 12px' }}>
        <div className="stat">
          <span className="stat-num" style={{ fontSize: 26 }}>{percent}%</span>
          <span className="stat-label">{doneCount} / {total} 코스</span>
        </div>
        <div className="progress-track" style={{ flex: 1, minWidth: 100 }}>
          <div className="progress-fill" style={{ width: `${percent}%` }} />
        </div>
      </div>
      {/* 카테고리별 완료 수 — 어느 영역을 파고 있는지 한눈에 */}
      <div className="chip-row" style={{ marginTop: 0 }}>
        {COURSE_CATEGORIES.map((group) => {
          const groupDone = group.items.filter((i) => i.slug && done.has(i.slug)).length;
          return (
            <span
              key={group.category}
              className="chip"
              style={groupDone > 0 ? { color: 'var(--teal)', fontWeight: 700 } : undefined}
            >
              {group.category} {groupDone}/{group.items.length}
            </span>
          );
        })}
      </div>

      {/* 비밀번호 재설정 — 학생이 비밀번호를 잊었을 때 멘토가 처리하는 창구.
          학습 포인트: 이 기능은 원래 "아이디+이름만 알면 누구나" 쓸 수 있는 무인증 API였다.
          보안 검토에서 계정 탈취 경로로 확인되어, 멘토 권한 뒤로 옮겼다.
          본인 확인은 "학생 얼굴을 보고 확인한다"는 오프라인 절차가 대신한다. */}
      <div style={{ marginTop: 12, borderTop: '1px solid var(--line)', paddingTop: 10 }}>
        {!resetOpen ? (
          <button
            className="btn btn-ghost"
            style={{ fontSize: 13, padding: '4px 0' }}
            onClick={() => setResetOpen(true)}
          >
            🔑 비밀번호 재설정
          </button>
        ) : (
          <form onSubmit={resetPassword}>
            <div style={{ display: 'flex', gap: 6 }}>
              <input
                className="input"
                type="text"
                value={newPassword}
                onChange={(e) => setNewPassword(e.target.value)}
                placeholder="새 비밀번호 (8자 이상)"
                style={{ fontSize: 13 }}
              />
              <button className="btn btn-primary" type="submit" disabled={resetting}>
                {resetting ? '...' : '설정'}
              </button>
              <button className="btn btn-ghost" type="button" onClick={() => setResetOpen(false)}>
                취소
              </button>
            </div>
            {resetError && <p className="error-text" style={{ fontSize: 12.5 }}>{resetError}</p>}
            {resetMessage && (
              <p style={{ color: 'var(--teal)', fontSize: 12.5, marginTop: 6 }}>{resetMessage}</p>
            )}
          </form>
        )}
      </div>
    </div>
  );
}

// 주차별 체크리스트 진도 표.
// 학습 포인트: 서버가 분모(totalByWeek)와 분자(학생별 doneByWeek)를 나눠서 주면,
// 프론트는 표로 배치만 한다. 셀 색은 완료율에 따라 3단계(0 / 진행 중 / 완주)로 표현 —
// 숫자를 읽기 전에 색으로 먼저 상황이 보이게 하는 것이 정보 디자인이다.
function WeeklyChecklistTable({ overview }) {
  // 주차 목록은 분모(totalByWeek)의 키에서 뽑는다. JSON을 거치면 키가 문자열이 되므로
  // 숫자로 되돌려 정렬한다. (학습 포인트: JSON 객체의 키는 항상 문자열!)
  const weeks = Object.keys(overview.totalByWeek)
    .map(Number)
    .sort((a, b) => a - b);

  function cellStyle(done, total) {
    if (total === 0 || done === 0) return { color: 'var(--muted)' };
    if (done >= total) return { color: 'var(--teal)', fontWeight: 800 };
    return { color: 'var(--primary)', fontWeight: 700 };
  }

  return (
    <Card style={{ padding: 0, overflowX: 'auto' }}>
      {/* table--nowrap: 인적사항 표는 셀이 세로로 꺾이면 못 읽는다 — 가로 스크롤로 본다 */}
      <table className="table table-static table--nowrap" style={{ minWidth: 640 }}>
        <thead>
          <tr>
            <th>학생</th>
            {weeks.map((w) => (
              <th key={w} style={{ textAlign: 'center' }}>{w}주차</th>
            ))}
            <th style={{ textAlign: 'center' }}>전체</th>
          </tr>
        </thead>
        <tbody>
          {overview.students.map((student) => {
            let doneSum = 0;
            let totalSum = 0;
            return (
              <tr key={student.userId}>
                <td style={{ fontWeight: 600, whiteSpace: 'nowrap' }}>
                  {student.name}
                  <span className="muted" style={{ fontSize: 12, marginLeft: 6 }}>
                    {student.track === 'DESIGN' ? '디자인' : '개발'}
                  </span>
                </td>
                {weeks.map((w) => {
                  const total = overview.totalByWeek[w] ?? 0;
                  const done = student.doneByWeek[w] ?? 0; // 체크 없는 주차는 키가 없어 0 처리
                  doneSum += done;
                  totalSum += total;
                  return (
                    <td
                      key={w}
                      style={{ textAlign: 'center', fontVariantNumeric: 'tabular-nums', ...cellStyle(done, total) }}
                    >
                      {done}/{total}
                    </td>
                  );
                })}
                <td
                  style={{ textAlign: 'center', fontVariantNumeric: 'tabular-nums', ...cellStyle(doneSum, totalSum) }}
                >
                  {doneSum}/{totalSum}
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </Card>
  );
}

// 수습생 인적사항 명단 — 경리 담당자가 CSV로 내려받을 수 있다.
// 학습 포인트: 개인정보 화면이라 링크가 아니라 표로, 다운로드는 버튼 하나로 명확히 둔다.
function StudentRoster({ students }) {
  // 학습 포인트: 파일 다운로드는 axios(JSON) 말고 브라우저의 링크 이동으로 처리한다.
  // withCredentials 링크 이동이면 세션 쿠키도 함께 가서, 서버가 멘토인지 확인할 수 있다.
  const csvUrl = '/api/mentor/students/export.csv';

  return (
    <Card style={{ padding: 0, overflowX: 'auto' }}>
      <div style={{ padding: '12px 16px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12 }}>
        <span className="muted" style={{ fontSize: 13 }}>
          총 {students.length}명 · 개인정보이니 취급에 주의하세요
        </span>
        <a href={csvUrl} className="btn btn-primary" style={{ fontSize: 13 }}>
          ⬇ CSV 내려받기 (경리용)
        </a>
      </div>
      {/* table--nowrap: "트랙"→"트/랙"처럼 셀이 세로로 꺾이지 않게. 가로 스크롤로 본다 */}
      <table className="table table-static table--nowrap" style={{ minWidth: 720 }}>
        <thead>
          <tr>
            <th>이름</th>
            <th>회사 이메일</th>
            <th>트랙</th>
            <th>생년월일</th>
            <th>연락처</th>
            <th>학교</th>
            <th>비상 연락</th>
          </tr>
        </thead>
        <tbody>
          {students.map((s) => (
            <tr key={s.userId}>
              <td style={{ fontWeight: 600, whiteSpace: 'nowrap' }}>{s.name}</td>
              <td style={{ whiteSpace: 'nowrap' }}>{s.companyEmail}</td>
              <td>{s.track === 'DESIGN' ? '디자인' : '개발'}</td>
              <td style={{ whiteSpace: 'nowrap' }}>{s.birthDate}</td>
              <td style={{ whiteSpace: 'nowrap' }}>{s.phone}</td>
              <td style={{ whiteSpace: 'nowrap' }}>{s.school}</td>
              <td style={{ whiteSpace: 'nowrap' }} className="muted">
                {s.emergencyName}({s.emergencyRelation}) {s.emergencyPhone}
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </Card>
  );
}

// 학생별 퀴즈 성적 요약 표.
// 학습 포인트: 서버는 코스별 최고점 목록만 주고, 응시 수·평균·만점 수 집계는 프론트가 한다.
function QuizResultsTable({ quizResults }) {
  return (
    <Card style={{ padding: 0, overflowX: 'auto' }}>
      <table className="table table-static table--nowrap" style={{ minWidth: 480 }}>
        <thead>
          <tr>
            <th>학생</th>
            <th style={{ textAlign: 'center' }}>응시 코스</th>
            <th style={{ textAlign: 'center' }}>평균 점수</th>
            <th style={{ textAlign: 'center' }}>만점 코스</th>
          </tr>
        </thead>
        <tbody>
          {quizResults.map((student) => {
            const taken = student.results.length;
            const perfect = student.results.filter((r) => r.bestScore === r.total).length;
            // 평균은 백분율로 — 코스마다 문항 수가 다를 수 있어 점수 합산보다 공정하다
            const avg =
              taken === 0
                ? null
                : Math.round(
                    (student.results.reduce((sum, r) => sum + r.bestScore / r.total, 0) / taken) * 100,
                  );
            return (
              <tr key={student.userId}>
                <td style={{ fontWeight: 600, whiteSpace: 'nowrap' }}>
                  {student.name}
                  <span className="muted" style={{ fontSize: 12, marginLeft: 6 }}>
                    {student.track === 'DESIGN' ? '디자인' : '개발'}
                  </span>
                </td>
                <td style={{ textAlign: 'center', fontVariantNumeric: 'tabular-nums' }}>{taken}</td>
                <td
                  style={{
                    textAlign: 'center',
                    fontVariantNumeric: 'tabular-nums',
                    fontWeight: 700,
                    color: avg === null ? 'var(--muted)' : avg >= 80 ? 'var(--teal)' : 'var(--primary)',
                  }}
                >
                  {avg === null ? '—' : `${avg}점`}
                </td>
                <td style={{ textAlign: 'center', fontVariantNumeric: 'tabular-nums' }}>{perfect}</td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </Card>
  );
}

export default function MentorPage() {
  const [submissions, setSubmissions] = useState([]);
  const [students, setStudents] = useState([]); // 학생별 코스 진도
  const [checklistOverview, setChecklistOverview] = useState(null); // 주차별 체크리스트 진도
  const [quizResults, setQuizResults] = useState([]); // 학생별 퀴즈 성적
  const [roster, setRoster] = useState([]); // 수습생 인적사항 명단
  const [loadError, setLoadError] = useState(false); // 일부 데이터 로딩 실패 여부
  const [loading, setLoading] = useState(true);
  const [selectedId, setSelectedId] = useState(null); // 클릭해서 펼친 제출물 id
  const [feedbackDraft, setFeedbackDraft] = useState('');
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState('');

  function load() {
    // 제출물·코스 진도·체크리스트 진도를 함께 불러온다.
    // 학습 포인트: Promise.all은 하나만 실패해도 전체가 실패해서, 잘 되던 섹션까지
    // 빈 화면이 된다. allSettled는 "각자 결과를 따로" 주므로 성공한 섹션은 그대로
    // 보여주고, 실패가 있으면 에러 배너만 띄울 수 있다. (리뷰에서 잡힌 개선점!)
    return Promise.allSettled([
      client.get('/mentor/submissions'),
      client.get('/mentor/course-progress'),
      client.get('/mentor/checklist-progress'),
      client.get('/mentor/quiz-results'),
      client.get('/mentor/students'),
    ])
      .then(([subsRes, progressRes, checklistRes, quizRes, rosterRes]) => {
        if (subsRes.status === 'fulfilled') setSubmissions(subsRes.value.data);
        if (progressRes.status === 'fulfilled') setStudents(progressRes.value.data);
        if (checklistRes.status === 'fulfilled') setChecklistOverview(checklistRes.value.data);
        if (quizRes.status === 'fulfilled') setQuizResults(quizRes.value.data);
        if (rosterRes.status === 'fulfilled') setRoster(rosterRes.value.data);
        const anyFailed = [subsRes, progressRes, checklistRes, quizRes, rosterRes].some(
          (r) => r.status === 'rejected',
        );
        setLoadError(anyFailed);
      })
      .finally(() => setLoading(false));
  }

  useEffect(() => {
    load();
  }, []);

  const selected = submissions.find((s) => s.id === selectedId) || null;

  function selectRow(submission) {
    // 같은 행을 다시 누르면 닫는다.
    if (selectedId === submission.id) {
      setSelectedId(null);
      return;
    }
    setSelectedId(submission.id);
    // 기존 피드백이 있으면 이어서 수정할 수 있게 미리 채운다.
    setFeedbackDraft(submission.feedback || '');
    setError('');
  }

  async function saveFeedback(e) {
    e.preventDefault();
    if (!feedbackDraft.trim()) {
      setError('피드백 내용을 적어 주세요.');
      return;
    }
    setSaving(true);
    setError('');
    try {
      await client.post(`/mentor/submissions/${selectedId}/feedback`, {
        feedback: feedbackDraft,
      });
      // 저장 후 목록을 다시 불러와 상태(REVIEWED)를 화면에 반영한다.
      await load();
    } catch {
      setError('피드백 저장 중 문제가 생겼어요. 다시 시도해 주세요.');
    } finally {
      setSaving(false);
    }
  }

  if (loading) {
    return <p className="empty">불러오는 중...</p>;
  }

  return (
    <div>
      <h1 className="page-title">멘토 리뷰</h1>
      <p className="page-desc">
        학생별 학습 진도를 확인하고, 제출물에 피드백을 남기세요.
      </p>

      {/* 일부 데이터 로딩 실패 시 — 빈 상태 문구와 구분되는 에러 안내 */}
      {loadError && (
        <p className="error-text" style={{ marginBottom: 14 }}>
          일부 데이터를 불러오지 못했어요. 잠시 후 새로고침해 주세요.
        </p>
      )}

      {/* ── 수습생 명단 (인적사항) ── */}
      <h2 className="section-title">수습생 명단</h2>
      {roster.length === 0 ? (
        <p className="empty">아직 가입한 수습생이 없어요. (학생이 회원가입하면 여기에 표시됩니다)</p>
      ) : (
        <StudentRoster students={roster} />
      )}

      {/* ── 학생별 코스 진도 ── */}
      <h2 className="section-title" style={{ marginTop: 24 }}>학생별 코스 진도</h2>
      {students.length === 0 ? (
        <p className="empty">아직 학생 계정이 없어요.</p>
      ) : (
        <div className="grid-cards" style={{ marginBottom: 24 }}>
          {students.map((student) => (
            <StudentProgressCard key={student.userId} student={student} />
          ))}
        </div>
      )}

      {/* ── 주차별 체크리스트 진도 ── */}
      <h2 className="section-title">주차별 체크리스트 진도</h2>
      {!checklistOverview || checklistOverview.students.length === 0 ? (
        <p className="empty">아직 학생 계정이 없어요.</p>
      ) : Object.keys(checklistOverview.totalByWeek).length === 0 ? (
        // 시드가 안 들어간 경우 — "아무도 안 했다"와 "항목이 없다"는 다른 상황이다
        <p className="empty">등록된 체크리스트 항목이 없어요.</p>
      ) : (
        <WeeklyChecklistTable overview={checklistOverview} />
      )}

      {/* ── 퀴즈 성적 ── */}
      <h2 className="section-title" style={{ marginTop: 24 }}>퀴즈 성적</h2>
      {quizResults.length === 0 ? (
        <p className="empty">아직 학생 계정이 없어요.</p>
      ) : (
        <QuizResultsTable quizResults={quizResults} />
      )}

      {/* ── 코딩 문제 (진도표 + 제출된 코드 리뷰) ── */}
      <MentorCodingSection />

      {/* ── 제출물 리뷰 ── */}
      <h2 className="section-title" style={{ marginTop: 24 }}>제출물</h2>
      {submissions.length === 0 ? (
        <p className="empty">아직 제출물이 없어요.</p>
      ) : (
        <Card style={{ padding: 0, overflow: 'hidden' }}>
          <table className="table">
            <thead>
              <tr>
                <th>학생</th>
                <th>과제</th>
                <th>제출 시각</th>
                <th>상태</th>
              </tr>
            </thead>
            <tbody>
              {submissions.map((submission) => (
                <tr key={submission.id} onClick={() => selectRow(submission)}>
                  <td style={{ fontWeight: 600 }}>{submission.studentName}</td>
                  <td>{submission.assignmentTitle}</td>
                  <td className="muted">
                    {new Date(submission.submittedAt).toLocaleString('ko-KR')}
                  </td>
                  <td>
                    <Badge value={submission.status} />
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </Card>
      )}

      {/* 학습 포인트: 모달 라이브러리 없이도, 선택된 행의 상세를
          테이블 아래 카드로 펼치는 방식이면 충분히 쓸 만하다. */}
      {selected && (
        <Card style={{ marginTop: 14 }}>
          <div style={{ display: 'flex', gap: 8, alignItems: 'center', marginBottom: 10 }}>
            <strong>{selected.studentName}</strong>
            <span className="muted">—</span>
            <span>{selected.assignmentTitle}</span>
            <Badge value={selected.status} />
          </div>

          <div className="field">
            <label>제출 내용</label>
            <div
              style={{
                background: 'var(--bg)',
                border: '1px solid var(--line)',
                borderRadius: 10,
                padding: '10px 14px',
                whiteSpace: 'pre-line',
              }}
            >
              {selected.content}
            </div>
          </div>

          {selected.link && (
            <div className="field">
              <label>제출 링크</label>
              <a href={selected.link} target="_blank" rel="noreferrer">
                {selected.link}
              </a>
            </div>
          )}

          <form onSubmit={saveFeedback}>
            <div className="field">
              <label>피드백</label>
              <textarea
                className="textarea"
                value={feedbackDraft}
                onChange={(e) => setFeedbackDraft(e.target.value)}
                placeholder="잘한 점과 다음에 시도해 볼 점을 구체적으로 적어 주세요."
              />
            </div>
            {error && <p className="error-text">{error}</p>}
            <button className="btn btn-primary" type="submit" disabled={saving}>
              {saving ? '저장 중...' : '피드백 저장'}
            </button>
            <button
              className="btn btn-ghost"
              type="button"
              onClick={() => setSelectedId(null)}
              style={{ marginLeft: 8 }}
            >
              닫기
            </button>
          </form>
        </Card>
      )}
    </div>
  );
}
