import { Link, Outlet, RouterProvider, createRootRoute, createRoute, createRouter, useNavigate } from "@tanstack/react-router";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useState } from "react";

import { ApiError, api, type AuthState } from "./api";
import { AnalyticsPage } from "./features/analytics/AnalyticsPage";
import { AuthProvider, useAuth } from "./features/auth/AuthContext";
import { AuthScreen } from "./features/auth/AuthScreen";
import { clearAuth, loadAuth, saveAuth } from "./features/auth/authStorage";
import { CatalogPage } from "./features/catalog/CatalogPage";
import { HistoryPage } from "./features/history/HistoryPage";
import { WorkoutDetailPage } from "./features/history/WorkoutDetailPage";
import { ActiveWorkoutPage } from "./features/workout/ActiveWorkoutPage";
import { invalidateWorkoutQueries } from "./features/workout/hooks";
import { Metric } from "./shared/Metric";

function AppShell() {
  const { auth, logout } = useAuth();
  const nav = [
    { to: "/", label: "Сегодня" },
    { to: "/workout/active", label: "Тренировка" },
    { to: "/catalog/exercises", label: "Каталог" },
    { to: "/history", label: "История" },
    { to: "/analytics", label: "Аналитика" },
  ] as const;

  return (
    <div className="app-shell">
      <aside className="sidebar">
        <div className="brand-mark">
          <p className="eyebrow">Train Watcher</p>
          <h1>Дневник силовых сессий</h1>
        </div>
        <nav aria-label="Основная навигация">
          {nav.map((item) => (
            <Link key={item.to} to={item.to} activeProps={{ className: "active" }} activeOptions={{ exact: item.to === "/" }}>
              {item.label}
            </Link>
          ))}
        </nav>
        <div className="profile-card">
          <span>{auth.user.display_name}</span>
          <small>{auth.user.email}</small>
          <button onClick={logout}>Выйти</button>
        </div>
      </aside>
      <main className="main-stage">
        <Outlet />
      </main>
    </div>
  );
}

function HomePage() {
  const { auth } = useAuth();
  const navigate = useNavigate();
  const queryClient = useQueryClient();
  const activeWorkout = useQuery({ queryKey: ["workout", "active"], queryFn: () => api.activeWorkout(auth.accessToken) });
  const workouts = useQuery({ queryKey: ["workouts"], queryFn: () => api.workouts(auth.accessToken) });
  const calories = useQuery({ queryKey: ["calories"], queryFn: () => api.calories(auth.accessToken) });

  const startMutation = useMutation({
    mutationFn: () => api.createWorkout(auth.accessToken),
    onSuccess: async () => {
      await invalidateWorkoutQueries(queryClient);
      void navigate({ to: "/workout/active" });
    },
    onError: async (error) => {
      if (error instanceof ApiError && error.status === 409) {
        await invalidateWorkoutQueries(queryClient);
        void navigate({ to: "/workout/active" });
      }
    },
  });

  const active = activeWorkout.data;
  const latestFinished = workouts.data?.find((workout) => workout.status === "finished");

  return (
    <section className="stack home-stack">
      <div className="page-header">
        <div>
          <p className="eyebrow">Сегодня</p>
          <h2>Состояние дня</h2>
        </div>
      </div>

      <section className={`daily-command card ${active ? "active-session" : "idle-session"}`}>
        <div>
          <p className="eyebrow">{active ? "Active workout" : "Ready state"}</p>
          <h3>{active ? "Активная тренировка" : "Нет активной тренировки"}</h3>
          <p>
            {active
              ? `Начата ${new Date(active.started_at).toLocaleTimeString("ru-RU", { hour: "2-digit", minute: "2-digit" })}. Продолжи журнал подходов.`
              : "Запусти сессию и добавляй упражнения по ходу тренировки — каталог откроется отдельно."}
          </p>
        </div>
        <button className="primary pulse-action" onClick={() => (active ? navigate({ to: "/workout/active" }) : startMutation.mutate())} disabled={startMutation.isPending}>
          {startMutation.isPending ? "Создание..." : active ? "Продолжить" : "Начать тренировку"}
        </button>
      </section>

      <div className="stats-grid">
        <Metric label="Всего тренировок" value={workouts.data?.filter((w) => w.status !== "discarded").length ?? 0} />
        <Metric label="Калорий" value={Math.round(calories.data?.total_calories ?? 0)} />
        <Metric label="Последняя" value={latestFinished ? new Date(latestFinished.started_at).toLocaleDateString("ru-RU") : "нет"} />
      </div>
    </section>
  );
}

const rootRoute = createRootRoute({ component: AppShell });
const indexRoute = createRoute({ getParentRoute: () => rootRoute, path: "/", component: HomePage });
const activeWorkoutRoute = createRoute({ getParentRoute: () => rootRoute, path: "/workout/active", component: ActiveWorkoutPage });
const catalogRoute = createRoute({ getParentRoute: () => rootRoute, path: "/catalog", component: () => <CatalogPage kind="mine" /> });
const catalogExercisesRoute = createRoute({ getParentRoute: () => rootRoute, path: "/catalog/exercises", component: () => <CatalogPage kind="exercise" /> });
const catalogEquipmentRoute = createRoute({ getParentRoute: () => rootRoute, path: "/catalog/equipment", component: () => <CatalogPage kind="machine" /> });
const historyRoute = createRoute({ getParentRoute: () => rootRoute, path: "/history", component: HistoryPage });
const analyticsRoute = createRoute({ getParentRoute: () => rootRoute, path: "/analytics", component: AnalyticsPage });
const workoutDetailRoute = createRoute({ getParentRoute: () => rootRoute, path: "/workouts/$workoutId", component: WorkoutDetailPage });

const routeTree = rootRoute.addChildren([
  indexRoute,
  activeWorkoutRoute,
  catalogRoute,
  catalogExercisesRoute,
  catalogEquipmentRoute,
  historyRoute,
  analyticsRoute,
  workoutDetailRoute,
]);

const router = createRouter({ routeTree });

declare module "@tanstack/react-router" {
  interface Register {
    router: typeof router;
  }
}

export function App() {
  const [auth, setAuth] = useState<AuthState | null>(loadAuth);
  const queryClient = useQueryClient();

  function handleAuth(next: AuthState) {
    saveAuth(next);
    setAuth(next);
  }

  function logout() {
    clearAuth();
    queryClient.clear();
    setAuth(null);
  }

  if (!auth) {
    return <AuthScreen onAuth={handleAuth} />;
  }

  return (
    <AuthProvider auth={auth} logout={logout}>
      <RouterProvider router={router} />
    </AuthProvider>
  );
}
