// 이 파일이 하는 일: 주차(1~8) 탭을 고르면 그 주의 체크리스트를 보여주고,
// 체크박스를 누르면 서버에 진행 상황을 저장한다. 상단에 진행률을 크게 보여주고,
// 학습 센터 코스 진도 요약 위젯도 함께 보여준다.
import { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
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);

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

  return (
    <Card style={{ marginBottom: 16 }}>
      <div className="assign-title-row" style={{ marginBottom: 10 }}>
        <span className="assign-title">📚 학습 센터 진도</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>
    </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);

  // 학습 포인트: 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]);

  async function toggle(itemId) {
    // 서버에 토글을 요청하고, 서버가 알려준 최종 상태(checked)로 화면을 맞춘다.
    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;
    });
  }

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

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

      {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>
  );
}
