/**
 * Custom hooks for data fetching with caching
 *
 * These hooks provide a simple interface to fetch data with automatic caching.
 * They follow the same pattern as React Query / SWR for familiarity.
 */

import { useEffect, useCallback } from "react";
import useDataStore from "@stores/dataStore";

/**
 * Hook to fetch and use songs data
 * @param {Object} options - { enabled: true, refetchOnMount: false }
 * @returns {{ songs: Array, loading: boolean, error: string|null, refetch: Function }}
 */
export function useSongs(options = {}) {
  const { enabled = true, refetchOnMount = false } = options;

  const songs = useDataStore((state) => state.songs);
  const loading = useDataStore((state) => state.songsLoading);
  const error = useDataStore((state) => state.songsError);
  const fetchSongs = useDataStore((state) => state.fetchSongs);

  useEffect(() => {
    if (enabled) {
      fetchSongs(refetchOnMount);
    }
  }, [enabled, refetchOnMount, fetchSongs]);

  const refetch = useCallback(() => fetchSongs(true), [fetchSongs]);

  return { songs, loading, error, refetch };
}

/**
 * Hook to fetch and use a single song
 * @param {string} id - Song ID
 * @param {Object} options - { enabled: true }
 * @returns {{ song: Object|null, loading: boolean, refetch: Function }}
 */
export function useSong(id, options = {}) {
  const { enabled = true } = options;

  const songDetails = useDataStore((state) => state.songDetails);
  const loadingMap = useDataStore((state) => state.songDetailsLoading);
  const fetchSongDetail = useDataStore((state) => state.fetchSongDetail);

  const song = songDetails[id]?.data || null;
  const loading = loadingMap[id] || false;

  useEffect(() => {
    if (enabled && id) {
      fetchSongDetail(id);
    }
  }, [enabled, id, fetchSongDetail]);

  const refetch = useCallback(
    () => fetchSongDetail(id, true),
    [fetchSongDetail, id],
  );

  return { song, loading, refetch };
}

/**
 * Hook to fetch and use worship lists
 * @param {Object} options - { enabled: true, refetchOnMount: false }
 * @returns {{ lists: Array, loading: boolean, error: string|null, refetch: Function }}
 */
export function useLists(options = {}) {
  const { enabled = true, refetchOnMount = false } = options;

  const lists = useDataStore((state) => state.lists);
  const loading = useDataStore((state) => state.listsLoading);
  const error = useDataStore((state) => state.listsError);
  const fetchLists = useDataStore((state) => state.fetchLists);

  useEffect(() => {
    if (enabled) {
      fetchLists(refetchOnMount);
    }
  }, [enabled, refetchOnMount, fetchLists]);

  const refetch = useCallback(() => fetchLists(true), [fetchLists]);

  return { lists, loading, error, refetch };
}

/**
 * Hook to fetch and use songs in a specific list
 * @param {string} listId - List ID
 * @param {Object} options - { enabled: true }
 * @returns {{ songs: Array, loading: boolean, refetch: Function }}
 */
export function useListSongs(listId, options = {}) {
  const { enabled = true } = options;

  const listDetails = useDataStore((state) => state.listDetails);
  const loadingMap = useDataStore((state) => state.listDetailsLoading);
  const fetchListDetail = useDataStore((state) => state.fetchListDetail);

  const songs = listDetails[listId]?.songs || [];
  const loading = loadingMap[listId] || false;

  useEffect(() => {
    if (enabled && listId) {
      fetchListDetail(listId);
    }
  }, [enabled, listId, fetchListDetail]);

  const refetch = useCallback(
    () => fetchListDetail(listId, true),
    [fetchListDetail, listId],
  );

  return { songs, loading, refetch };
}

/**
 * Hook to fetch and use profiles
 * @param {Object} options - { enabled: true, refetchOnMount: false }
 * @returns {{ profiles: Array, loading: boolean, error: string|null, refetch: Function }}
 */
export function useProfiles(options = {}) {
  const { enabled = true, refetchOnMount = false } = options;

  const profiles = useDataStore((state) => state.profiles);
  const loading = useDataStore((state) => state.profilesLoading);
  const error = useDataStore((state) => state.profilesError);
  const fetchProfiles = useDataStore((state) => state.fetchProfiles);

  useEffect(() => {
    if (enabled) {
      fetchProfiles(refetchOnMount);
    }
  }, [enabled, refetchOnMount, fetchProfiles]);

  const refetch = useCallback(() => fetchProfiles(true), [fetchProfiles]);

  return { profiles, loading, error, refetch };
}

/**
 * Hook to fetch and use stats
 * @param {Object} options - { enabled: true, refetchOnMount: false }
 * @returns {{ stats: Object, loading: boolean, refetch: Function }}
 */
export function useStats(options = {}) {
  const { enabled = true, refetchOnMount = false } = options;

  const stats = useDataStore((state) => state.stats);
  const loading = useDataStore((state) => state.statsLoading);
  const fetchStats = useDataStore((state) => state.fetchStats);

  useEffect(() => {
    if (enabled) {
      fetchStats(refetchOnMount);
    }
  }, [enabled, refetchOnMount, fetchStats]);

  const refetch = useCallback(() => fetchStats(true), [fetchStats]);

  return { stats, loading, refetch };
}

/**
 * Hook for searching songs (with debouncing built-in)
 * @param {string} query - Search query
 * @param {Object} options - { debounceMs: 300 }
 * @returns {{ results: Array, loading: boolean }}
 */
export function useSearch(query, options = {}) {
  const { debounceMs = 300 } = options;

  const searchSongs = useDataStore((state) => state.searchSongs);
  const searchCache = useDataStore((state) => state.searchCache);
  const loading = useDataStore((state) => state.searchLoading);

  const trimmedQuery = query?.trim().toLowerCase() || "";
  const results = searchCache[trimmedQuery]?.results || [];

  useEffect(() => {
    if (!trimmedQuery) return;

    const timer = setTimeout(() => {
      searchSongs(trimmedQuery);
    }, debounceMs);

    return () => clearTimeout(timer);
  }, [trimmedQuery, debounceMs, searchSongs]);

  return { results, loading };
}

/**
 * Hook to get cache mutation functions
 * @returns Object with cache mutation functions
 */
export function useDataMutations() {
  const updateSongInCache = useDataStore((state) => state.updateSongInCache);
  const addSongToCache = useDataStore((state) => state.addSongToCache);
  const removeSongFromCache = useDataStore(
    (state) => state.removeSongFromCache,
  );
  const invalidateSongs = useDataStore((state) => state.invalidateSongs);
  const invalidateSongDetail = useDataStore(
    (state) => state.invalidateSongDetail,
  );

  const updateListInCache = useDataStore((state) => state.updateListInCache);
  const addListToCache = useDataStore((state) => state.addListToCache);
  const removeListFromCache = useDataStore(
    (state) => state.removeListFromCache,
  );
  const invalidateLists = useDataStore((state) => state.invalidateLists);
  const invalidateListDetail = useDataStore(
    (state) => state.invalidateListDetail,
  );

  const invalidateProfiles = useDataStore((state) => state.invalidateProfiles);
  const invalidateAll = useDataStore((state) => state.invalidateAll);

  return {
    // Songs
    updateSongInCache,
    addSongToCache,
    removeSongFromCache,
    invalidateSongs,
    invalidateSongDetail,
    // Lists
    updateListInCache,
    addListToCache,
    removeListFromCache,
    invalidateLists,
    invalidateListDetail,
    // General
    invalidateProfiles,
    invalidateAll,
  };
}

/**
 * Hook to prefetch data on app mount
 */
export function usePrefetch() {
  const prefetch = useDataStore((state) => state.prefetch);

  useEffect(() => {
    prefetch();
  }, [prefetch]);
}

/**
 * Hook to get cache status (for debugging)
 */
export function useCacheStatus() {
  const getCacheStatus = useDataStore((state) => state.getCacheStatus);
  return getCacheStatus();
}
