"use client";

import { useEffect, useState } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import {
  FilePlus2,
  Trash2,
  Eye,
  Pencil,
  ListChecks,
  ChevronLeft,
  ChevronRight,
  LayoutDashboard,
  FolderKanban,
  SunMoon,
  BarChart2,
} from "lucide-react";
import { useAppLocale } from "@/features/i18n/LocaleProvider";
import { getDashboardMessages } from "@/features/i18n/messages/dashboard";
import { getProjectsMessages } from "@/features/i18n/messages/projects";

interface ProjectListItem {
  id: string;
  title: string;
  slug: string;
  status: string;
  createdAt: string;
  updatedAt: string;
}

export default function ProjectsPage() {
  const router = useRouter();
  const locale = useAppLocale();
  const t = getDashboardMessages(locale);
  const p = getProjectsMessages(locale);
  const [projects, setProjects] = useState<ProjectListItem[]>([]);
  const [status, setStatus] = useState<"idle" | "loading" | "error">("idle");
  const [errorMessage, setErrorMessage] = useState<string | null>(null);
  const [selectedSlugs, setSelectedSlugs] = useState<string[]>([]);
  const [currentPage, setCurrentPage] = useState(1);
  const [isMenuOpen, setIsMenuOpen] = useState(false);
  const [emailVerified, setEmailVerified] = useState<boolean | null>(null);
  const pageSize = 10;

  useEffect(() => {
    let cancelled = false;

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

        const res = await fetch("/api/projects");
        if (!res.ok) {
          if (!cancelled) {
            setStatus("error");

            if (res.status === 401) {
              setErrorMessage(p.errorFetchUnauthorized);
              router.push("/login");
            } else {
              setErrorMessage(p.errorFetchGeneric);
            }
          }
          return;
        }

        const data = (await res.json()) as ProjectListItem[];
        if (!cancelled) {
          setProjects(Array.isArray(data) ? data : []);
          setStatus("idle");
          setErrorMessage(null);
        }
      } catch {
        if (!cancelled) {
          setStatus("error");
          setErrorMessage(p.errorFetchGeneric);
        }
      }
    };

    void load();

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

  // 이메일 인증 여부를 확인해 퍼블릭 페이지 링크 노출 여부를 결정한다.
  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;
    };
  }, []);

  useEffect(() => {
    const totalPages = Math.max(1, Math.ceil(projects.length / pageSize));
    setCurrentPage((prev) => Math.min(prev, totalPages));
  }, [projects.length, pageSize]);

  const handleDelete = async (slug: string) => {
    if (typeof window !== "undefined") {
      const confirmed = window.confirm(p.confirmDeleteSingle);

      if (!confirmed) return;
    }

    try {
      const res = await fetch(`/api/projects/${encodeURIComponent(slug)}`, {
        method: "DELETE",
      });

      if (!res.ok) {
        setStatus("error");
        setErrorMessage(p.errorDeleteSingle);
        return;
      }

      setProjects((prev) => prev.filter((p) => p.slug !== slug));
      setSelectedSlugs((prev) => prev.filter((s) => s !== slug));

      if (typeof window !== "undefined") {
        window.localStorage.removeItem(`pb:project:${slug}`);
        window.localStorage.removeItem(`pb:autosave:${slug}`);
      }

      setStatus("idle");
      setErrorMessage(null);
    } catch {
      setStatus("error");
      setErrorMessage(p.errorDeleteSingle);
    }
  };

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

      if (!res.ok) {
        setStatus("error");
        setErrorMessage("로그아웃 중 오류가 발생했습니다. 잠시 후 다시 시도해 주세요.");
        return;
      }

      router.push("/login");
    } catch {
      setStatus("error");
      setErrorMessage("로그아웃 중 오류가 발생했습니다. 잠시 후 다시 시도해 주세요.");
    }
  };

  const totalCount = projects.length;
  const totalPages = Math.max(1, Math.ceil(totalCount / pageSize));
  const startIndex = (currentPage - 1) * pageSize;
  const endIndex = startIndex + pageSize;
  const pageProjects = projects.slice(startIndex, endIndex);

  const handleBulkDelete = async () => {
    const slugs = selectedSlugs;
    if (slugs.length === 0) return;

    if (typeof window !== "undefined") {
      const confirmed = window.confirm(p.confirmDeleteBulk);
      if (!confirmed) return;
    }

    try {
      const results = await Promise.all(
        slugs.map(async (slug) => {
          const res = await fetch(`/api/projects/${encodeURIComponent(slug)}`, { method: "DELETE" });
          return { slug, ok: res.ok };
        }),
      );

      const okSlugs = results.filter((r) => r.ok).map((r) => r.slug);

      if (okSlugs.length === 0) {
        setStatus("error");
        setErrorMessage(p.errorDeleteBulkAllFailed);
        return;
      }

      setProjects((prev) => prev.filter((p) => !okSlugs.includes(p.slug)));
      setSelectedSlugs((prev) => prev.filter((s) => !okSlugs.includes(s)));

      if (typeof window !== "undefined") {
        for (const slug of okSlugs) {
          window.localStorage.removeItem(`pb:project:${slug}`);
          window.localStorage.removeItem(`pb:autosave:${slug}`);
        }
      }
  
      if (okSlugs.length !== slugs.length) {
        setStatus("error");
        setErrorMessage(p.errorDeleteBulkSomeFailed);
      } else {
        setStatus("idle");
        setErrorMessage(null);
      }
    } catch {
      setStatus("error");
      setErrorMessage(p.errorDeleteBulkAllFailed);
    }
  };

  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">{p.headerTitle}</h1>
          <p className="text-sm text-slate-500 dark:text-slate-400">{p.headerDescription}</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"
              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"
            >
              <LayoutDashboard className="w-4 h-4" aria-hidden="true" />
              <span>{t.navDashboard}</span>
            </Link>
            <Link
              href="/projects"
              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"
            >
              <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 overflow-auto bg-slate-50/60 dark:bg-transparent">
        {status === "error" && (
          <p className="text-xs text-red-500 mb-3 dark:text-red-300">
            {errorMessage ?? p.errorFetchGeneric}
          </p>
        )}
        {projects.length === 0 && status === "idle" && (
          <p className="text-xs text-slate-500 dark:text-slate-400">아직 저장된 프로젝트가 없습니다. 에디터에서 프로젝트를 저장해 보세요.</p>
        )}
        {projects.length > 0 && (
          <>
            <div
              data-testid="projects-toolbar"
              className="flex items-center justify-between mb-2 text-[11px] text-slate-600 dark:text-slate-300"
            >
              <div className="inline-flex items-center gap-2">
                <span className="inline-flex items-center gap-1 px-2 py-1 rounded-full border bg-slate-100 border-slate-300 text-slate-700 dark:bg-slate-900/70 dark:border-slate-700 dark:text-slate-200">
                  <ListChecks className="w-3 h-3 text-slate-400 dark:text-slate-500" aria-hidden="true" />
                  <span>
                    {p.toolbarSelectedPrefix}
                    <span className="font-semibold">{selectedSlugs.length}</span>
                    {p.toolbarSelectedSuffix}
                  </span>
                </span>
              </div>
              <div className="flex items-center gap-2">
                <button
                  type="button"
                  className="inline-flex items-center gap-1 rounded border px-2 py-1 text-xs font-medium border-red-300 text-red-700 bg-red-50 hover:bg-red-100 disabled:opacity-40 disabled:cursor-not-allowed dark:border-red-700 dark:text-red-200 dark:bg-red-900/40 dark:hover:bg-red-900/60"
                  disabled={selectedSlugs.length === 0}
                  onClick={() => {
                    void handleBulkDelete();
                  }}
                >
                  <Trash2 className="w-3 h-3" aria-hidden="true" />
                  <span>{p.toolbarDeleteSelected}</span>
                </button>
                <Link
                  href="/editor?new=1"
                  className="inline-flex items-center gap-1 rounded border px-2 py-1 text-xs font-medium border-sky-500 bg-sky-600 text-white hover:bg-sky-700 shadow-sm dark:border-sky-700 dark:bg-sky-950 dark:text-sky-100 dark:hover:bg-sky-900"
                >
                  <FilePlus2 className="w-3 h-3" aria-hidden="true" />
                  <span>{p.toolbarCreateNew}</span>
                </Link>
              </div>
            </div>
            <table className="w-full text-xs text-left border-collapse mt-2">
              <thead>
                <tr className="border-b border-slate-200 text-slate-600 dark:border-slate-800 dark:text-slate-400">
                  <th className="py-2 pr-2 w-8">
                    <input
                      type="checkbox"
                      className="h-3 w-3 rounded border-slate-700 bg-slate-900 align-middle"
                      aria-label={p.tableHeaderSelectAllAria}
                      checked={
                        pageProjects.length > 0 && pageProjects.every((p) => selectedSlugs.includes(p.slug))
                      }
                      onChange={(e) => {
                        if (e.target.checked) {
                          const slugsOnPage = pageProjects.map((p) => p.slug);
                          setSelectedSlugs((prev) => Array.from(new Set([...prev, ...slugsOnPage])));
                        } else {
                          const slugsOnPage = pageProjects.map((p) => p.slug);
                          setSelectedSlugs((prev) => prev.filter((s) => !slugsOnPage.includes(s)));
                        }
                      }}
                    />
                  </th>
                  <th className="py-2 pr-4">{p.tableHeaderTitle}</th>
                  <th className="py-2 pr-4">{p.tableHeaderSlug}</th>
                  <th className="py-2 pr-4">{p.tableHeaderStatus}</th>
                  <th className="py-2 pr-4">{p.tableHeaderCreatedAt}</th>
                  <th className="py-2 pr-4">{p.tableHeaderUpdatedAt}</th>
                  <th className="py-2 pr-4 text-right">{p.tableHeaderActions}</th>
                </tr>
              </thead>
              <tbody>
                {pageProjects.map((project) => {
                  const checked = selectedSlugs.includes(project.slug);
                  return (
                    <tr
                      key={project.id}
                      className="border-b border-slate-200 hover:bg-slate-50 dark:border-slate-900 dark:hover:bg-slate-900/60"
                    >
                      <td className="py-2 pr-2 w-8">
                        <input
                          type="checkbox"
                          className="h-3 w-3 rounded border-slate-700 bg-slate-900 align-middle"
                          aria-label={`${project.title}${p.tableRowSelectAriaSuffix}`}
                          checked={checked}
                          onChange={(e) => {
                            if (e.target.checked) {
                              setSelectedSlugs((prev) =>
                                prev.includes(project.slug) ? prev : [...prev, project.slug],
                              );
                            } else {
                              setSelectedSlugs((prev) => prev.filter((s) => s !== project.slug));
                            }
                          }}
                        />
                      </td>
                      <td className="py-2 pr-4 text-slate-900 dark:text-slate-100">{project.title}</td>
                      <td className="py-2 pr-4 text-slate-600 dark:text-slate-300 font-mono text-[11px]">{project.slug}</td>
                      <td className="py-2 pr-4 text-slate-600 dark:text-slate-300">{project.status}</td>
                      <td className="py-2 pr-4 text-slate-500 dark:text-slate-400 text-[11px]">
                        {new Date(project.createdAt).toLocaleString()}
                      </td>
                      <td className="py-2 pr-4 text-slate-500 text-[11px]">
                        {new Date(project.updatedAt).toLocaleString()}
                      </td>
                      <td className="py-2 pl-4 pr-0 text-right text-[11px]">
                        <div className="inline-flex items-center gap-2">
                          <Link
                            href={`/editor?slug=${encodeURIComponent(project.slug)}`}
                            className="inline-flex items-center gap-1 text-sky-600 hover:text-sky-700 underline-offset-2 hover:underline dark:text-sky-300 dark:hover:text-sky-200"
                          >
                            <Pencil className="w-3 h-3" aria-hidden="true" />
                            <span>{p.actionEdit}</span>
                          </Link>
                          <Link
                            href={`/preview?slug=${encodeURIComponent(project.slug)}`}
                            className="inline-flex items-center gap-1 text-slate-600 hover:text-slate-800 underline-offset-2 hover:underline dark:text-slate-300 dark:hover:text-slate-100"
                          >
                            <Eye className="w-3 h-3" aria-hidden="true" />
                            <span>{p.actionPreview}</span>
                          </Link>
                          {emailVerified !== false && (
                            <Link
                              href={`/p/${encodeURIComponent(project.slug)}`}
                              className="inline-flex items-center gap-1 text-sky-700 hover:text-sky-900 underline-offset-2 hover:underline dark:text-sky-300 dark:hover:text-sky-200"
                            >
                              <Eye className="w-3 h-3" aria-hidden="true" />
                              <span>{t.projectOpenPublicPageLink}</span>
                            </Link>
                          )}
                          <Link
                            href={`/projects/${encodeURIComponent(project.slug)}/submissions`}
                            className="inline-flex items-center gap-1 text-emerald-600 hover:text-emerald-700 underline-offset-2 hover:underline dark:text-emerald-300 dark:hover:text-emerald-100"
                          >
                            <ListChecks className="w-3 h-3" aria-hidden="true" />
                            <span>{p.actionViewSubmissions}</span>
                          </Link>
                          <button
                            type="button"
                            className="inline-flex items-center gap-1 text-red-600 hover:text-red-700 underline-offset-2 hover:underline dark:text-red-300 dark:hover:text-red-200"
                            onClick={() => {
                              void handleDelete(project.slug);
                            }}
                          >
                            <Trash2 className="w-3 h-3" aria-hidden="true" />
                            <span>{p.actionDelete}</span>
                          </button>
                        </div>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>

            <div className="mt-3 flex items-center justify-between text-[11px] text-slate-600 dark:text-slate-300">
              <div className="inline-flex items-center gap-2">
                <span className="px-2 py-1 rounded-full bg-slate-100 border border-slate-300 text-slate-700 dark:bg-slate-900/70 dark:border-slate-700 dark:text-slate-200">
                  {p.pagerTotalPrefix}
                  {totalCount}
                  {p.pagerTotalCountSuffix}
                  <span className="font-semibold">
                    {totalCount === 0 ? 0 : startIndex + 1}–{Math.min(endIndex, totalCount)}
                  </span>
                </span>
              </div>
              <div className="flex items-center gap-1">
                {Array.from({ length: totalPages }).map((_, idx) => {
                  const page = idx + 1;
                  const isActive = page === currentPage;
                  return (
                    <button
                      key={page}
                      type="button"
                      onClick={() => setCurrentPage(page)}
                      className={`w-6 h-6 rounded-full text-[10px] flex items-center justify-center border transition-colors ${
                        isActive
                          ? "bg-sky-600 text-white border-sky-500 shadow-sm"
                          : "bg-white text-slate-700 border-slate-300 hover:bg-slate-100 dark:bg-slate-900 dark:text-slate-300 dark:border-slate-700 dark:hover:bg-slate-800"
                      }`}
                    >
                      {page}
                    </button>
                  );
                })}
              </div>
              <div className="flex items-center gap-1">
                <button
                  type="button"
                  disabled={currentPage === 1}
                  className="inline-flex items-center gap-1 px-2 py-1 rounded border border-slate-300 text-slate-700 bg-white disabled:opacity-40 disabled:cursor-not-allowed hover:bg-slate-100 dark:border-slate-700 dark:text-slate-300 dark:bg-slate-900 dark:hover:bg-slate-800"
                  onClick={() => setCurrentPage((p) => Math.max(1, p - 1))}
                >
                  <ChevronLeft className="w-3 h-3" aria-hidden="true" />
                  <span>{p.pagerPrevLabel}</span>
                </button>
                <button
                  type="button"
                  disabled={currentPage === totalPages}
                  className="inline-flex items-center gap-1 px-2 py-1 rounded border border-slate-300 text-slate-700 bg-white disabled:opacity-40 disabled:cursor-not-allowed hover:bg-slate-100 dark:border-slate-700 dark:text-slate-300 dark:bg-slate-900 dark:hover:bg-slate-800"
                  onClick={() => setCurrentPage((p) => Math.min(totalPages, p + 1))}
                >
                  <span>{p.pagerNextLabel}</span>
                  <ChevronRight className="w-3 h-3" aria-hidden="true" />
                </button>
              </div>
            </div>
          </>
        )}
      </section>
    </main>
  );
}
