import { useState, useEffect, useCallback } from 'react';
import { invokeWithTracking } from '@/lib/edgeFunctionTracking';
import { useAuth } from '@/hooks/useAuth';
import { supabase } from '@/integrations/supabase/client';
import { logger } from '@/lib/logger';
import { UnitPreferences, getMeasurementSystemFromCountry } from '@/lib/units';
import type { Json } from '@/integrations/supabase/types';
import * as storage from '@/lib/localStorage';

// Type guard for unit preferences
function isValidUnitPreferences(obj: unknown): obj is UnitPreferences {
  return (
    typeof obj === 'object' &&
    obj !== null &&
    'measurement_system' in obj &&
    (obj.measurement_system === 'metric' || obj.measurement_system === 'imperial')
  );
}

const DEFAULT_PREFERENCES: UnitPreferences = {
  measurement_system: 'metric',
  temperature: 'celsius',
  auto_detect: true
};

export function useUnitPreferences() {
  const { user } = useAuth();
  const [preferences, setPreferences] = useState<UnitPreferences>(DEFAULT_PREFERENCES);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    loadPreferences();
  }, [user]);

  const loadPreferences = async () => {
    try {
      if (user) {
        const { data, error } = await supabase
          .from('user_preferences')
          .select('unit_preferences')
          .eq('user_id', user.id)
          .maybeSingle();

        if (error && error.code !== 'PGRST116') {
          logger.error('Failed to fetch unit preferences', {
            userId: user.id,
            action: 'fetch_unit_preferences',
            error: error.message,
            errorCode: error.code
          });
          throw error;
        }

        if (data?.unit_preferences && isValidUnitPreferences(data.unit_preferences)) {
          const validPrefs = data.unit_preferences as UnitPreferences;
          setPreferences({ ...DEFAULT_PREFERENCES, ...validPrefs });
        } else {
          await autoDetectPreferences();
        }
      } else {
        const stored = localStorage.getItem('unit_preferences');
        if (stored) {
          try {
            const parsed = JSON.parse(stored);
            setPreferences({ ...DEFAULT_PREFERENCES, ...parsed });
          } catch (e) {
            await autoDetectPreferences();
          }
        } else {
          await autoDetectPreferences();
        }
      }
    } catch (error: unknown) {
      logger.error('Error loading unit preferences', {
        userId: user?.id,
        action: 'load_unit_preferences',
        error: error instanceof Error ? error.message : String(error)
      });
      await autoDetectPreferences();
    } finally {
      setLoading(false);
    }
  };

  const autoDetectPreferences = useCallback(async () => {
    try {
      const response = await invokeWithTracking('detect-location', {}, user?.id);
      
      if (response.data && response.data.measurementSystem) {
        const newPreferences: UnitPreferences = {
          ...DEFAULT_PREFERENCES,
          measurement_system: response.data.measurementSystem,
        };
        
        setPreferences(newPreferences);
        
        if (user) {
          const { error } = await supabase
            .from('user_preferences')
            .upsert({ 
              user_id: user.id,
              unit_preferences: newPreferences as unknown as Json,
              updated_at: new Date().toISOString()
            });
          
          if (error) {
            logger.error('Error saving auto-detected preferences', {
              userId: user.id,
              action: 'save_auto_detected_preferences',
              error: error.message
            });
          }
        } else {
          localStorage.setItem('unit_preferences', JSON.stringify(newPreferences));
        }
        
        return newPreferences;
      }
    } catch (error: unknown) {
      logger.error('Error auto-detecting location', {
        userId: user?.id,
        action: 'auto_detect_location',
        error: error instanceof Error ? error.message : String(error)
      });
    }
    
    // Fallback to default
    setPreferences(DEFAULT_PREFERENCES);
    return DEFAULT_PREFERENCES;
  }, [user]);

  const updatePreferences = async (newPreferences: Partial<UnitPreferences>) => {
    const updated = { ...preferences, ...newPreferences };
    setPreferences(updated);

    try {
      if (user) {
        await supabase
          .from('user_preferences')
          .update({ 
            unit_preferences: updated as unknown as Json,
            updated_at: new Date().toISOString()
          })
          .eq('user_id', user.id);
        
        logger.info('Unit preferences updated', {
          userId: user.id,
          action: 'update_unit_preferences'
        });
      } else {
        storage.setJSON('unit_preferences', updated);
      }
    } catch (error: unknown) {
      logger.error('Error saving unit preferences', {
        userId: user?.id,
        action: 'save_unit_preferences',
        error: error instanceof Error ? error.message : String(error)
      });
      setPreferences(preferences);
      throw error;
    }
  };

  return {
    preferences,
    loading,
    updatePreferences,
    autoDetectPreferences
  };
}