import { useNavigate } from "@tanstack/react-router";
import { useEffect, useMemo, useState } from "react";

import { useAuth } from "../auth/AuthContext";
import type { CatalogEntity, CatalogKind, WorkoutSetInput } from "../../types";
import { Metric } from "../../shared/Metric";
import { AddExerciseDrawer } from "./AddExerciseDrawer";
import { EmptyWorkoutState } from "./EmptyWorkoutState";
import { FinishWorkoutDialog } from "./FinishWorkoutDialog";
import { useActiveWorkout, useWorkoutMutations } from "./hooks";
import { WorkoutExerciseCard } from "./WorkoutExerciseCard";

function useElapsed(startedAt?: string) {
  const [elapsed, setElapsed] = useState("00:00");

  useEffect(() => {
    if (!startedAt) return;
    const started = new Date(startedAt).getTime();
    const tick = () => {
      const diff = Math.max(0, Date.now() - started);
      const totalSeconds = Math.floor(diff / 1000);
      const hours = Math.floor(totalSeconds / 3600);
      const minutes = Math.floor((totalSeconds % 3600) / 60);
      const seconds = totalSeconds % 60;
      setElapsed(hours > 0 ? `${hours}:${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}` : `${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`);
    };
    tick();
    const intervalId = window.setInterval(tick, 1000);
    return () => window.clearInterval(intervalId);
  }, [startedAt]);

  return elapsed;
}

export function ActiveWorkoutPage() {
  const { auth } = useAuth();
  const navigate = useNavigate();
  const activeWorkout = useActiveWorkout();
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [finishOpen, setFinishOpen] = useState(false);
  const [discardOpen, setDiscardOpen] = useState(false);
  const workout = activeWorkout.data;
  const elapsed = useElapsed(workout?.started_at);
  const mutations = useWorkoutMutations({
    onStartConflict: () => void navigate({ to: "/workout/active" }),
    onFinish: () => void navigate({ to: "/history" }),
    onDiscard: () => void navigate({ to: "/" }),
  });

  const sortedItems = useMemo(() => [...(workout?.items ?? [])].sort((a, b) => a.order_index - b.order_index), [workout?.items]);

  function addFromDrawer(entity: CatalogEntity, kind: CatalogKind, closeAfter: boolean) {
    if (!workout) return;
    mutations.addWorkoutItem.mutate(
      { workoutId: workout.id, sourceId: entity.id, kind },
      { onSuccess: () => { if (closeAfter) setDrawerOpen(false); } },
    );
  }

  if (activeWorkout.isLoading) {
    return <section className="card loading-card">Загружаю активную тренировку...</section>;
  }

  if (!workout) {
    return (
      <section className="stack">
        <div className="page-header">
          <div>
            <p className="eyebrow">Active Workout</p>
            <h2>Живой журнал</h2>
          </div>
        </div>
        <section className="card workout-cta">
          <h3>Нет активной тренировки</h3>
          <p>Новая сессия создаст защищенный active workout. Если сессия уже существует, приложение восстановит ее после обновления.</p>
          <button className="primary" disabled={mutations.startWorkout.isPending} onClick={() => mutations.startWorkout.mutate()}>
            {mutations.startWorkout.isPending ? "Создание..." : "Начать тренировку"}
          </button>
        </section>
      </section>
    );
  }

  const anyPending =
    mutations.addWorkoutItem.isPending ||
    mutations.recordWorkoutSet.isPending ||
    mutations.recordWorkoutSetsBatch.isPending ||
    mutations.removeWorkoutItem.isPending ||
    mutations.removeWorkoutSet.isPending ||
    mutations.updateWorkoutSet.isPending;

  return (
    <section className="stack workout-page">
      <div className="live-header card">
        <div>
          <p className="eyebrow">Active Workout</p>
          <h2>Живой журнал</h2>
          <span>Старт: {new Date(workout.started_at).toLocaleString("ru-RU", { hour: "2-digit", minute: "2-digit", day: "2-digit", month: "short" })}</span>
        </div>
        <div className="live-clock" aria-label="Прошло времени">{elapsed}</div>
        <div className="live-metrics">
          <Metric label="Подходы" value={workout.total_sets} tone="dark" />
          <Metric label="Объем" value={`${Math.round(workout.total_volume)} кг`} tone="dark" />
          <Metric label="Ккал" value={`~${Math.round(workout.estimated_calories)}`} tone="dark" />
        </div>
        <div className="live-actions">
          <button className="primary" onClick={() => setDrawerOpen(true)}>+ Добавить упражнение</button>
          <button className="ghost" onClick={() => setFinishOpen(true)}>Завершить</button>
          <button className="danger-ghost" onClick={() => setDiscardOpen(true)}>Отменить</button>
        </div>
      </div>

      {sortedItems.length === 0 ? (
        <EmptyWorkoutState onOpenDrawer={() => setDrawerOpen(true)} />
      ) : (
        <div className="exercise-journal">
          {sortedItems.map((item) => (
            <WorkoutExerciseCard
              key={item.id}
              item={item}
              pending={anyPending}
              onRecordSet={(payload: WorkoutSetInput) => mutations.recordWorkoutSet.mutate({ itemId: item.id, payload })}
              onRecordBatch={(sets) => mutations.recordWorkoutSetsBatch.mutate({ itemId: item.id, sets })}
              onRemoveItem={() => mutations.removeWorkoutItem.mutate(item.id)}
              onRemoveSet={(setId) => mutations.removeWorkoutSet.mutate({ itemId: item.id, setId })}
              onUpdateSet={(setId, payload) => mutations.updateWorkoutSet.mutate({ setId, payload })}
            />
          ))}
        </div>
      )}

      <button className="primary sticky-add" onClick={() => setDrawerOpen(true)}>+ Добавить упражнение</button>

      <AddExerciseDrawer
        open={drawerOpen}
        token={auth.accessToken}
        workout={workout}
        pending={mutations.addWorkoutItem.isPending}
        onClose={() => setDrawerOpen(false)}
        onAdd={addFromDrawer}
      />
      <FinishWorkoutDialog
        open={finishOpen}
        workout={workout}
        pending={mutations.finishWorkout.isPending}
        onClose={() => setFinishOpen(false)}
        onFinish={(notes) => mutations.finishWorkout.mutate({ workoutId: workout.id, notes })}
      />
      {discardOpen && (
        <div className="dialog-backdrop" onClick={() => setDiscardOpen(false)}>
          <div className="modal-card discard-dialog card" onClick={(event) => event.stopPropagation()}>
            <p className="eyebrow">Danger command</p>
            <h2>Отменить тренировку?</h2>
            <p>Запись будет помечена как отмененная и исчезнет из основной аналитики. Подходы не удаляются физически.</p>
            <div className="modal-actions">
              <button className="ghost" onClick={() => setDiscardOpen(false)}>Назад</button>
              <button className="danger" disabled={mutations.discardWorkout.isPending} onClick={() => mutations.discardWorkout.mutate(workout.id)}>
                {mutations.discardWorkout.isPending ? "Отмена..." : "Отменить тренировку"}
              </button>
            </div>
          </div>
        </div>
      )}
    </section>
  );
}
