import React, { createContext, useContext, useState, useCallback, useEffect, ReactNode } from 'react';

interface SecurityContextType {
  // Unlocked items (itemId -> unlock timestamp)
  unlockedItems: Map<string, number>;
  // Unlocked passwords (itemId -> password) - stored temporarily while unlocked
  unlockedPasswords: Map<string, string>;
  // Check if item is unlocked
  isUnlocked: (itemId: string) => boolean;
  // Unlock an item
  unlockItem: (itemId: string, password: string) => Promise<boolean>;
  // Lock an item
  lockItem: (itemId: string) => void;
  // Lock all items
  lockAll: () => void;
  // Get password for unlocked item
  getUnlockedPassword: (itemId: string) => string | null;
}

const SecurityContext = createContext<SecurityContextType | undefined>(undefined);

const LOCK_TIMEOUT = 10 * 60 * 1000; // 10 minutes in milliseconds

export function SecurityProvider({ children }: { children: ReactNode }) {
  const [unlockedItems, setUnlockedItems] = useState<Map<string, number>>(new Map());
  const [unlockedPasswords, setUnlockedPasswords] = useState<Map<string, string>>(new Map());

  // Check for expired unlocks every minute
  useEffect(() => {
    const interval = setInterval(() => {
      const now = Date.now();
      setUnlockedItems(prev => {
        const updated = new Map(prev);
        const expiredIds: string[] = [];
        
        prev.forEach((timestamp, itemId) => {
          if (now - timestamp > LOCK_TIMEOUT) {
            updated.delete(itemId);
            expiredIds.push(itemId);
          }
        });
        
        // Clear passwords for expired unlocks
        if (expiredIds.length > 0) {
          setUnlockedPasswords(prevPasswords => {
            const updatedPasswords = new Map(prevPasswords);
            expiredIds.forEach(id => updatedPasswords.delete(id));
            return updatedPasswords;
          });
        }
        
        return updated;
      });
    }, 60000); // Check every minute

    return () => clearInterval(interval);
  }, []);

  const isUnlocked = useCallback((itemId: string): boolean => {
    const timestamp = unlockedItems.get(itemId);
    if (!timestamp) return false;
    
    // Check if still within timeout
    const now = Date.now();
    if (now - timestamp > LOCK_TIMEOUT) {
      setUnlockedItems(prev => {
        const updated = new Map(prev);
        updated.delete(itemId);
        return updated;
      });
      return false;
    }
    
    return true;
  }, [unlockedItems]);

  const unlockItem = useCallback(async (itemId: string, password: string): Promise<boolean> => {
    try {
      const trimmedPassword = password.trim();
      
      if (!trimmedPassword) {
        console.error('Empty password provided');
        return false;
      }
      
      // Verify password against user account password via backend
      try {
        const { authApi } = await import('@/lib/api');
        const response = await authApi.verifyPassword(trimmedPassword);
        
        if (!response.valid) {
          console.error('Password verification failed - invalid password');
          return false;
        }
        
        console.log('Password verified successfully');
      } catch (error: any) {
        console.error('Password verification error:', error);
        if (error.status === 401) {
          return false;
        }
        return false;
      }

      // Unlock the item and store password temporarily
      setUnlockedItems(prev => {
        const updated = new Map(prev);
        updated.set(itemId, Date.now());
        return updated;
      });
      
      // Store password temporarily for encryption (cleared when locked)
      setUnlockedPasswords(prev => {
        const updated = new Map(prev);
        updated.set(itemId, trimmedPassword);
        return updated;
      });

      return true;
    } catch (error) {
      console.error('Unlock error:', error);
      return false;
    }
  }, []);

  const lockItem = useCallback((itemId: string) => {
    setUnlockedItems(prev => {
      const updated = new Map(prev);
      updated.delete(itemId);
      return updated;
    });
    // Clear stored password when locking
    setUnlockedPasswords(prev => {
      const updated = new Map(prev);
      updated.delete(itemId);
      return updated;
    });
  }, []);

  const lockAll = useCallback(() => {
    setUnlockedItems(new Map());
    setUnlockedPasswords(new Map());
  }, []);
  
  const getUnlockedPassword = useCallback((itemId: string): string | null => {
    return unlockedPasswords.get(itemId) || null;
  }, [unlockedPasswords]);

  const value: SecurityContextType = {
    unlockedItems,
    unlockedPasswords,
    isUnlocked,
    unlockItem,
    lockItem,
    lockAll,
    getUnlockedPassword,
  };

  return (
    <SecurityContext.Provider value={value}>
      {children}
    </SecurityContext.Provider>
  );
}

export function useSecurity() {
  const context = useContext(SecurityContext);
  if (context === undefined) {
    throw new Error('useSecurity must be used within a SecurityProvider');
  }
  return context;
}
