import { startOfWeek } from "date-fns";
import { DashboardAnalysisCard } from "@/components/dashboard-analysis-card";
import { RunningStatsChart } from "@/components/running-stats-chart";
import { StatCard } from "@/components/stat-card";
import { VolumeTrendChart } from "@/components/volume-trend-chart";
import { formatDateShort } from "@/lib/format";
import { listAnalysesForCalendar, serializeAnalysis } from "@/lib/models/analysis";
import { listRunningActivities } from "@/lib/models/running";
import { listStrengthWorkouts } from "@/lib/models/strength";
import { workoutVolumeKg } from "@/lib/strength/stats";
import { getCurrentUserId } from "@/lib/session";

export const dynamic = "force-dynamic";

const TREND_LIMIT = 20;

export default async function Home() {
  const userId = await getCurrentUserId();

  const [runs, strengthWorkouts, allAnalyses] = await Promise.all([
    listRunningActivities(userId),
    listStrengthWorkouts(userId),
    listAnalysesForCalendar(userId),
  ]);

  const weekStart = startOfWeek(new Date(), { weekStartsOn: 1 });
  const weeklyKm =
    runs.filter((run) => run.startTime >= weekStart).reduce((sum, run) => sum + run.distanceM, 0) /
    1000;
  const weeklyStrengthSessions = strengthWorkouts.filter(
    (workout) => workout.date >= weekStart
  ).length;

  const totalRuns = runs.length;
  const totalDistanceKm = runs.reduce((sum, r) => sum + r.distanceM, 0) / 1000;
  const totalStrengthWorkouts = strengthWorkouts.length;

  const volumeTrendData = strengthWorkouts
    .slice(0, TREND_LIMIT)
    .map((w) => ({
      label: formatDateShort(w.date),
      date: w.date.toISOString().slice(0, 10),
      name: w.name,
      volumeKg: workoutVolumeKg(w),
    }))
    .reverse();

  // Aggregate running distance per ISO week (Mon-based).
  const weeklyDistanceM = new Map<number, number>();
  for (const r of runs) {
    const weekStartTs = startOfWeek(r.startTime, { weekStartsOn: 1 }).getTime();
    weeklyDistanceM.set(weekStartTs, (weeklyDistanceM.get(weekStartTs) ?? 0) + r.distanceM);
  }
  const runTrendData = [...weeklyDistanceM.entries()]
    .sort((a, b) => a[0] - b[0])
    .slice(-TREND_LIMIT)
    .map(([ts, meters]) => ({
      label: formatDateShort(new Date(ts)),
      distanceKm: Math.round((meters / 1000) * 100) / 100,
    }));

  const serializedAnalyses = allAnalyses.map(serializeAnalysis);

  const dayRuns = runs.map((r) => ({
    id: r._id.toString(),
    name: r.name,
    startTime: r.startTime.toISOString(),
    distanceM: r.distanceM,
    durationSec: r.durationSec,
    avgPaceSecPerKm: r.avgPaceSecPerKm,
  }));

  const dayWorkouts = strengthWorkouts.map((w) => ({
    id: w._id.toString(),
    name: w.name,
    date: w.date.toISOString(),
    exerciseCount: w.exercises.length,
  }));

  return (
    <div className="flex flex-col gap-8">
      <section className="grid grid-cols-2 gap-3 sm:grid-cols-4">
        <StatCard label="Km w tym tygodniu" value={`${weeklyKm.toFixed(1)} km`} hint="Bieganie" />
        <StatCard
          label="Siłownia w tym tygodniu"
          value={weeklyStrengthSessions}
          hint="Treningi"
        />
        <StatCard
          label="Łączny dystans"
          value={`${totalDistanceKm.toFixed(0)} km`}
          hint={`${totalRuns} biegów`}
        />
        <StatCard
          label="Treningi siłowe"
          value={totalStrengthWorkouts}
          hint="Łącznie"
        />
      </section>

      {(volumeTrendData.length > 1 || runTrendData.length > 1) && (
        <section className="flex flex-col gap-4">
          <h2 className="text-lg font-semibold text-fg">Globalne statystyki</h2>
          <div className="grid grid-cols-1 gap-4 lg:grid-cols-2">
            {volumeTrendData.length > 1 && <VolumeTrendChart data={volumeTrendData} />}
            {runTrendData.length > 1 && <RunningStatsChart data={runTrendData} />}
          </div>
        </section>
      )}

      <DashboardAnalysisCard
        analyses={serializedAnalyses}
        runs={dayRuns}
        workouts={dayWorkouts}
      />
    </div>
  );
}
