import { differenceInSeconds, parseISO } from "date-fns";
import { createMemo, createSignal, For, onCleanup, onMount, Show } from "solid-js";

import { useApp } from "~/lib/app-context";
import { formatStamp } from "~/lib/utils";

const presets = [
  { mode: "focus" as const, label: "Focus", seconds: 1500 },
  { mode: "short_break" as const, label: "Short break", seconds: 300 },
  { mode: "long_break" as const, label: "Long break", seconds: 900 }
];

export default function FocusRoute() {
  const app = useApp();
  const workspaceSlug = () => app.primaryWorkspace()?.slug ?? "personal";
  const [now, setNow] = createSignal(Date.now());
  const [selectedTaskId, setSelectedTaskId] = createSignal<string | undefined>(app.state.tasks[0]?.id);
  const [selectedMode, setSelectedMode] = createSignal(presets[0]);

  onMount(() => {
    const timer = window.setInterval(() => setNow(Date.now()), 1000);
    onCleanup(() => window.clearInterval(timer));
  });

  const active = createMemo(() => app.activeFocusSession());
  const remaining = createMemo(() => {
    const session = active();
    if (!session) {
      return selectedMode().seconds;
    }

    const startedAt = parseISO(session.startedAt).getTime();
    const pausedBase = session.pausedTotalSeconds;
    const pausedLive = session.pausedAt ? differenceInSeconds(new Date(now()), parseISO(session.pausedAt)) : 0;
    const elapsed = differenceInSeconds(new Date(now()), new Date(startedAt)) - pausedBase - pausedLive;
    return Math.max(session.durationSeconds - elapsed, 0);
  });

  const display = createMemo(() => {
    const seconds = remaining();
    const minutes = Math.floor(seconds / 60)
      .toString()
      .padStart(2, "0");
    const remainder = Math.floor(seconds % 60)
      .toString()
      .padStart(2, "0");
    return `${minutes}:${remainder}`;
  });

  const start = async () =>
    app.startFocusSession(workspaceSlug(), selectedMode().mode, selectedMode().seconds, selectedTaskId());

  const sessions = createMemo(() =>
    app.state.focusSessions.filter(session => session.workspaceSlug === workspaceSlug()),
  );

  return (
    <div class="mx-auto max-w-2xl space-y-6">
      {/* Page header */}
      <div>
        <h1 class="text-xl font-semibold">Focus</h1>
        <p class="mt-1 text-sm text-[var(--text-muted)]">Hold the line for one clean block</p>
      </div>

      {/* Timer card */}
      <div class="rounded-lg border border-[var(--border)] bg-[var(--surface)] p-6">
        {/* Timer display */}
        <div class="text-center">
          <div class="text-6xl font-semibold tracking-tight">{display()}</div>
          <p class="mt-2 text-sm text-[var(--text-muted)]">
            {active() ? active()!.mode.replace("_", " ") : "Ready to start"}
          </p>
        </div>

        {/* Preset selector */}
        <div class="mt-6 flex justify-center gap-2">
          <For each={presets}>
            {preset => (
              <button
                class="rounded-md px-4 py-2 text-sm font-medium transition-colors"
                classList={{
                  "bg-[var(--accent-subtle)] text-[var(--accent)]": selectedMode().mode === preset.mode && !Boolean(active()),
                  "bg-[var(--bg-subtle)] text-[var(--text-muted)] hover:text-[var(--text)]": selectedMode().mode !== preset.mode || Boolean(active())
                }}
                onClick={() => setSelectedMode(preset)}
                disabled={Boolean(active())}
              >
                {preset.label}
              </button>
            )}
          </For>
        </div>

        {/* Task selector */}
        <div class="mt-6">
          <select
            class="input-base"
            value={selectedTaskId()}
            onInput={event => setSelectedTaskId(event.currentTarget.value)}
            disabled={Boolean(active())}
          >
            <option value="">No task selected</option>
            <For each={app.state.tasks.filter(task => task.workspaceSlug === workspaceSlug())}>
              {task => <option value={task.id}>{task.title}</option>}
            </For>
          </select>
        </div>

        {/* Controls */}
        <div class="mt-6 flex justify-center gap-3">
          <Show when={!active()}>
            <button
              class="button-primary px-6 py-2 text-sm"
              onClick={() => void start()}
            >
              Start session
            </button>
          </Show>
          <Show when={active()}>
            <button
              class="button-secondary px-4 py-2 text-sm"
              onClick={() => active() && (active()!.pausedAt ? app.resumeFocusSession(active()!.id) : app.pauseFocusSession(active()!.id))}
            >
              {active()?.pausedAt ? "Resume" : "Pause"}
            </button>
            <button
              class="button-primary px-4 py-2 text-sm"
              onClick={() => active() && app.completeFocusSession(active()!.id)}
            >
              Complete
            </button>
          </Show>
        </div>
      </div>

      {/* Session history */}
      <div class="rounded-lg border border-[var(--border)] bg-[var(--surface)]">
        <div class="border-b border-[var(--border)] px-4 py-3">
          <h2 class="text-sm font-medium">Session history</h2>
        </div>
        <div class="divide-y divide-[var(--border)]">
          <Show when={sessions().length === 0}>
            <div class="px-4 py-6 text-center text-sm text-[var(--text-muted)]">
              No sessions recorded yet
            </div>
          </Show>
          <For each={sessions().slice(0, 10)}>
            {session => (
              <div class="flex items-center justify-between px-4 py-3">
                <div>
                  <p class="text-sm font-medium">{session.mode.replace("_", " ")}</p>
                  <p class="text-xs text-[var(--text-muted)]">{formatStamp(session.startedAt)}</p>
                </div>
                <span class="text-sm text-[var(--text-muted)]">
                  {Math.round(session.durationSeconds / 60)} min
                </span>
              </div>
            )}
          </For>
        </div>
      </div>
    </div>
  );
}
