'use client';

import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useFamilyOverlay } from '@/components/family/family-overlay-provider';
import { useAuth } from '@/components/id/auth-provider';
import {
  FamilyGroup,
  FamilyPresenceMember,
  fetchFamilyGroup,
  fetchFamilyGroups,
  fetchFamilyPresence,
  getAccessToken
} from '@/lib/api';
import { resolveFamilyGroupId } from '@/lib/selected-family-storage';

export function useSelectedFamily(enabled = true) {
  const { user, token, isPinLocked, isLoading, isContentReady } = useAuth();
  const { selectedGroupId, setSelectedGroupId, isSelectionHydrated } = useFamilyOverlay();
  const userId = user?.id;
  const [groups, setGroups] = useState<FamilyGroup[]>([]);
  const [group, setGroup] = useState<FamilyGroup | null>(null);
  const [presenceMembers, setPresenceMembers] = useState<FamilyPresenceMember[]>([]);
  const [loading, setLoading] = useState(true);
  const hasLoadedRef = useRef(false);

  const refresh = useCallback(async () => {
    const accessToken = getAccessToken() ?? token?.trim() ?? null;
    if (!enabled || !userId || !accessToken || isPinLocked || isLoading || !isContentReady) {
      setGroups([]);
      setGroup(null);
      setPresenceMembers([]);
      hasLoadedRef.current = false;
      setLoading(false);
      return;
    }

    let pendingHydration = false;

    try {
      const groupsResponse = await fetchFamilyGroups(userId, accessToken);
      const list = groupsResponse.groups ?? [];
      setGroups(list);

      if (!list.length) {
        setGroup(null);
        setPresenceMembers([]);
        if (selectedGroupId) setSelectedGroupId(null);
        hasLoadedRef.current = true;
        return;
      }

      const effectiveId = resolveFamilyGroupId(list, selectedGroupId, isSelectionHydrated);
      if (!effectiveId) {
        pendingHydration = !isSelectionHydrated;
        return;
      }

      if (effectiveId !== selectedGroupId) {
        setSelectedGroupId(effectiveId);
      }

      const [groupResponse, presenceResponse] = await Promise.all([
        fetchFamilyGroup(effectiveId, accessToken),
        fetchFamilyPresence(effectiveId, accessToken)
      ]);
      setGroup(groupResponse);
      setPresenceMembers(presenceResponse.members ?? []);
      hasLoadedRef.current = true;
    } catch {
      // Фоновая ошибка не должна сбрасывать уже показанную семью в сайдбаре.
    } finally {
      if (!pendingHydration) {
        setLoading(false);
      }
    }
  }, [enabled, isContentReady, isLoading, isPinLocked, isSelectionHydrated, selectedGroupId, setSelectedGroupId, token, userId]);

  useEffect(() => {
    if (!enabled || !userId || !token || isPinLocked || isLoading || !isContentReady) {
      setGroups([]);
      setGroup(null);
      setPresenceMembers([]);
      hasLoadedRef.current = false;
      setLoading(false);
      return;
    }
    setLoading(!hasLoadedRef.current);
    void refresh();
  }, [enabled, isContentReady, isLoading, isPinLocked, isSelectionHydrated, refresh, token, userId]);

  useEffect(() => {
    const accessToken = getAccessToken() ?? token?.trim() ?? null;
    if (!enabled || !accessToken || isPinLocked || isLoading || !isContentReady || !group) return;
    const timer = window.setInterval(() => void refresh(), 25_000);
    return () => window.clearInterval(timer);
  }, [enabled, group, isContentReady, isLoading, isPinLocked, refresh, token]);

  const presenceByUserId = useMemo(
    () => new Map(presenceMembers.map((member) => [member.userId, member])),
    [presenceMembers]
  );

  const groupSummaries = useMemo(
    () => groups.map((item) => ({ id: item.id, name: item.name })),
    [groups]
  );

  return {
    groups,
    groupSummaries,
    group,
    loading,
    hasFamily: Boolean(group),
    selectedGroupId: group?.id ?? selectedGroupId,
    setSelectedGroupId,
    presenceByUserId,
    refresh
  };
}

/** @deprecated Используйте useSelectedFamily */
export function usePrimaryFamily(enabled = true) {
  return useSelectedFamily(enabled);
}
