import { createMemo, createSignal, For, Show } from "solid-js";
import { format, addDays, subDays, startOfWeek, addWeeks, subWeeks, parseISO, isSameDay, isWithinInterval } from "date-fns";
import { ChevronLeft, ChevronRight, Circle, CheckCircle } from "lucide-solid";

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

export default function TimelineRoute() {
  const app = useApp();
  const workspaceSlug = () => app.primaryWorkspace()?.slug ?? "personal";
  const [cursorDate, setCursorDate] = createSignal(new Date());

  const tasks = createMemo(() =>
    app.state.tasks.filter(t => t.workspaceSlug === workspaceSlug() && (t.dueAt || t.scheduledStart))
  );

  const events = createMemo(() =>
    app.state.events.filter(e => e.workspaceSlug === workspaceSlug())
  );

  const visibleDays = createMemo(() => {
    const start = startOfWeek(cursorDate(), { weekStartsOn: 1 });
    return Array.from({ length: 14 }, (_, i) => addDays(start, i));
  });

  const rangeLabel = createMemo(() => {
    const days = visibleDays();
    const start = days[0];
    const end = days[days.length - 1];
    return `${format(start, "MMM d")} - ${format(end, "MMM d, yyyy")}`;
  });

  const itemsForDay = (day: Date) => {
    const taskItems = tasks()
      .filter(task => {
        if (task.dueAt && isSameDay(parseISO(task.dueAt), day)) return true;
        if (task.scheduledStart && isSameDay(parseISO(task.scheduledStart), day)) return true;
        return false;
      })
      .map(task => ({
        kind: "task" as const,
        id: task.id,
        title: task.title,
        color: task.color,
        status: task.status,
        date: task.dueAt || task.scheduledStart || ""
      }));

    const eventItems = events()
      .filter(event => isSameDay(parseISO(event.startsAt), day))
      .map(event => ({
        kind: "event" as const,
        id: event.id,
        title: event.title,
        color: event.color,
        status: "",
        date: event.startsAt
      }));

    return [...taskItems, ...eventItems].sort((a, b) => a.date.localeCompare(b.date));
  };

  const navigate = (direction: "prev" | "next") => {
    setCursorDate(direction === "next" ? addWeeks(cursorDate(), 1) : subWeeks(cursorDate(), 1));
  };

  const goToToday = () => setCursorDate(new Date());

  return (
    <div class="space-y-6">
      {/* Header */}
      <div class="flex items-center justify-between">
        <div>
          <h1 class="text-xl font-semibold">Timeline</h1>
          <p class="mt-1 text-sm text-[var(--text-muted)]">Visual project overview</p>
        </div>
        <div class="flex items-center gap-3">
          <button
            onClick={goToToday}
            class="px-3 py-1.5 rounded-lg border border-[var(--border)] text-sm hover:bg-[var(--surface-hover)]"
          >
            Today
          </button>
          <div class="flex items-center gap-2">
            <button
              onClick={() => navigate("prev")}
              class="p-1.5 rounded-lg hover:bg-[var(--surface-hover)]"
            >
              <ChevronLeft class="w-5 h-5" />
            </button>
            <span class="text-sm font-medium min-w-[160px] text-center">{rangeLabel()}</span>
            <button
              onClick={() => navigate("next")}
              class="p-1.5 rounded-lg hover:bg-[var(--surface-hover)]"
            >
              <ChevronRight class="w-5 h-5" />
            </button>
          </div>
        </div>
      </div>

      {/* Timeline grid */}
      <div class="rounded-lg border border-[var(--border)] bg-[var(--surface)] overflow-hidden">
        {/* Day headers */}
        <div class="grid grid-cols-14 border-b border-[var(--border)]">
          <For each={visibleDays()}>
            {day => {
              const isToday = isSameDay(day, new Date());
              return (
                <div class={`px-2 py-2 text-center border-r border-[var(--border)] last:border-r-0 ${isToday ? "bg-[var(--accent-muted)]" : ""}`}>
                  <div class="text-xs text-[var(--text-muted)]">{format(day, "EEE")}</div>
                  <div class={`text-sm font-medium ${isToday ? "text-[var(--accent)]" : ""}`}>
                    {format(day, "d")}
                  </div>
                </div>
              );
            }}
          </For>
        </div>

        {/* Timeline content */}
        <div class="grid grid-cols-14 min-h-[400px]">
          <For each={visibleDays()}>
            {day => {
              const items = itemsForDay(day);
              const isToday = isSameDay(day, new Date());
              return (
                <div class={`border-r border-[var(--border)] last:border-r-0 p-1 ${isToday ? "bg-[var(--accent-muted)]/30" : ""}`}>
                  <div class="space-y-1">
                    <For each={items.slice(0, 6)}>
                      {item => {
                        const color = getColorStyle(item.color);
                        return (
                          <div
                            class="rounded px-1.5 py-0.5 text-xs truncate cursor-pointer hover:opacity-80"
                            style={{ background: color.bg, color: color.text }}
                            title={item.title}
                          >
                            <div class="flex items-center gap-1">
                              <Show when={item.kind === "task"}>
                                {item.status === "done" ? (
                                  <CheckCircle class="w-3 h-3 flex-shrink-0" />
                                ) : (
                                  <Circle class="w-3 h-3 flex-shrink-0" />
                                )}
                              </Show>
                              <span class="truncate">{item.title}</span>
                            </div>
                          </div>
                        );
                      }}
                    </For>
                    <Show when={items.length > 6}>
                      <div class="text-xs text-[var(--text-muted)] px-1.5">
                        +{items.length - 6} more
                      </div>
                    </Show>
                  </div>
                </div>
              );
            }}
          </For>
        </div>
      </div>

      {/* Legend */}
      <div class="flex items-center gap-4 text-sm text-[var(--text-muted)]">
        <div class="flex items-center gap-1.5">
          <Circle class="w-4 h-4" />
          <span>Task</span>
        </div>
        <div class="flex items-center gap-1.5">
          <CheckCircle class="w-4 h-4 text-green-500" />
          <span>Completed</span>
        </div>
        <div class="flex items-center gap-1.5">
          <div class="w-4 h-4 rounded bg-[var(--accent-muted)]" />
          <span>Today</span>
        </div>
      </div>
    </div>
  );
}