"use client";

import { useCallback, useEffect, useState } from "react";
import { createClient, getBrowserUserId } from "@/lib/supabase/client";
import { getHabitStreak } from "@/lib/habits";
import { playHabitComplete } from "@/lib/sounds";
import type { Habit, HabitCompletion } from "@/types";

export function useHabits() {
  const [habits, setHabits] = useState<Habit[]>([]);
  const [completions, setCompletions] = useState<HabitCompletion[]>([]);
  const [loading, setLoading] = useState(true);
  const [userId, setUserId] = useState<string | null>(null);
  const supabase = createClient();

  useEffect(() => {
    void getBrowserUserId().then(setUserId).catch(() => setUserId(null));
  }, []);

  const fetchHabits = useCallback(async () => {
    const { data } = await supabase
      .from("habits")
      .select("*")
      .eq("archived", false)
      .order("sort_order")
      .order("created_at");
    setHabits(data || []);
    setLoading(false);
  }, [supabase]);

  const fetchCompletions = useCallback(
    async (startDate: string, endDate: string) => {
      const { data } = await supabase
        .from("habit_completions")
        .select("*")
        .gte("completed_date", startDate)
        .lte("completed_date", endDate);
      setCompletions(data || []);
    },
    [supabase]
  );

  useEffect(() => {
    const timer = window.setTimeout(() => {
      void fetchHabits();
    }, 0);

    return () => window.clearTimeout(timer);
  }, [fetchHabits]);

  async function createHabit(input: {
    name: string;
    icon?: string;
    color?: string;
    frequency?: string;
  }) {
    if (!userId) throw new Error("Not authenticated");
    const { data, error } = await supabase
      .from("habits")
      .insert({
        user_id: userId,
        name: input.name,
        icon: input.icon || "✅",
        color: input.color || "#6366f1",
        frequency: input.frequency || "daily",
      })
      .select()
      .single();
    if (error) throw error;
    setHabits((prev) => [...prev, data]);
    return data as Habit;
  }

  async function updateHabit(
    id: string,
    input: Partial<{ name: string; icon: string; color: string; archived: boolean }>
  ) {
    const { error } = await supabase.from("habits").update(input).eq("id", id);
    if (error) throw error;
    if (input.archived) {
      setHabits((prev) => prev.filter((h) => h.id !== id));
    } else {
      setHabits((prev) => prev.map((h) => (h.id === id ? { ...h, ...input } : h)));
    }
  }

  async function deleteHabit(id: string) {
    const { error } = await supabase.from("habits").delete().eq("id", id);
    if (error) throw error;
    setHabits((prev) => prev.filter((h) => h.id !== id));
  }

  async function toggleCompletion(habitId: string, date: string) {
    if (!userId) throw new Error("Not authenticated");

    const existing = completions.find(
      (c) => c.habit_id === habitId && c.completed_date === date
    );

    if (existing) {
      await supabase.from("habit_completions").delete().eq("id", existing.id);
      setCompletions((prev) => prev.filter((c) => c.id !== existing.id));
    } else {
      const { data, error } = await supabase
        .from("habit_completions")
        .insert({ habit_id: habitId, user_id: userId, completed_date: date })
        .select()
        .single();
      if (error) throw error;
      setCompletions((prev) => [...prev, data]);
      playHabitComplete();
    }
  }

  function isCompleted(habitId: string, date: string): boolean {
    return completions.some(
      (c) => c.habit_id === habitId && c.completed_date === date
    );
  }

  function getStreak(habitId: string): number {
    const completedDates = completions
      .filter((c) => c.habit_id === habitId)
      .map((c) => c.completed_date);

    return getHabitStreak(completedDates);
  }

  return {
    habits,
    completions,
    loading,
    createHabit,
    updateHabit,
    deleteHabit,
    toggleCompletion,
    isCompleted,
    getStreak,
    fetchCompletions,
    refetch: fetchHabits,
  };
}
