// lib/hooks/useFeedHooks.ts
import { useMemo, useCallback, useState, useEffect } from 'react';
import { useNDKCurrentUser, useNDK } from '@/lib/hooks/useNDK';
import { nip19 } from 'nostr-tools';
import { NDKFilter, NDKEvent, NDKSubscriptionCacheUsage } from '@nostr-dev-kit/ndk-mobile';
import { useFeedEvents } from '@/lib/hooks/useFeedEvents';
import { useFeedMonitor } from '@/lib/hooks/useFeedMonitor';
import { FeedOptions, AnyFeedEntry } from '@/types/feed';
import { POWR_EVENT_KINDS } from '@/types/nostr-workout';

// POWR official account pubkey
export const POWR_ACCOUNT_PUBKEY = 'npub1p0wer69rpkraqs02l5v8rutagfh6g9wxn2dgytkv44ysz7avt8nsusvpjk';

// Convert POWR account pubkey to hex at the module level
export let POWR_PUBKEY_HEX: string = '';
try {
  if (POWR_ACCOUNT_PUBKEY.startsWith('npub')) {
    const decoded = nip19.decode(POWR_ACCOUNT_PUBKEY);
    POWR_PUBKEY_HEX = decoded.data as string;
  } else {
    POWR_PUBKEY_HEX = POWR_ACCOUNT_PUBKEY;
  }
  console.log("Initialized POWR pubkey hex:", POWR_PUBKEY_HEX);
} catch (error) {
  console.error('Error decoding POWR account npub:', error);
  POWR_PUBKEY_HEX = '';
}

/**
 * Hook for the Following tab in the social feed
 * Shows content from authors the user follows
 */
export function useFollowingFeed(options: FeedOptions = {}) {
  const { currentUser } = useNDKCurrentUser();
  const { ndk } = useNDK();
  const [followedUsers, setFollowedUsers] = useState<string[]>([]);
  const [isLoadingContacts, setIsLoadingContacts] = useState(true);
  
  // Improved contact list fetching
  useEffect(() => {
    if (!ndk || !currentUser?.pubkey) {
      setIsLoadingContacts(false);
      return;
    }
    
    console.log("Fetching contact list for user:", currentUser.pubkey);
    setIsLoadingContacts(true);
    
    const fetchContactList = async () => {
      try {
        // Try multiple approaches for maximum reliability
        let contacts: string[] = [];
        
        // First try: Use NDK user's native follows
        if (currentUser.follows) {
          try {
            // Check if follows is an array, a Set, or a function
            if (Array.isArray(currentUser.follows)) {
              contacts = [...currentUser.follows];
              console.log(`Found ${contacts.length} contacts from array`);
            } else if (currentUser.follows instanceof Set) {
              contacts = Array.from(currentUser.follows);
              console.log(`Found ${contacts.length} contacts from Set`);
            } else if (typeof currentUser.follows === 'function') {
              // If it's a function, try to call it
              try {
                const followsResult = await currentUser.followSet();
                if (followsResult instanceof Set) {
                  contacts = Array.from(followsResult);
                  console.log(`Found ${contacts.length} contacts from followSet() function`);
                }
              } catch (err) {
                console.error("Error calling followSet():", err);
              }
            }
          } catch (err) {
            console.log("Error processing follows:", err);
          }
        }
        
        // Second try: Direct kind:3 fetch
        if (contacts.length === 0) {
          try {
            const contactEvents = await ndk.fetchEvents({
              kinds: [3],
              authors: [currentUser.pubkey],
              limit: 1
            }, {
              closeOnEose: true,
              cacheUsage: NDKSubscriptionCacheUsage.CACHE_FIRST
            });
            
            if (contactEvents.size > 0) {
              const contactEvent = Array.from(contactEvents)[0];
              
              const extracted = contactEvent.tags
                .filter(tag => tag[0] === 'p')
                .map(tag => tag[1]);
                
              if (extracted.length > 0) {
                console.log(`Found ${extracted.length} contacts via direct kind:3 fetch`);
                contacts = extracted;
              }
            }
          } catch (err) {
            console.error("Error fetching kind:3 events:", err);
          }
        }
        
        // If still no contacts found, try fetching any recent events and look for p-tags
        if (contacts.length === 0) {
          try {
            const userEvents = await ndk.fetchEvents({
              authors: [currentUser.pubkey],
              kinds: [1, 3, 7], // Notes, contacts, reactions
              limit: 10
            }, {
              closeOnEose: true,
              cacheUsage: NDKSubscriptionCacheUsage.CACHE_FIRST  
            });
            
            // Collect all p-tags from recent events
            const mentions = new Set<string>();
            for (const event of userEvents) {
              event.tags
                .filter(tag => tag[0] === 'p')
                .forEach(tag => mentions.add(tag[1]));
            }
            
            if (mentions.size > 0) {
              console.log(`Found ${mentions.size} potential contacts from recent events`);
              contacts = Array.from(mentions);
            }
          } catch (err) {
            console.error("Error fetching recent events:", err);
          }
        }
        
        // If all else fails and we recognize this user, use hardcoded values (for testing only)
        if (contacts.length === 0 && currentUser?.pubkey === "55127fc9e1c03c6b459a3bab72fdb99def1644c5f239bdd09f3e5fb401ed9b21") {
          console.log("Using hardcoded follows for known user");
          contacts = [
            "3129509e23d3a6125e1451a5912dbe01099e151726c4766b44e1ecb8c846f506",
            "fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52",
            "0c776e95521742beaf102523a8505c483e8c014ee0d3bd6457bb249034e5ff04",
            "2edbcea694d164629854a52583458fd6d965b161e3c48b57d3aff01940558884",
            "55127fc9e1c03c6b459a3bab72fdb99def1644c5f239bdd09f3e5fb401ed9b21"
          ];
        }
        
        // Always include self to ensure self-created content is visible
        if (currentUser.pubkey && !contacts.includes(currentUser.pubkey)) {
          contacts.push(currentUser.pubkey);
        }
        
        // Add POWR account to followed users if not already there
        if (POWR_PUBKEY_HEX && !contacts.includes(POWR_PUBKEY_HEX)) {
          contacts.push(POWR_PUBKEY_HEX);
        }
        
        console.log("Final contact list count:", contacts.length);
        setFollowedUsers(contacts);
      } catch (error) {
        console.error("Error fetching contact list:", error);
      } finally {
        setIsLoadingContacts(false);
      }
    };
    
    fetchContactList();
  }, [ndk, currentUser?.pubkey]);
  
  // Create filters with the correct follows
  const followingFilters = useMemo<NDKFilter[]>(() => {
    if (followedUsers.length === 0) {
      console.log("No users to follow, not creating filters");
      return [];
    }
    
    console.log("Creating filters for", followedUsers.length, "followed users");
    console.log("Sample follows:", followedUsers.slice(0, 3));
    
    return [
      {
        kinds: [1] as any[], // Social posts 
        authors: followedUsers,
        '#t': ['workout', 'fitness', 'exercise', 'powr', 'gym'], // Only workout-related posts
        limit: 30
      },
      {
        kinds: [30023] as any[], // Articles
        authors: followedUsers,
        limit: 20
      },
      {
        kinds: [1301, 33401, 33402] as any[], // Workout-specific content
        authors: followedUsers,
        limit: 30
      }
    ];
  }, [followedUsers]);
  
  // Use feed events hook - only enable if we have follows
  const feed = useFeedEvents(
    followedUsers.length > 0 ? followingFilters : false, 
    {
      subId: 'following-feed',
      enabled: followedUsers.length > 0,
      feedType: 'following',
      ...options
    }
  );
  
  // Feed monitor for auto-refresh
  const monitor = useFeedMonitor({
    onRefresh: async () => {
      return feed.resetFeed();
    }
  });
  
  return {
    ...feed,
    ...monitor,
    hasFollows: followedUsers.length > 0,
    followCount: followedUsers.length,
    followedUsers: followedUsers, // Make this available for debugging
    isLoadingContacts
  };
}

/**
 * Hook for the POWR tab in the social feed
 * Shows official POWR content and featured content
 */
export function usePOWRFeed(options: FeedOptions = {}) {
  // Create filters for POWR content
  const powrFilters = useMemo<NDKFilter[]>(() => {
    if (!POWR_PUBKEY_HEX) return [];
    
    return [
      {
        kinds: [1, 30023, 30024] as any[], // Social posts and articles (including drafts)
        authors: [POWR_PUBKEY_HEX],
        limit: 25
      },
      {
        kinds: [1301, 33401, 33402] as any[], // Workout-specific content
        authors: [POWR_PUBKEY_HEX],
        limit: 25
      }
    ];
  }, []);
  
  // Filter function to ensure we don't show duplicates
  const filterPOWRContent = useCallback((entry: AnyFeedEntry) => {
    // Always show POWR content
    return true;
  }, []);
  
  // Use feed events hook
  const feed = useFeedEvents(
    POWR_PUBKEY_HEX ? powrFilters : false,
    {
      subId: 'powr-feed',
      feedType: 'powr',
      filterFn: filterPOWRContent,
      ...options
    }
  );
  
  // Feed monitor for auto-refresh
  const monitor = useFeedMonitor({
    onRefresh: async () => {
      return feed.resetFeed();
    }
  });
  
  return {
    ...feed,
    ...monitor
  };
}

/**
 * Hook for the Global tab in the social feed
 * Shows all workout-related content
 */
export function useGlobalFeed(options: FeedOptions = {}) {
  // Global filters - focus on workout content
  const globalFilters = useMemo<NDKFilter[]>(() => [
    {
      kinds: [1301] as any[], // Workout records
      limit: 20
    },
    {
      kinds: [1] as any[], // Social posts
      '#t': ['workout', 'fitness', 'powr', 'gym'], // With relevant tags
      limit: 20
    },
    {
      kinds: [33401, 33402] as any[], // Exercise templates and workout templates
      limit: 20
    }
  ], []);
  
  // Use feed events hook
  const feed = useFeedEvents(
    globalFilters,
    {
      subId: 'global-feed',
      feedType: 'global',
      ...options
    }
  );
  
  // Feed monitor for auto-refresh
  const monitor = useFeedMonitor({
    onRefresh: async () => {
      return feed.resetFeed();
    }
  });
  
  return {
    ...feed,
    ...monitor
  };
}