"use client";

import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import Link from "next/link";
import { BarChart2, FolderKanban, LayoutDashboard, ListChecks, SunMoon } from "lucide-react";
import { useAppLocale } from "@/features/i18n/LocaleProvider";
import { getDashboardMessages } from "@/features/i18n/messages/dashboard";

// 대시보드 페이지 (/dashboard)
// - /api/dashboard/overview 에서 요약/프로젝트별 통계를 가져와 카드 형태로 렌더링한다.
// - 비로그인(401) 응답 시 로그인 페이지로 리다이렉트하고 에러 메시지를 표시한다.

interface SummaryStats {
  totalProjects: number;
  totalSubmissions: number;
  todaySubmissions: number;
  last7DaysSubmissions: number;
}

interface DailySubmissionItem {
  // 일별 제출 수 그래프를 위한 집계 데이터
  date: string; // YYYY-MM-DD
  count: number;
}

interface ProjectStatsItem {
  projectId: string;
  title: string;
  slug: string;
  status: string;
  totalSubmissions: number;
  lastSubmissionAt: string | null;
}

type PageStatus = "idle" | "loading" | "error";

export default function DashboardPage() {
  const router = useRouter();
  const locale = useAppLocale();
  const t = getDashboardMessages(locale);

  const [summary, setSummary] = useState<SummaryStats | null>(null);
  const [projects, setProjects] = useState<ProjectStatsItem[]>([]);
  const [dailySubmissions, setDailySubmissions] = useState<DailySubmissionItem[]>([]);
  const [status, setStatus] = useState<PageStatus>("idle");
  const [errorMessage, setErrorMessage] = useState<string | null>(null);
  const [isMenuOpen, setIsMenuOpen] = useState(false);
  const [emailVerified, setEmailVerified] = useState<boolean | null>(null);

  // 마운트 시 대시보드 개요 데이터를 불러온다.
  useEffect(() => {
    let cancelled = false;

    const load = async () => {
      try {
        setStatus("loading");
        setErrorMessage(null);

        const res = await fetch("/api/dashboard/overview");

        if (!res.ok) {
          if (cancelled) return;

          if (res.status === 401) {
            setStatus("error");
            setErrorMessage(t.errorUnauthorized);
            router.push("/login");
            return;
          }

          setStatus("error");
          setErrorMessage(t.errorGeneric);
          return;
        }

        const data = (await res.json()) as {
          summaryStats: SummaryStats;
          projectStats: ProjectStatsItem[];
          dailySubmissions?: DailySubmissionItem[];
        };

        if (cancelled) return;

        setSummary(data.summaryStats ?? null);
        setProjects(Array.isArray(data.projectStats) ? data.projectStats : []);
        setDailySubmissions(
          Array.isArray(data.dailySubmissions) ? data.dailySubmissions : [],
        );
        setStatus("idle");
        setErrorMessage(null);
      } catch {
        if (!cancelled) {
          setStatus("error");
          setErrorMessage(t.errorGeneric);
        }
      }
    };

    void load();

    return () => {
      cancelled = true;
    };
  }, [router]);

  // 마운트 시 현재 사용자 이메일 인증 여부를 확인한다.
  useEffect(() => {
    let cancelled = false;

    const loadMe = async () => {
      try {
        const res = await fetch("/api/auth/me");
        if (cancelled || !res.ok) return;

        const data = (await res.json().catch(() => null)) as any;
        if (!cancelled && data) {
          setEmailVerified(Boolean(data.emailVerified));
        }
      } catch {
        // ignore – 인증 여부를 알 수 없으면 배너만 표시하지 않는다.
      }
    };

    void loadMe();

    return () => {
      cancelled = true;
    };
  }, []);

  const safeSummary: SummaryStats =
    summary ?? {
      totalProjects: 0,
      totalSubmissions: 0,
      todaySubmissions: 0,
      last7DaysSubmissions: 0,
    };

  const handleLogout = async () => {
    try {
      const res = await fetch("/api/auth/logout", {
        method: "POST",
      });

      if (!res.ok) {
        return;
      }

      router.push("/login");
    } catch {
    }
  };

  const handleToggleTheme = () => {
    if (typeof document === "undefined") {
      return;
    }

    const root = document.documentElement;
    if (!root) {
      return;
    }

    root.classList.toggle("dark");
  };

  return (
    <main className="min-h-screen flex flex-col bg-slate-100 text-slate-900 dark:bg-slate-950 dark:text-slate-50">
      <header className="border-b border-slate-200 px-6 py-4 flex items-center justify-between bg-white/80 backdrop-blur dark:border-slate-800 dark:bg-slate-950/80">
        <div>
          <h1 className="text-2xl font-bold tracking-tight">{t.title}</h1>
          <p className="text-sm text-slate-500 mt-1 dark:text-slate-400">{t.description}</p>
        </div>
        <div className="flex items-center gap-3 text-sm">
          <nav className="inline-flex items-center gap-1 rounded-full border border-slate-200 bg-white/80 px-1.5 py-1 shadow-sm dark:border-slate-700 dark:bg-slate-900/80">
            <Link
              href="/dashboard"
              aria-current="page"
              className="inline-flex items-center gap-1 px-3 py-1.5 rounded-full text-sm font-semibold bg-sky-600 text-white shadow-sm hover:bg-sky-700"
            >
              <LayoutDashboard className="w-4 h-4" aria-hidden="true" />
              <span>{t.navDashboard}</span>
            </Link>
            <Link
              href="/projects"
              className="inline-flex items-center gap-1 px-3 py-1.5 rounded-full text-sm font-medium text-slate-700 hover:bg-slate-100 hover:text-sky-700 dark:text-slate-200 dark:hover:bg-slate-800 dark:hover:text-sky-200"
            >
              <FolderKanban className="w-4 h-4" aria-hidden="true" />
              <span>{t.navProjects}</span>
            </Link>
            <Link
              href="/projects/submissions"
              className="inline-flex items-center gap-1 px-3 py-1.5 rounded-full text-sm font-medium text-emerald-700 hover:bg-emerald-50 hover:text-emerald-800 dark:text-emerald-200 dark:hover:bg-emerald-900/60 dark:hover:text-emerald-100"
            >
              <ListChecks className="w-4 h-4" aria-hidden="true" />
              <span>{t.navSubmissions}</span>
            </Link>
            <Link
              href="/reports"
              className="inline-flex items-center gap-1 px-3 py-1.5 rounded-full text-sm font-medium text-slate-700 hover:bg-slate-100 hover:text-sky-700 dark:text-slate-200 dark:hover:bg-slate-800 dark:hover:text-sky-200"
            >
              <BarChart2 className="w-4 h-4" aria-hidden="true" />
              <span>{t.navReports ?? "Reports"}</span>
            </Link>
          </nav>
          <button
            type="button"
            className="inline-flex items-center gap-1 rounded-full border border-slate-300 bg-white/80 px-3 py-1.5 text-xs font-medium text-slate-700 hover:bg-slate-100 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-200 dark:hover:bg-slate-800"
            onClick={handleToggleTheme}
          >
            <SunMoon className="w-4 h-4" aria-hidden="true" />
            <span>{t.themeToggleLabel}</span>
          </button>
          <div className="relative">
            <button
              type="button"
              className="inline-flex items-center gap-1 rounded-full border border-slate-300 bg-white/80 px-3 py-1.5 text-xs font-medium text-slate-700 hover:bg-slate-100 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-200 dark:hover:bg-slate-800"
              onClick={() => {
                setIsMenuOpen((prev) => !prev);
              }}
            >
              {t.menuLabel}
            </button>
            {isMenuOpen && (
              <div className="absolute right-0 mt-1 w-32 rounded border border-slate-200 bg-white shadow-lg z-20 dark:border-slate-700 dark:bg-slate-900/95">
                <button
                  type="button"
                  className="w-full px-3 py-2 text-left text-xs text-slate-700 hover:bg-slate-100 dark:text-slate-200 dark:hover:bg-slate-800"
                  onClick={() => {
                    setIsMenuOpen(false);
                    router.push("/mypage");
                  }}
                >
                  {t.myPageLabel}
                </button>
                <button
                  type="button"
                  className="w-full px-3 py-2 text-left text-xs text-slate-700 hover:bg-slate-100 dark:text-slate-200 dark:hover:bg-slate-800"
                  onClick={() => {
                    setIsMenuOpen(false);
                    void handleLogout();
                  }}
                >
                  {t.logoutLabel}
                </button>
              </div>
            )}
          </div>
        </div>
      </header>

      <section className="flex-1 px-6 py-4 space-y-4 overflow-auto bg-slate-50/60 dark:bg-transparent">
        {status === "error" && errorMessage && (
          <p className="text-xs text-red-500 dark:text-red-300">{errorMessage}</p>
        )}

        {emailVerified === false && (
          <p className="text-xs text-amber-700 mb-1 dark:text-amber-300">
            {t.emailNotVerifiedBanner}
          </p>
        )}

        {status === "loading" && (
          <p className="text-xs text-slate-400">{t.loadingText}</p>
        )}

        {/* 상단 요약 위젯 영역 */}
        <div className="grid grid-cols-2 md:grid-cols-4 gap-3 text-xs">
          <div
            data-testid="dashboard-summary-total-projects"
            className="rounded-xl border border-slate-200 bg-white/80 px-4 py-3 flex flex-col gap-1 shadow-sm dark:border-slate-800 dark:bg-slate-900/70"
          >
            <span className="text-[11px] font-medium text-slate-500 dark:text-slate-400">
              {t.summaryTotalProjectsLabel}
            </span>
            <span className="text-2xl font-bold tracking-tight">{safeSummary.totalProjects}</span>
          </div>

          <div
            data-testid="dashboard-summary-total-submissions"
            className="rounded-xl border border-slate-200 bg-white/80 px-4 py-3 flex flex-col gap-1 shadow-sm dark:border-slate-800 dark:bg-slate-900/70"
          >
            <span className="text-[11px] font-medium text-slate-500 dark:text-slate-400">
              {t.summaryTotalSubmissionsLabel}
            </span>
            <span className="text-2xl font-bold tracking-tight">{safeSummary.totalSubmissions}</span>
          </div>

          <div
            data-testid="dashboard-summary-today-submissions"
            className="rounded-xl border border-slate-200 bg-white/80 px-4 py-3 flex flex-col gap-1 shadow-sm dark:border-slate-800 dark:bg-slate-900/70"
          >
            <span className="text-[11px] font-medium text-slate-500 dark:text-slate-400">
              {t.summaryTodaySubmissionsLabel}
            </span>
            <span className="text-2xl font-bold tracking-tight">{safeSummary.todaySubmissions}</span>
          </div>

          <div
            data-testid="dashboard-summary-last7days-submissions"
            className="rounded-xl border border-slate-200 bg-white/80 px-4 py-3 flex flex-col gap-1 shadow-sm dark:border-slate-800 dark:bg-slate-900/70"
          >
            <span className="text-[11px] font-medium text-slate-500 dark:text-slate-400">
              {t.summaryLast7DaysSubmissionsLabel}
            </span>
            <span className="text-2xl font-bold tracking-tight">{safeSummary.last7DaysSubmissions}</span>
          </div>
        </div>

        {/* 일별 제출 수 간단 그래프 영역 */}
        <div
          data-testid="dashboard-daily-chart"
          className="mt-2 rounded-xl border border-slate-200 bg-white/80 px-4 py-3 shadow-sm dark:border-slate-800 dark:bg-slate-900/70"
        >
          <div className="flex items-baseline justify-between mb-2">
            <h2 className="text-sm font-semibold text-slate-800 dark:text-slate-200">{t.chartTitle}</h2>
            <span className="text-[10px] text-slate-500 dark:text-slate-500">{t.chartSubtitle}</span>
          </div>

          {dailySubmissions.length === 0 ? (
            <p className="text-[11px] text-slate-500 dark:text-slate-400">{t.chartEmptyLabel}</p>
          ) : (
            <div className="flex items-end gap-2 text-[10px]">
              {dailySubmissions.map((item) => (
                <div
                  key={item.date}
                  data-testid="dashboard-daily-chart-bar"
                  className="flex flex-col items-center gap-1"
                >
                  <div
                    className="w-6 rounded-t bg-emerald-500/80"
                    style={{ height: `${Math.max(8, item.count * 12)}px` }}
                  />
                  <span className="text-slate-700 font-semibold dark:text-slate-300">{item.count}</span>
                  <span className="text-slate-500 dark:text-slate-500">{item.date}</span>
                </div>
              ))}
            </div>
          )}
        </div>

        {/* 프로젝트 카드 리스트 영역 */}
        <div className="mt-2">
          <h2 className="text-base font-semibold mb-2 text-slate-800 dark:text-slate-100">
            {t.sectionProjectsTitle}
          </h2>

          {projects.length === 0 && status === "idle" && !errorMessage && (
            <p className="text-xs text-slate-500 dark:text-slate-400">{t.sectionProjectsEmpty}</p>
          )}

          {projects.length > 0 && (
            <div className="grid gap-3 md:grid-cols-2 lg:grid-cols-3">
              {projects.map((project) => {
                const lastSubmitted = project.lastSubmissionAt
                  ? new Date(project.lastSubmissionAt).toLocaleString()
                  : t.projectLatestSubmissionEmpty;

                return (
                  <article
                    key={project.projectId}
                    data-testid="dashboard-project-card"
                    className="rounded-xl border border-slate-200 bg-white/80 px-4 py-3 flex flex-col gap-1 shadow-sm dark:border-slate-800 dark:bg-slate-900/70"
                  >
                    <div className="flex items-baseline justify-between gap-2">
                      <div>
                        <h3 className="text-sm font-semibold text-slate-900 dark:text-slate-50">{project.title}</h3>
                        <p className="text-[11px] text-slate-500 font-mono dark:text-slate-400">{project.slug}</p>
                      </div>
                      <span className="text-[10px] px-2 py-0.5 rounded-full border border-slate-300 bg-slate-50 text-slate-700 dark:border-slate-700 dark:bg-transparent dark:text-slate-300">
                        {project.status}
                      </span>
                    </div>

                    <div className="mt-1 flex items-center justify-between text-[11px] text-slate-700 dark:text-slate-300">
                      <span>
                        {t.projectTotalSubmissionsPrefix}
                        <span className="font-semibold">{project.totalSubmissions}</span>
                        {t.projectTotalSubmissionsSuffix}
                      </span>
                      <span className="text-slate-500 dark:text-slate-400">
                        {t.projectLatestSubmissionPrefix} {lastSubmitted}
                      </span>
                    </div>

                    <div className="mt-2 flex items-center gap-2 text-[11px]">
                      <Link
                        href={`/projects/${encodeURIComponent(project.slug)}/submissions`}
                        className="text-emerald-700 hover:text-emerald-900 underline-offset-2 hover:underline dark:text-emerald-300 dark:hover:text-emerald-100"
                      >
                        {t.projectViewSubmissionsLink}
                      </Link>
                      <Link
                        href={`/p/${encodeURIComponent(project.slug)}`}
                        className="text-sky-700 hover:text-sky-900 underline-offset-2 hover:underline dark:text-sky-300 dark:hover:text-sky-200"
                      >
                        {t.projectOpenPublicPageLink}
                      </Link>
                    </div>
                  </article>
                );
              })}
            </div>
          )}
        </div>
      </section>
    </main>
  );
}
