"use client";

import React from "react";
import useSWR, { useSWRConfig } from "swr";
import { useToast } from "@/app/components/ui/ToastProvider";

function getMonthRange(date: Date) {
  const y = date.getFullYear();
  const m = date.getMonth(); // 0-based
  const first = new Date(y, m, 1);
  const last = new Date(y, m + 1, 0);
  return { y, m, first, last };
}

export default function AttendanceCalendar({ isLoggedIn = true }: { isLoggedIn?: boolean }) {
  const [current, setCurrent] = React.useState(new Date());
  const [days, setDays] = React.useState<string[]>([]);
  const [todayChecked, setTodayChecked] = React.useState<boolean | null>(null);
  const [loading, setLoading] = React.useState(false);
  const [effectiveLoggedIn, setEffectiveLoggedIn] = React.useState<boolean>(!!isLoggedIn);
  const { show } = useToast();
  const { mutate } = useSWRConfig();

  const { y, m } = getMonthRange(current);
  const ymKey = `${y}-${String(m + 1).padStart(2, "0")}`;
  const today = React.useMemo(() => {
    const d = new Date();
    return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
  }, []);

  React.useEffect(() => {
    let cancelled = false;
    (async () => {
      if (!isLoggedIn) {
        setDays([]);
        setTodayChecked(null);
        setEffectiveLoggedIn(false);
        return;
      }
      setLoading(true);
      try {
        const res = await fetch(`/api/attendance?year=${y}&month=${m + 1}`, { cache: "no-store" });
        const data = await res.json().catch(() => ({}));
        if (!cancelled) {
          setDays(Array.isArray(data?.days) ? data.days : []);
          // today === null 이면 비로그인으로 판정
          const isAuthed = data?.today !== null && data?.today !== undefined;
          setEffectiveLoggedIn(isAuthed && !!isLoggedIn);
          setTodayChecked(isAuthed ? !!data?.today : null);
        }
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();
    return () => { cancelled = true; };
  }, [y, m, ymKey, isLoggedIn]);

  const goPrev = () => setCurrent(new Date(current.getFullYear(), current.getMonth() - 1, 1));
  const goNext = () => setCurrent(new Date(current.getFullYear(), current.getMonth() + 1, 1));

  const handleCheckIn = async () => {
    if (!effectiveLoggedIn) return;
    try {
      const res = await fetch("/api/attendance", { method: "POST" });
      const data = await res.json().catch(() => ({}));
      if (res.ok && !data?.duplicated) {
        const d = new Date();
        const s = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
        setDays((prev) => (prev.includes(s) ? prev : [...prev, s]));
        setTodayChecked(true);
        show("출석 완료");
      } else if (res.ok) {
        setTodayChecked(true);
        show("출석 완료");
      }
      // 출석 통계/랭킹 리셋(재검증)
      mutate("/api/attendance/me-stats");
      mutate("/api/attendance/rankings");
    } catch {
      // ignore
    }
  };

  // 캘린더 데이터 생성
  const firstOfMonth = new Date(y, m, 1);
  const startWeekday = firstOfMonth.getDay(); // 0:Sun
  const lastOfMonth = new Date(y, m + 1, 0).getDate();
  const weeks: Array<Array<{ d: number | null; dateStr?: string; checked?: boolean }>> = [];
  let day = 1;
  for (let w = 0; w < 6; w++) {
    const row: any[] = [];
    for (let wd = 0; wd < 7; wd++) {
      if (w === 0 && wd < startWeekday) {
        row.push({ d: null });
      } else if (day > lastOfMonth) {
        row.push({ d: null });
      } else {
        const dateStr = `${y}-${String(m + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
        row.push({ d: day, dateStr, checked: days.includes(dateStr) });
        day++;
      }
    }
    weeks.push(row);
    if (day > lastOfMonth) break;
  }

  return (
    <div className="w-full max-w-[520px] mx-auto bg-white rounded-xl border border-neutral-200 p-4">
      <div className="relative">
        <div className="flex items-center justify-between mb-3">
        <button onClick={goPrev} className="h-8 w-8 rounded-md border border-neutral-300 hover:bg-neutral-50">‹</button>
        <div className="text-sm font-semibold text-neutral-800">
          {y}년 {m + 1}월
        </div>
        <button onClick={goNext} className="h-8 w-8 rounded-md border border-neutral-300 hover:bg-neutral-50">›</button>
        </div>
        <table className="w-full text-center text-sm">
        <thead className="text-neutral-500">
          <tr>
            {["일","월","화","수","목","금","토"].map((h) => (<th key={h} className="py-1">{h}</th>))}
          </tr>
        </thead>
        <tbody>
          {weeks.map((row, i) => (
            <tr key={i}>
              {row.map((cell, j) => (
                <td key={`${i}-${j}`} className="h-9 align-middle">
                  {cell.d ? (
                    (() => {
                      const isToday = cell.dateStr === today;
                      const base = "mx-auto w-8 h-8 leading-8 rounded-full";
                      const color = cell.checked ? " bg-[#F94B37] text-white" : " text-neutral-700";
                      const ring = isToday ? (cell.checked ? " ring-2 ring-offset-2 ring-[#F94B37]" : " ring-2 ring-[#F94B37]") : "";
                      return (
                        <div className={`${base}${color}${ring}`}>
                          {cell.d}
                        </div>
                      );
                    })()
                  ) : (
                    <div className="w-7 h-7 mx-auto" />
                  )}
                </td>
              ))}
            </tr>
          ))}
        </tbody>
        </table>
        <div className="mt-2 flex items-center justify-center gap-3 text-[11px] text-neutral-600">
        <span className="inline-flex items-center gap-1">
          <span className="inline-block w-3 h-3 rounded-full bg-[#F94B37]" />
          출석일
        </span>
        <span className="inline-flex items-center gap-1">
          <span className="inline-block w-3 h-3 rounded-full ring-2 ring-[#F94B37]" />
          오늘
        </span>
        </div>
        <div className="mt-4 flex items-center justify-center">
        <button
          onClick={handleCheckIn}
            disabled={todayChecked === true || loading || !effectiveLoggedIn}
          className="h-9 px-4 rounded-md bg-neutral-900 text-white text-sm hover:bg-neutral-800 disabled:opacity-50"
        >
          {todayChecked ? "오늘 출석 완료" : "오늘 출석하기"}
        </button>
        </div>
        {/* 내 출석 통계 */}
        {effectiveLoggedIn && <MyAttendanceStats />}
        {!effectiveLoggedIn && (
          <div className="absolute inset-0 z-20 bg-white/70 backdrop-blur-[1px] rounded-lg flex items-center justify-center">
            <div className="text-sm font-semibold text-neutral-700">로그인이 필요합니다</div>
          </div>
        )}
      </div>
      <Rankings />
    </div>
  );
}

function MyAttendanceStats() {
  const { data } = useSWR<{ total: number; currentStreak: number; maxStreak: number }>(
    "/api/attendance/me-stats",
    (u) => fetch(u, { cache: "no-store" }).then((r) => r.json())
  );
  const total = data?.total ?? 0;
  const current = data?.currentStreak ?? 0;
  const max = data?.maxStreak ?? 0;
  return (
    <div className="mt-4 grid grid-cols-3 gap-2">
      <div className="rounded-lg border border-neutral-200 px-3 py-2 text-center">
        <div className="text-[11px] text-neutral-600">내 출석일수</div>
        <div className="text-lg font-semibold text-neutral-900">{total}</div>
      </div>
      <div className="rounded-lg border border-neutral-200 px-3 py-2 text-center">
        <div className="text-[11px] text-neutral-600">현재 연속출석</div>
        <div className="text-lg font-semibold text-neutral-900">{current}일</div>
      </div>
      <div className="rounded-lg border border-neutral-200 px-3 py-2 text-center">
        <div className="text-[11px] text-neutral-600">최대 연속</div>
        <div className="text-lg font-semibold text-neutral-900">{max}일</div>
      </div>
    </div>
  );
}

function Rankings() {
  const { data } = useSWR<{ overall?: any[]; streak: any[] }>(
    "/api/attendance/rankings",
    (u) => fetch(u, { cache: "no-store" }).then((r) => r.json())
  );
  const streak = data?.streak ?? [];
  const overall = data?.overall ?? [];
  return (
    <div className="mt-6 grid grid-cols-2 gap-4">
      <div className="rounded-lg border border-neutral-200">
        <div className="px-3 py-2 border-b border-neutral-200 text-sm font-semibold">최대 연속출석 순위</div>
        <ol className="p-3 space-y-2">
          {streak.length === 0 && <li className="text-xs text-neutral-500">데이터가 없습니다.</li>}
          {streak.map((u, idx) => (
            <li key={u.userId} className="flex items-center gap-3 text-sm">
              <span className="inline-flex items-center justify-center w-6 h-6 rounded-full bg-neutral-900 text-white text-xs">{idx + 1}</span>
              <span className="truncate">{u.nickname}</span>
              <span className="ml-auto text-xs text-neutral-600">{u.streak}일</span>
            </li>
          ))}
        </ol>
      </div>
      <div className="rounded-lg border border-neutral-200">
        <div className="px-3 py-2 border-b border-neutral-200 text-sm font-semibold">출석일 순위</div>
        <ol className="p-3 space-y-2">
          {overall.length === 0 && <li className="text-xs text-neutral-500">데이터가 없습니다.</li>}
          {overall.map((u, idx) => (
            <li key={u.userId} className="flex items-center gap-3 text-sm">
              <span className="inline-flex items-center justify-center w-6 h-6 rounded-full bg-neutral-900 text-white text-xs">{idx + 1}</span>
              <span className="truncate">{u.nickname}</span>
              <span className="ml-auto text-xs text-neutral-600">{u.count}일</span>
            </li>
          ))}
        </ol>
      </div>
    </div>
  );
}


