"use client";

import { useState, useEffect, useMemo } from "react";
import {
  Plus,
  Flame,
  Archive,
  ChevronLeft,
  ChevronRight,
  CheckCheck,
} from "lucide-react";
import { Modal } from "@/components/ui/modal";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Skeleton } from "@/components/ui/skeleton";
import { cn } from "@/lib/utils";
import { useHabits } from "@/hooks/use-habits";

const ICONS = ["✅", "💪", "📖", "🧘", "🏃", "💧", "🥗", "💤", "📝", "🎯", "🧠", "💰", "📱", "🚫", "⏰", "🔥"];
const COLORS = ["#6366f1", "#ec4899", "#f59e0b", "#10b981", "#3b82f6", "#8b5cf6", "#ef4444", "#06b6d4"];
const DAY_LABELS = ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"];

function getToday(): string {
  const d = new Date();
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
}

function addDays(date: string, n: number): string {
  const d = new Date(date + "T00:00:00");
  d.setDate(d.getDate() + n);
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
}

function getWeekDates(offset: number): string[] {
  const today = getToday();
  const d = new Date(today + "T00:00:00");
  // Anchor to Monday of current week
  const dow = d.getDay() === 0 ? 6 : d.getDay() - 1; // 0=Mon, 6=Sun
  const monday = addDays(today, -dow + offset * 7);
  return Array.from({ length: 7 }, (_, i) => addDays(monday, i));
}

/** Last 52 weeks × 7 days grid (364 days) ending today */
function buildYearGrid(): string[][] {
  const today = getToday();
  const d = new Date(today + "T00:00:00");
  const dow = d.getDay() === 0 ? 6 : d.getDay() - 1;
  // Start from the Monday 52 weeks ago (364 days)
  const start = addDays(today, -(52 * 7 - 1) - dow);
  const weeks: string[][] = [];
  for (let w = 0; w < 53; w++) {
    const week: string[] = [];
    for (let d2 = 0; d2 < 7; d2++) {
      const date = addDays(start, w * 7 + d2);
      if (date <= today) week.push(date);
      else week.push("");
    }
    if (week.some(Boolean)) weeks.push(week);
  }
  return weeks;
}

function buildMonthBuckets(weeks: string[][]): { key: string; label: string; dates: string[] }[] {
  const buckets = new Map<string, { key: string; label: string; dates: string[] }>();

  weeks.flat().forEach((date) => {
    if (!date) return;
    const d = new Date(date + "T00:00:00");
    const key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}`;

    if (!buckets.has(key)) {
      buckets.set(key, {
        key,
        label: d.toLocaleDateString("de-DE", { month: "short" }),
        dates: [],
      });
    }

    buckets.get(key)!.dates.push(date);
  });

  return Array.from(buckets.values());
}

export default function HabitsPage() {
  const {
    habits,
    completions,
    loading,
    createHabit,
    updateHabit,
    toggleCompletion,
    isCompleted,
    getStreak,
    fetchCompletions,
  } = useHabits();

  const [weekOffset, setWeekOffset] = useState(0);
  const [formOpen, setFormOpen] = useState(false);
  const [newName, setNewName] = useState("");
  const [newIcon, setNewIcon] = useState("✅");
  const [newColor, setNewColor] = useState("#6366f1");
  const [submitting, setSubmitting] = useState(false);

  const today = getToday();
  const weekDates = useMemo(() => getWeekDates(weekOffset), [weekOffset]);
  const yearGrid = useMemo(() => buildYearGrid(), []);
  const monthBuckets = useMemo(() => buildMonthBuckets(yearGrid), [yearGrid]);

  // Fetch a full year of completions once — enough for week nav + heatmap
  useEffect(() => {
    const yearStart = addDays(today, -365);
    void fetchCompletions(yearStart, today);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  async function handleCreate() {
    if (!newName.trim() || submitting) return;
    setSubmitting(true);
    await createHabit({ name: newName.trim(), icon: newIcon, color: newColor });
    setNewName(""); setNewIcon("✅"); setNewColor("#6366f1");
    setSubmitting(false); setFormOpen(false);
  }

  // Heatmap: completions per date (count, max = habits.length)
  const completionsByDate = useMemo(() => {
    const map: Record<string, Set<string>> = {};
    for (const c of completions) {
      if (!map[c.completed_date]) map[c.completed_date] = new Set();
      map[c.completed_date].add(c.habit_id);
    }
    return map;
  }, [completions]);

  const monthSummaries = useMemo(() => {
    return monthBuckets.map((month) => {
      const done = month.dates.reduce((sum, date) => sum + (completionsByDate[date]?.size ?? 0), 0);
      const possible = month.dates.length * Math.max(1, habits.length);
      const ratio = possible > 0 ? done / possible : 0;
      return { ...month, done, ratio };
    });
  }, [completionsByDate, habits.length, monthBuckets]);

  // Today stats
  const todayDone = habits.filter((h) => isCompleted(h.id, today)).length;
  const todayTotal = habits.length;

  // Best streak across all habits
  const bestStreak = habits.reduce((max, h) => Math.max(max, getStreak(h.id)), 0);

  // Total completions ever (in loaded range)
  const totalCompletions = completions.length;

  function heatIntensity(date: string): 0 | 1 | 2 | 3 | 4 {
    if (!date) return 0;
    const done = completionsByDate[date]?.size ?? 0;
    if (done === 0) return 0;
    if (habits.length === 0) return 1;
    const ratio = done / habits.length;
    if (ratio >= 1) return 4;
    if (ratio >= 0.66) return 3;
    if (ratio >= 0.33) return 2;
    return 1;
  }

  const heatColors = [
    "bg-white/[0.07]",
    "bg-emerald-500/20",
    "bg-emerald-500/35",
    "bg-emerald-500/55",
    "bg-emerald-500/80",
  ];

  const weekLabel = (() => {
    if (weekOffset === 0) return "Diese Woche";
    const s = new Date(weekDates[0] + "T00:00:00");
    const e = new Date(weekDates[6] + "T00:00:00");
    const opts: Intl.DateTimeFormatOptions = { day: "numeric", month: "short" };
    return `${s.toLocaleDateString("de-DE", opts)} – ${e.toLocaleDateString("de-DE", opts)}`;
  })();

  if (loading) {
    return (
      <div className="flex gap-5 h-[calc(100dvh-72px)]">
        <Skeleton className="w-72 h-full rounded-2xl" />
        <Skeleton className="flex-1 h-full rounded-2xl" />
      </div>
    );
  }

  return (
    <div className="flex gap-5 h-[calc(100dvh-72px)] overflow-hidden -mt-1">

      {/* ── Left Sidebar ───────────────────────────────────────────── */}
      <aside className="hidden lg:flex w-72 shrink-0 flex-col gap-3 overflow-y-auto scrollbar-none">

        {/* Stats */}
        <div className="rounded-2xl border border-white/[0.06] bg-white/[0.02] p-4">
          <p className="text-[11px] font-semibold uppercase tracking-widest text-white/30 mb-4">Übersicht</p>
          <div className="grid grid-cols-3 gap-3">
            <div className="flex flex-col gap-1">
              <span className="text-2xl font-bold text-white leading-none">{todayDone}<span className="text-base text-white/25">/{todayTotal}</span></span>
              <span className="text-[10px] text-white/25 uppercase tracking-wider">Heute</span>
            </div>
            <div className="flex flex-col gap-1">
              <span className="text-2xl font-bold text-orange-400 leading-none flex items-center gap-1">{bestStreak}<Flame className="h-4 w-4" /></span>
              <span className="text-[10px] text-white/25 uppercase tracking-wider">Best Streak</span>
            </div>
            <div className="flex flex-col gap-1">
              <span className="text-2xl font-bold text-white leading-none">{totalCompletions}</span>
              <span className="text-[10px] text-white/25 uppercase tracking-wider">Gesamt</span>
            </div>
          </div>

          {/* Today progress bar */}
          {todayTotal > 0 && (
            <div className="mt-4">
              <div className="flex justify-between mb-1.5">
                <span className="text-[10px] text-white/25">Heute erledigt</span>
                <span className="text-[10px] text-emerald-400/70">{Math.round(todayDone / todayTotal * 100)}%</span>
              </div>
              <div className="h-1.5 rounded-full bg-white/[0.06] overflow-hidden">
                <div
                  className="h-full rounded-full bg-emerald-500/70 transition-all duration-500"
                  style={{ width: `${(todayDone / todayTotal) * 100}%` }}
                />
              </div>
            </div>
          )}
        </div>

        {/* Year heatmap */}
        <div className="rounded-2xl border border-white/[0.06] bg-white/[0.02] p-4">
          <div className="mb-3 flex items-center justify-between gap-3">
            <p className="text-[11px] font-semibold uppercase tracking-widest text-white/30">Jahr</p>
            <span className="rounded-full border border-white/[0.06] bg-white/[0.03] px-2 py-0.5 text-[9px] font-semibold uppercase tracking-[0.14em] text-white/22">
              12M
            </span>
          </div>

          {/* Grid: rows=days, cols=weeks */}
          <div
            className="grid grid-flow-col grid-rows-7 gap-px"
            style={{ gridTemplateColumns: `repeat(${yearGrid.length}, minmax(0, 1fr))` }}
          >
            {yearGrid.flatMap((week, wi) =>
              week.map((date, di) => {
                const intensity = heatIntensity(date);
                return (
                  <div
                    key={`${wi}-${di}-${date || "empty"}`}
                    title={date ? `${date}: ${completionsByDate[date]?.size ?? 0}/${habits.length}` : ""}
                    className={cn(
                      "aspect-square min-w-0 rounded-[2px] transition-colors",
                      date ? heatColors[intensity] : "bg-transparent"
                    )}
                  />
                );
              })
            )}
          </div>

          {/* Month rail */}
          <div className="mt-3 grid grid-cols-4 gap-1">
            {monthSummaries.map((month) => (
              <div
                key={month.key}
                title={`${month.label}: ${month.done} Completions`}
                className="overflow-hidden rounded-lg border border-white/[0.06] bg-white/[0.025]"
              >
                <div
                  className="h-0.5 rounded-full bg-emerald-400/70"
                  style={{
                    width: month.done > 0
                      ? `${Math.max(8, Math.min(100, Math.round(month.ratio * 100)))}%`
                      : "0%",
                  }}
                />
                <div className="flex items-center justify-between gap-1 px-1.5 py-1">
                  <span className="truncate text-[9px] font-bold uppercase tracking-[0.08em] text-white/38">
                    {month.label}
                  </span>
                  <span className="text-[8px] font-semibold tabular-nums text-emerald-300/45">
                    {Math.round(month.ratio * 100)}%
                  </span>
                </div>
              </div>
            ))}
          </div>

          {/* Legend */}
          <div className="flex items-center gap-1.5 mt-2.5">
            <span className="text-[9px] text-white/15">Weniger</span>
            {[0, 1, 2, 3, 4].map((i) => (
              <div key={i} className={cn("h-[7px] w-[7px] rounded-[2px]", heatColors[i])} />
            ))}
            <span className="text-[9px] text-white/15">Mehr</span>
          </div>
        </div>

        {/* Per-habit streaks */}
        {habits.length > 0 && (
          <div className="rounded-2xl border border-white/[0.06] bg-white/[0.02] p-4 flex-1">
            <p className="text-[11px] font-semibold uppercase tracking-widest text-white/30 mb-3">Streaks</p>
            <div className="space-y-2.5">
              {[...habits]
                .sort((a, b) => getStreak(b.id) - getStreak(a.id))
                .map((h) => {
                  const s = getStreak(h.id);
                  const done = isCompleted(h.id, today);
                  return (
                    <div key={h.id} className="flex items-center gap-2.5">
                      <span className="text-[15px] leading-none">{h.icon}</span>
                      <div className="flex-1 min-w-0">
                        <div className="flex items-center justify-between">
                          <span className="text-[12px] text-white/50 truncate">{h.name}</span>
                          <span className={cn("text-[11px] font-bold ml-2", s > 0 ? "text-orange-400" : "text-white/20")}>
                            {s > 0 ? `${s}🔥` : "—"}
                          </span>
                        </div>
                        <div className="h-[3px] rounded-full bg-white/[0.05] mt-1 overflow-hidden">
                          <div
                            className="h-full rounded-full transition-all duration-500"
                            style={{
                              width: s > 0 ? `${Math.min(100, s * 5)}%` : done ? "5%" : "0%",
                              backgroundColor: h.color,
                              opacity: 0.7,
                            }}
                          />
                        </div>
                      </div>
                    </div>
                  );
                })}
            </div>
          </div>
        )}
      </aside>

      {/* ── Main Area ──────────────────────────────────────────────── */}
      <main className="flex-1 flex flex-col min-w-0 rounded-2xl border border-white/[0.06] bg-white/[0.02] overflow-hidden">

        {/* Top bar */}
        <div className="flex items-center justify-between px-6 py-4 border-b border-white/[0.05] shrink-0">
          <div className="flex items-center gap-3">
            <button
              onClick={() => setWeekOffset((p) => p - 1)}
              className="h-7 w-7 rounded-lg flex items-center justify-center text-white/25 hover:bg-white/[0.06] hover:text-white/60 transition-colors cursor-pointer"
            >
              <ChevronLeft className="h-4 w-4" />
            </button>
            <span className={cn(
              "text-sm font-semibold px-3 py-1 rounded-lg",
              weekOffset === 0 ? "bg-emerald-500/[0.10] text-emerald-300" : "text-white/50"
            )}>
              {weekLabel}
            </span>
            <button
              onClick={() => setWeekOffset((p) => Math.min(p + 1, 0))}
              disabled={weekOffset >= 0}
              className="h-7 w-7 rounded-lg flex items-center justify-center text-white/25 hover:bg-white/[0.06] hover:text-white/60 transition-colors cursor-pointer disabled:opacity-20 disabled:cursor-default"
            >
              <ChevronRight className="h-4 w-4" />
            </button>
          </div>

          <button
            onClick={() => setFormOpen(true)}
            className="flex items-center gap-2 rounded-xl border border-emerald-500/25 bg-emerald-500/[0.08] px-3.5 py-1.5 text-[12px] font-semibold text-emerald-300 hover:bg-emerald-500/[0.14] transition-colors cursor-pointer"
          >
            <Plus className="h-3.5 w-3.5" />
            Neues Habit
          </button>
        </div>

        {/* Today's progress bar */}
        {weekOffset === 0 && habits.length > 0 && (
          <div className="px-6 py-3 border-b border-white/[0.04] shrink-0">
            <div className="flex items-center gap-3">
              <CheckCheck className="h-3.5 w-3.5 text-emerald-400/60 shrink-0" />
              <div className="flex-1 h-1.5 rounded-full bg-white/[0.05] overflow-hidden">
                <div
                  className="h-full rounded-full bg-emerald-500/60 transition-all duration-700"
                  style={{ width: todayTotal > 0 ? `${(todayDone / todayTotal) * 100}%` : "0%" }}
                />
              </div>
              <span className="text-[11px] text-white/25 shrink-0 font-medium">
                {todayDone}/{todayTotal} heute
              </span>
            </div>
          </div>
        )}

        {/* Column headers */}
        {habits.length > 0 && (
          <div className="grid grid-cols-[1fr_repeat(7,44px)_56px] gap-1 items-center px-5 py-2.5 border-b border-white/[0.04] shrink-0">
            <div />
            {weekDates.map((date, i) => {
              const isToday = date === today;
              return (
                <div key={date} className="flex flex-col items-center gap-0.5">
                  <span className={cn("text-[9px] font-bold uppercase tracking-wider", isToday ? "text-emerald-400" : "text-white/20")}>
                    {DAY_LABELS[i]}
                  </span>
                  <span className={cn(
                    "text-[11px] font-semibold w-5 h-5 flex items-center justify-center rounded-full",
                    isToday ? "bg-emerald-500/20 text-emerald-300" : "text-white/20"
                  )}>
                    {new Date(date + "T00:00:00").getDate()}
                  </span>
                </div>
              );
            })}
            <div className="flex justify-center">
              <Flame className="h-3 w-3 text-orange-400/40" />
            </div>
          </div>
        )}

        {/* Habit rows */}
        <div className="flex-1 overflow-y-auto px-5 py-3 space-y-1.5">
          {habits.length === 0 ? (
            <div className="flex flex-col items-center justify-center h-full gap-3 text-center">
              <div className="text-4xl">🎯</div>
              <p className="text-sm text-white/25 max-w-xs">
                Noch keine Habits. Fang mit einem kleinen an — Konsistenz schlägt Intensität.
              </p>
              <button
                onClick={() => setFormOpen(true)}
                className="mt-2 flex items-center gap-2 rounded-xl border border-emerald-500/25 bg-emerald-500/[0.08] px-4 py-2 text-[13px] font-semibold text-emerald-300 hover:bg-emerald-500/[0.14] transition-colors cursor-pointer"
              >
                <Plus className="h-4 w-4" /> Erstes Habit erstellen
              </button>
            </div>
          ) : (
            habits.map((habit) => {
              const streak = getStreak(habit.id);
              const doneToday = isCompleted(habit.id, today);
              return (
                <div
                  key={habit.id}
                  className={cn(
                    "group grid grid-cols-[1fr_repeat(7,44px)_56px] gap-1 items-center rounded-xl px-4 py-3 border transition-all",
                    doneToday && weekOffset === 0
                      ? "border-white/[0.07] bg-white/[0.03]"
                      : "border-transparent hover:border-white/[0.05] hover:bg-white/[0.02]"
                  )}
                >
                  {/* Habit name */}
                  <div className="flex items-center gap-2.5 min-w-0">
                    <span className="text-[16px] leading-none shrink-0">{habit.icon}</span>
                    <span className={cn("text-[13px] font-medium truncate", doneToday && weekOffset === 0 ? "text-white/70" : "text-white/45")}>
                      {habit.name}
                    </span>
                    <button
                      onClick={() => updateHabit(habit.id, { archived: true })}
                      className="opacity-0 group-hover:opacity-100 ml-auto p-1 text-white/15 hover:text-white/40 transition-all cursor-pointer shrink-0"
                      title="Archivieren"
                    >
                      <Archive className="h-3 w-3" />
                    </button>
                  </div>

                  {/* Day dots */}
                  {weekDates.map((date) => {
                    const done = isCompleted(habit.id, date);
                    const isFuture = date > today;
                    return (
                      <button
                        key={date}
                        onClick={() => !isFuture && void toggleCompletion(habit.id, date)}
                        disabled={isFuture}
                        className={cn(
                          "w-8 h-8 rounded-xl mx-auto flex items-center justify-center transition-all cursor-pointer text-[14px]",
                          done
                            ? "scale-100"
                            : "scale-95 border border-white/[0.08] bg-white/[0.025] hover:border-white/[0.18] hover:bg-white/[0.045] hover:scale-100",
                          isFuture && "cursor-not-allowed border-white/[0.03] bg-transparent opacity-25"
                        )}
                        style={done ? {
                          backgroundColor: habit.color + "22",
                          boxShadow: `0 0 0 1.5px ${habit.color}40`,
                        } : undefined}
                      >
                        {done
                          ? <span style={{ color: habit.color }}>✓</span>
                          : <span className="block h-3 w-3 rounded-full border-2 border-white/[0.36] bg-white/[0.04] shadow-[0_0_0_1px_rgba(255,255,255,0.04)]" />
                        }
                      </button>
                    );
                  })}

                  {/* Streak */}
                  <div className="text-center">
                    {streak > 0 ? (
                      <span className="text-[12px] font-bold text-orange-400">{streak}🔥</span>
                    ) : (
                      <span className="text-[11px] text-white/15">—</span>
                    )}
                  </div>
                </div>
              );
            })
          )}
        </div>
      </main>

      {/* ── Create Modal ──────────────────────────────────────────── */}
      {formOpen && (
        <Modal open={formOpen} onClose={() => setFormOpen(false)} title="Neues Habit" className="max-w-md">
          <div className="space-y-4">
            <Input
              placeholder="Habit Name..."
              value={newName}
              onChange={(e) => setNewName(e.target.value)}
              autoFocus
              onKeyDown={(e) => e.key === "Enter" && void handleCreate()}
            />

            <div>
              <p className="text-xs text-white/40 mb-2">Icon</p>
              <div className="flex flex-wrap gap-1.5">
                {ICONS.map((icon) => (
                  <button
                    key={icon}
                    onClick={() => setNewIcon(icon)}
                    className={cn(
                      "w-9 h-9 rounded-lg flex items-center justify-center text-lg transition-all cursor-pointer border",
                      newIcon === icon ? "border-emerald-500/40 bg-emerald-500/[0.10]" : "border-white/[0.06] hover:bg-white/[0.05]"
                    )}
                  >
                    {icon}
                  </button>
                ))}
              </div>
            </div>

            <div>
              <p className="text-xs text-white/40 mb-2">Farbe</p>
              <div className="flex gap-2">
                {COLORS.map((color) => (
                  <button
                    key={color}
                    onClick={() => setNewColor(color)}
                    className={cn(
                      "w-8 h-8 rounded-full transition-all cursor-pointer ring-2 ring-offset-2 ring-offset-[#0a0a0d]",
                      newColor === color ? "ring-white/40" : "ring-transparent"
                    )}
                    style={{ backgroundColor: color }}
                  />
                ))}
              </div>
            </div>

            {/* Preview */}
            <div className="rounded-xl border border-white/[0.06] bg-white/[0.02] px-4 py-3 flex items-center gap-3">
              <span className="text-[18px]">{newIcon}</span>
              <span className="text-[13px] font-medium text-white/60">{newName || "Habit Name"}</span>
              <div className="ml-auto w-4 h-4 rounded-full" style={{ backgroundColor: newColor }} />
            </div>

            <div className="flex justify-end gap-2 pt-1">
              <Button variant="ghost" onClick={() => setFormOpen(false)}>Abbrechen</Button>
              <Button onClick={() => void handleCreate()} disabled={!newName.trim() || submitting}>
                {submitting ? "Erstelle…" : "Erstellen"}
              </Button>
            </div>
          </div>
        </Modal>
      )}
    </div>
  );
}
