import { useCallback, useEffect, useState } from 'react';
import * as dataSync from '../api/dataSync';
import { apolloClient } from '../api/client';
import { PROFILE_QUERY } from '../api/operations/queries';

export type FavoriteProfile = {
  id: string;
  imaginaryName?: string;
  age?: number;
  gender?: string;
  sexuality?: string;
  bio?: string | null;
  desires?: string[];
  connectionGoals?: string[];
  interests?: string[];
  verificationStatus?: string | null;
  isMajestic?: boolean;
  distance?: { km: number; mi: number } | null;
  photos?: Array<{
    id: string;
    publicId?: string;
    pictureUrls?: { small?: string; medium?: string; large?: string };
  }>;
  interactionStatus?: {
    mine?: string | null;
    theirs?: string | null;
    message?: string | null;
  } | null;
};

export interface EnrichedFavorite {
  targetProfileId: string;
  savedAt: number;
  profile?: FavoriteProfile;
  profileError?: string;
}

// Strip volatile fields (signed photo URLs that expire) before saving the
// snapshot. Keep enough to render a card if Feeld's API isn't available.
const snapshotForStorage = (p: any): FavoriteProfile => ({
  id: p?.id,
  imaginaryName: p?.imaginaryName,
  age: p?.age,
  gender: typeof p?.gender === 'string' ? p.gender : undefined,
  sexuality: typeof p?.sexuality === 'string' ? p.sexuality : undefined,
  bio: typeof p?.bio === 'string' ? p.bio : null,
  desires: Array.isArray(p?.desires) ? p.desires : [],
  connectionGoals: Array.isArray(p?.connectionGoals) ? p.connectionGoals : [],
  interests: Array.isArray(p?.interests) ? p.interests : [],
  verificationStatus: typeof p?.verificationStatus === 'string' ? p.verificationStatus : null,
  isMajestic: !!p?.isMajestic,
  distance: p?.distance ?? null,
  photos: Array.isArray(p?.photos)
    ? p.photos.map((ph: any) => ({
        id: ph?.id,
        publicId: ph?.publicId,
        // pictureUrls intentionally omitted — they're signed and expire
      }))
    : [],
});

export function useFavorites() {
  const [favorites, setFavorites] = useState<EnrichedFavorite[]>([]);
  const [loading, setLoading] = useState(true);
  const [profilesLoading, setProfilesLoading] = useState(false);

  const refreshFromServer = useCallback(async () => {
    setLoading(true);
    try {
      const raw = await dataSync.getFavorites();
      // Start with snapshot data so the UI renders immediately
      setFavorites(
        raw.map((f) => ({
          targetProfileId: f.targetProfileId,
          savedAt: f.savedAt,
          profile: f.profile as FavoriteProfile | undefined,
        })),
      );
    } finally {
      setLoading(false);
    }
  }, []);

  // Initial load
  useEffect(() => {
    refreshFromServer();
  }, [refreshFromServer]);

  // Re-fetch full profile data + fresh signed photo URLs + current
  // interactionStatus for every favorite via ProfileQuery. Uses network-only
  // so we never serve stale interaction state from the Apollo cache.
  const enrichProfiles = useCallback(async () => {
    const current = favorites;
    if (current.length === 0) return;
    setProfilesLoading(true);
    try {
      const enriched = await Promise.all(
        current.map(async (f) => {
          try {
            const result = await apolloClient.query({
              query: PROFILE_QUERY,
              variables: { profileId: f.targetProfileId },
              fetchPolicy: 'network-only',
            });
            const profile = result.data?.profile;
            return profile
              ? { ...f, profile }
              : { ...f, profileError: 'Profile not found' };
          } catch (e: any) {
            return { ...f, profileError: e?.message || 'Fetch failed' };
          }
        }),
      );
      setFavorites(enriched);
    } finally {
      setProfilesLoading(false);
    }
    // We intentionally read the current `favorites` snapshot — re-running on
    // every change would cause an infinite loop after we setFavorites below.
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [favorites.length]);

  // Re-fetch profile data whenever the list changes
  useEffect(() => {
    if (!loading && favorites.length > 0) {
      enrichProfiles();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [loading, favorites.length]);

  const addFavorite = useCallback(async (profile: any) => {
    if (!profile?.id) return;
    const snapshot = snapshotForStorage(profile);
    await dataSync.addFavorite(profile.id, snapshot);
    setFavorites((prev) =>
      prev.some((f) => f.targetProfileId === profile.id)
        ? prev
        : [{ targetProfileId: profile.id, savedAt: Date.now(), profile: snapshot }, ...prev],
    );
  }, []);

  const removeFavorite = useCallback(async (targetProfileId: string) => {
    await dataSync.removeFavorite(targetProfileId);
    setFavorites((prev) => prev.filter((f) => f.targetProfileId !== targetProfileId));
  }, []);

  const isFavorite = useCallback(
    (targetProfileId: string) => favorites.some((f) => f.targetProfileId === targetProfileId),
    [favorites],
  );

  const toggleFavorite = useCallback(
    async (profile: any) => {
      if (!profile?.id) return;
      if (isFavorite(profile.id)) {
        await removeFavorite(profile.id);
      } else {
        await addFavorite(profile);
      }
    },
    [isFavorite, addFavorite, removeFavorite],
  );

  const clearAll = useCallback(async () => {
    await dataSync.clearAllFavorites();
    setFavorites([]);
  }, []);

  return {
    favorites,
    loading,
    profilesLoading,
    addFavorite,
    removeFavorite,
    isFavorite,
    toggleFavorite,
    clearAll,
    refreshFromServer,
    refreshProfiles: enrichProfiles,
  };
}
