import { useDatabase } from './useDatabase';
import { Q } from '@nozbe/watermelondb';
import { useEffect, useState, useMemo } from 'react';
import Task from '../models/Task';
import { startOfMonth, endOfMonth } from 'date-fns';

export function useTasksInMonth(monthDate: Date) {
  const { collections } = useDatabase();
  const [tasks, setTasks] = useState<Task[]>([]);
  const [loading, setLoading] = useState(true);

  const range = useMemo(() => {
    const s = startOfMonth(monthDate);
    s.setHours(0, 0, 0, 0);
    const e = endOfMonth(monthDate);
    e.setHours(23, 59, 59, 999);
    return { start: s.getTime(), end: e.getTime() };
  }, [monthDate]);

  useEffect(() => {
    let mounted = true;
    setLoading(true);
    const subscription = collections.tasks
      .query(
        Q.where('due_date', Q.between(range.start, range.end)),
        Q.sortBy('due_date', 'asc')
      )
      .observe()
      .subscribe({
        next: (result) => {
          if (mounted) {
            setTasks(result);
            setLoading(false);
          }
        },
        error: () => {
          if (mounted) setLoading(false);
        },
      });

    return () => {
      mounted = false;
      subscription.unsubscribe();
    };
  }, [collections, range.start, range.end]);

  const byDay = useMemo(() => {
    const map: Record<number, Task[]> = {};
    for (const t of tasks) {
      const key = new Date(t.dueDate).getDate();
      const bucket = map[key] ?? [];
      bucket.push(t);
      map[key] = bucket;
    }
    return map;
  }, [tasks]);

  return { tasks, byDay, loading };
}

export function useTasks(categoryId?: string, showCompleted = false) {
  const { collections } = useDatabase();
  const [tasks, setTasks] = useState<Task[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    let mounted = true;
    const conditions: any[] = [];

    if (categoryId && categoryId !== 'all') {
      conditions.push(Q.where('category_id', categoryId));
    }

    if (showCompleted) {
      conditions.push(Q.where('completed', true));
    } else {
      conditions.push(Q.where('completed', false));
    }

    const query = conditions.length > 0
      ? collections.tasks.query(Q.and(...conditions))
      : collections.tasks.query();

    const subscription = query
      .observe()
      .subscribe({
        next: (result) => {
          if (mounted) {
            setTasks(result);
            setLoading(false);
          }
        },
        error: () => {
          if (mounted) setLoading(false);
        },
      });

    return () => {
      mounted = false;
      subscription.unsubscribe();
    };
  }, [collections, categoryId, showCompleted]);

  return { tasks, loading };
}

export function useTasksByDate(date: Date) {
  const { collections } = useDatabase();
  const [tasks, setTasks] = useState<Task[]>([]);
  const [loading, setLoading] = useState(true);

  const startOfDay = useMemo(() => {
    const d = new Date(date);
    d.setHours(0, 0, 0, 0);
    return d;
  }, [date]);
  const endOfDay = useMemo(() => {
    const d = new Date(date);
    d.setHours(23, 59, 59, 999);
    return d;
  }, [date]);

  useEffect(() => {
    let mounted = true;
    const subscription = collections.tasks
      .query(
        Q.where('due_date', Q.between(startOfDay.getTime(), endOfDay.getTime())),
        Q.sortBy('due_date', 'asc')
      )
      .observe()
      .subscribe({
        next: (result) => {
          if (mounted) {
            setTasks(result);
            setLoading(false);
          }
        },
        error: () => {
          if (mounted) setLoading(false);
        },
      });

    return () => {
      mounted = false;
      subscription.unsubscribe();
    };
  }, [collections, startOfDay, endOfDay]);

  return { tasks, loading };
}

export function useTasksInMonth(month: Date) {
  const { collections } = useDatabase();
  const [tasks, setTasks] = useState<Task[]>([]);
  const [loading, setLoading] = useState(true);

  const range = useMemo(() => {
    const start = startOfMonth(month);
    start.setHours(0, 0, 0, 0);
    const end = endOfMonth(month);
    end.setHours(23, 59, 59, 999);
    return { start: start.getTime(), end: end.getTime() };
  }, [month]);

  useEffect(() => {
    let mounted = true;
    const subscription = collections.tasks
      .query(
        Q.where('due_date', Q.between(range.start, range.end)),
        Q.sortBy('due_date', 'asc')
      )
      .observe()
      .subscribe({
        next: (result) => {
          if (mounted) {
            setTasks(result);
            setLoading(false);
          }
        },
        error: () => {
          if (mounted) setLoading(false);
        },
      });

    return () => {
      mounted = false;
      subscription.unsubscribe();
    };
  }, [collections, range]);

  const byDay = useMemo(() => {
    const map: Record<number, Task[]> = {};
    for (const task of tasks) {
      const day = new Date(task.dueDate).getDate();
      if (!map[day]) map[day] = [];
      map[day].push(task);
    }
    return map;
  }, [tasks]);

  return { tasks, byDay, loading };
}
