// 이 파일이 하는 일: 주차(1~8) 탭을 고르면 그 주의 체크리스트를 보여주고,
// 체크박스를 누르면 서버에 진행 상황을 저장한다. 상단에 진행률을 크게 보여주고,
// 학습 센터 코스 진도 요약 위젯도 함께 보여준다.
import { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import { Award, BookA, BookOpen, Compass, Palette, PartyPopper } from 'lucide-react';
import client from '../api/client';
import { useAuth } from '../AuthContext';
import Card from '../components/Card';
import { COURSE_CATEGORIES, ALL_COURSES } from '../courseCatalog';

// 학습 센터 진도 요약 위젯.
// 학습 포인트: 멘토 페이지의 StudentProgressCard와 같은 계산을 "내 데이터"로 한다.
// 같은 로직이 세 번째로 필요해지면 공용 컴포넌트로 뽑을 때다 (지금은 두 번이라 참는다 —
// 성급한 추상화보다 한 번의 중복이 낫다는 "Rule of Three").
function CourseProgressWidget() {
  const [completedSlugs, setCompletedSlugs] = useState(new Set());
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    let cancelled = false;
    client
      .get('/course-progress/me')
      .then((res) => {
        if (!cancelled) setCompletedSlugs(new Set(res.data));
      })
      .finally(() => {
        if (!cancelled) setLoading(false);
      });
    return () => {
      cancelled = true;
    };
  }, []);

  const total = ALL_COURSES.length;
  const doneCount = ALL_COURSES.filter((c) => completedSlugs.has(c.slug)).length;
  const percent = total === 0 ? 0 : Math.round((doneCount / total) * 100);

  // "다음에 들을 강좌" — 카탈로그 순서상 아직 완료 안 한 첫 강좌.
  // 학습 포인트: 83강좌 앞에서 "그래서 뭘 먼저?"를 없애 주는 나침반이다.
  // (external 링크나 slug 없는 항목은 건너뛴다.)
  const nextCourse = ALL_COURSES.find((c) => c.slug && !completedSlugs.has(c.slug));

  if (loading) return null; // 로딩 중엔 위젯 자리를 비워 화면 덜컹임을 줄인다

  return (
    <Card style={{ marginBottom: 16 }}>
      <div className="assign-title-row" style={{ marginBottom: 10 }}>
        <span className="assign-title" style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
          <BookOpen size={18} strokeWidth={1.5} aria-hidden="true" /> 학습 센터 진도
        </span>
        <Link to="/learn" className="btn btn-ghost" style={{ marginLeft: 'auto', fontSize: 13 }}>
          학습 센터로 →
        </Link>
      </div>
      <div className="stat-row" style={{ marginBottom: 12 }}>
        <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: 120 }}>
          <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 && completedSlugs.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>

      {/* 다음에 들을 강좌 안내 — 길 잃지 않게 다음 한 걸음을 짚어 준다 */}
      {nextCourse ? (
        <Link
          to={`/learn/${nextCourse.slug}`}
          style={{ color: 'inherit', textDecoration: 'none' }}
        >
          <div
            style={{
              marginTop: 14, padding: '10px 14px', borderRadius: 10,
              background: 'var(--primary-soft)', display: 'flex', alignItems: 'center', gap: 10,
            }}
          >
            <nextCourse.Icon size={22} strokeWidth={1.5} aria-hidden="true" />
            <div style={{ minWidth: 0 }}>
              <div style={{ fontSize: 12, fontWeight: 700, color: 'var(--primary)', display: 'flex', alignItems: 'center', gap: 4 }}>
                다음에 들을 강좌 <Compass size={13} strokeWidth={1.5} aria-hidden="true" />
              </div>
              <div style={{ fontWeight: 700 }}>{nextCourse.title}</div>
            </div>
            <span style={{ marginLeft: 'auto', color: 'var(--primary)', fontWeight: 700 }}>→</span>
          </div>
        </Link>
      ) : (
        <p style={{ marginTop: 14, marginBottom: 0, color: 'var(--teal)', fontWeight: 700, display: 'flex', alignItems: 'center', gap: 6 }}>
          <PartyPopper size={18} strokeWidth={1.5} aria-hidden="true" /> 모든 강좌를 완료했어요! 대단합니다.
        </p>
      )}
    </Card>
  );
}

const WEEKS = [1, 2, 3, 4, 5, 6, 7, 8];

// 진행률(%)에 따라 다른 응원 문구를 고른다.
// 학습 포인트: 이런 "표시용 계산"은 컴포넌트 밖 순수 함수로 빼두면 테스트하기 쉽다.
function cheerMessage(percent) {
  if (percent === 100) return '이번 주 완주! 정말 수고했어요 🎉';
  if (percent >= 70) return '거의 다 왔어요, 조금만 더!';
  if (percent >= 30) return '좋은 흐름이에요. 이대로 쭉!';
  if (percent > 0) return '시작이 반이에요. 하나씩 채워봐요.';
  return '이번 주 첫 체크를 눌러볼까요?';
}

export default function DashboardPage() {
  const { user } = useAuth();
  const [week, setWeek] = useState(1);
  const [items, setItems] = useState([]); // 이번 주 체크리스트 항목
  const [checkedIds, setCheckedIds] = useState(new Set()); // 내가 체크한 항목 id들
  const [loading, setLoading] = useState(true);
  const [toggleError, setToggleError] = useState(''); // 체크 저장 실패 안내
  const [docs, setDocs] = useState([]); // 학습 문서 목록(주차별 과제집 연결용)

  // 학습 포인트: week가 바뀔 때마다 useEffect가 다시 실행된다 (의존성 배열 [week]).
  // 체크리스트와 내 진행 상황을 함께 불러온다.
  useEffect(() => {
    let cancelled = false;
    setLoading(true);
    Promise.all([
      client.get('/checklist', { params: { week } }),
      client.get('/progress/me'),
    ])
      .then(([itemsRes, progressRes]) => {
        if (cancelled) return;
        setItems(itemsRes.data);
        // 학습 포인트: 배열보다 Set이 "포함 여부 확인(has)"이 빠르고 코드도 깔끔하다.
        setCheckedIds(new Set(progressRes.data));
      })
      .finally(() => {
        if (!cancelled) setLoading(false);
      });
    return () => {
      // 학습 포인트: 탭을 빠르게 연달아 누르면 이전 요청의 응답이
      // 나중에 도착해 화면을 덮어쓸 수 있다. cancelled 플래그로 무시한다.
      cancelled = true;
    };
  }, [week]);

  // 학습 문서 목록을 한 번 불러온다 — 대시보드에서 이 주차 학습 문서로 바로 잇기 위해.
  useEffect(() => {
    client.get('/documents').then((res) => setDocs(res.data)).catch(() => {});
  }, []);

  async function toggle(itemId) {
    // 서버에 토글을 요청하고, 서버가 알려준 최종 상태(checked)로 화면을 맞춘다.
    // 학습 포인트: 저장이 실패하면(오프라인·세션만료·500) 조용히 넘어가면 학생은 "체크를
    // 눌렀는데 아무 반응 없음"을 겪는다. 실패를 잡아 사용자에게 알린다.
    setToggleError('');
    try {
      const res = await client.post(`/progress/${itemId}/toggle`);
      setCheckedIds((prev) => {
        const next = new Set(prev);
        if (res.data.checked) {
          next.add(itemId);
        } else {
          next.delete(itemId);
        }
        return next;
      });
    } catch {
      setToggleError('저장 중 문제가 생겼어요. 잠시 후 다시 시도해 주세요.');
    }
  }

  const doneCount = items.filter((item) => checkedIds.has(item.id)).length;
  const percent = items.length === 0 ? 0 : Math.round((doneCount / items.length) * 100);

  // 이 주차 학습 문서(주차별 과제집). 대시보드에서 "무엇부터 볼지"를 잇는 고리.
  const weekDocs = docs.filter((d) => d.week === week);

  // day별로 묶어서 보여준다 (day가 null인 항목은 "주간 공통"으로).
  const groups = new Map();
  for (const item of items) {
    const key = item.day == null ? '주간 공통' : `${item.day}일차`;
    if (!groups.has(key)) groups.set(key, []);
    groups.get(key).push(item);
  }

  return (
    <div>
      {/* 히어로: 인사 + 이번 주 진행률을 한눈에 */}
      <div className="hero compact">
        <div className="eyebrow">Dashboard</div>
        <h1>
          {user?.name}님, {week}주차 진행 상황이에요
        </h1>
        <p>{cheerMessage(percent)}</p>
        <div className="chip-row" style={{ alignItems: 'center' }}>
          <div className="stat">
            <span className="stat-num">{percent}%</span>
            <span className="stat-label">
              {doneCount} / {items.length} 완료
            </span>
          </div>
          <div className="progress-track" style={{ flex: 1, minWidth: 160 }}>
            <div className="progress-fill" style={{ width: `${percent}%` }} />
          </div>
        </div>
        {/* 회사 한 줄 소개 — 매일 보는 첫 화면에서 우리가 어떤 회사인지 잊지 않게 */}
        <p className="muted" style={{ fontSize: 13, marginTop: 14, marginBottom: 0 }}>
          ㈜어썸데브 — 고객과 함께 더 나은 세상을 만들어 나가는 기업
        </p>
      </div>

      {/* 학습 센터 코스 진도 요약 */}
      <CourseProgressWidget />

      {/* 빠른 이동 — 자주 찾는 곳을 카드로. */}
      <div className="grid-cards" style={{ gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', marginBottom: 16 }}>
        <Link to="/glossary" style={{ color: 'inherit' }}>
          <div className="card card-clickable" style={{ height: '100%' }}>
            <BookA size={24} strokeWidth={1.5} aria-hidden="true" style={{ marginBottom: 6 }} />
            <div style={{ fontWeight: 700 }}>개발 용어 사전</div>
            <p className="muted" style={{ fontSize: 13, marginTop: 4 }}>모르는 용어가 나오면 여기서 검색하세요.</p>
          </div>
        </Link>
        <Link to="/certificate" style={{ color: 'inherit' }}>
          <div className="card card-clickable" style={{ height: '100%' }}>
            <Award size={24} strokeWidth={1.5} aria-hidden="true" style={{ marginBottom: 6 }} />
            <div style={{ fontWeight: 700 }}>내 학습 증명서</div>
            <p className="muted" style={{ fontSize: 13, marginTop: 4 }}>지금까지의 성취를 증명서로 — 인쇄·PDF 저장.</p>
          </div>
        </Link>
        <Link to="/design" style={{ color: 'inherit' }}>
          <div className="card card-clickable" style={{ height: '100%' }}>
            <Palette size={24} strokeWidth={1.5} aria-hidden="true" style={{ marginBottom: 6 }} />
            <div style={{ fontWeight: 700 }}>디자인 재료 모음</div>
            <p className="muted" style={{ fontSize: 13, marginTop: 4 }}>색·글자·여백 토큰과 아이콘을 골라 쓰는 곳.</p>
          </div>
        </Link>
      </div>

      <div className="tabs">
        {WEEKS.map((w) => (
          <button
            key={w}
            className={`tab${w === week ? ' active' : ''}`}
            onClick={() => setWeek(w)}
          >
            {w}주차
          </button>
        ))}
      </div>

      {/* 이 주차 학습 문서로 가는 고리 — 대시보드를 "학습 허브"로. 문서 → 체크 흐름을 만든다. */}
      {weekDocs.length > 0 && (
        <div className="assignment-doc-links">
          {weekDocs.map((d) => (
            <Link key={d.slug} to={`/docs/${d.slug}`} className="card assignment-doc-link">
              <span className="assignment-doc-badge">📚 학습 문서</span>
              <span className="assignment-doc-title">{d.title}</span>
              <span className="assignment-doc-cta">체크 전에 먼저 읽어 보세요 →</span>
            </Link>
          ))}
        </div>
      )}

      {toggleError && (
        <p className="error-text" role="alert" style={{ marginBottom: 10 }}>{toggleError}</p>
      )}

      {loading ? (
        <p className="empty">불러오는 중...</p>
      ) : items.length === 0 ? (
        <Card>
          <p className="empty">
            이 주차에는 체크리스트가 없어요.
            <br />
            <span style={{ fontSize: 13 }}>궁금하면 멘토에게 물어보세요!</span>
          </p>
        </Card>
      ) : (
        [...groups.entries()].map(([groupName, groupItems]) => {
          const groupDone = groupItems.filter((i) => checkedIds.has(i.id)).length;
          return (
            <div key={groupName}>
              <div className="day-head">
                <span className="day-badge">{groupName}</span>
                <span className="day-count">
                  {groupDone} / {groupItems.length} 완료
                </span>
              </div>
              <Card style={{ padding: '8px 16px' }}>
                {groupItems.map((item) => {
                  const done = checkedIds.has(item.id);
                  return (
                    // 학습 포인트: label로 감싸면 글자를 눌러도 체크박스가 토글된다 (접근성).
                    <label key={item.id} className={`check-row${done ? ' done' : ''}`}>
                      <input
                        type="checkbox"
                        checked={done}
                        onChange={() => toggle(item.id)}
                      />
                      <span className="check-label">{item.label}</span>
                    </label>
                  );
                })}
              </Card>
            </div>
          );
        })
      )}
    </div>
  );
}
