import 'package:worker/core/errors/exceptions.dart';
import 'package:worker/core/network/network_info.dart';
import 'package:worker/features/favorites/data/datasources/favorite_products_local_datasource.dart';
import 'package:worker/features/favorites/data/datasources/favorites_remote_datasource.dart';
import 'package:worker/features/favorites/domain/repositories/favorites_repository.dart';
import 'package:worker/features/products/domain/entities/product.dart';

/// Favorites Repository Implementation
///
/// Implements the FavoritesRepository interface with online-first approach:
/// 1. Always try API first when online
/// 2. Cache API responses locally
/// 3. Fall back to local cache on network errors
class FavoritesRepositoryImpl implements FavoritesRepository {
  FavoritesRepositoryImpl({
    required this.remoteDataSource,
    required this.productsLocalDataSource,
    required this.networkInfo,
  });

  final FavoritesRemoteDataSource remoteDataSource;
  final FavoriteProductsLocalDataSource productsLocalDataSource;
  final NetworkInfo networkInfo;

  // =========================================================================
  // GET FAVORITE PRODUCTS (Returns actual Product entities)
  // =========================================================================

  /// Get favorite products with full product data
  ///
  /// Online-first: Fetches from API, caches locally
  /// Offline: Returns cached products
  @override
  Future<List<Product>> getFavoriteProducts() async {
    try {
      // Online-first: Try to fetch from API
      if (await networkInfo.isConnected) {
        _debugPrint('Fetching favorite products from API');

        try {
          // Get products from wishlist API
          final remoteProducts = await remoteDataSource.getFavorites();

          // Cache products locally
          await productsLocalDataSource.saveProducts(remoteProducts);

          _debugPrint('Fetched ${remoteProducts.length} favorite products from API');
          return remoteProducts.map((model) => model.toEntity()).toList();
        } on ServerException catch (e) {
          _debugPrint('API error, falling back to cache: $e');
          return _getProductsFromCache();
        } on NetworkException catch (e) {
          _debugPrint('Network error, falling back to cache: $e');
          return _getProductsFromCache();
        }
      } else {
        // Offline: Use local cache
        _debugPrint('Offline - using cached favorite products');
        return _getProductsFromCache();
      }
    } catch (e) {
      _debugPrint('Error getting favorite products: $e');
      return _getProductsFromCache();
    }
  }

  /// Get favorite products from local cache
  Future<List<Product>> _getProductsFromCache() async {
    try {
      final cachedProducts = await productsLocalDataSource.getAllProducts();
      _debugPrint('Loaded ${cachedProducts.length} favorite products from cache');
      return cachedProducts.map((model) => model.toEntity()).toList();
    } catch (e) {
      _debugPrint('Error loading from cache: $e');
      return [];
    }
  }

  // =========================================================================
  // ADD FAVORITE
  // =========================================================================

  @override
  Future<void> addFavorite(String productId) async {
    try {
      // Online-first: Try to add via API
      if (await networkInfo.isConnected) {
        _debugPrint('Adding favorite via API: $productId');

        try {
          final success = await remoteDataSource.addToFavorites(productId);

          if (success) {
            _debugPrint('Added favorite successfully: $productId');
          } else {
            throw const ServerException('Failed to add to favorites');
          }
        } on ServerException catch (e) {
          _debugPrint('API error adding favorite: $e');
          rethrow;
        } on NetworkException catch (e) {
          _debugPrint('Network error adding favorite: $e');
          rethrow;
        }
      } else {
        // Offline: Queue for later sync
        _debugPrint('Offline - cannot add favorite: $productId');
        throw const NetworkException('No internet connection');
      }
    } catch (e) {
      _debugPrint('Error adding favorite: $e');
      rethrow;
    }
  }

  // =========================================================================
  // REMOVE FAVORITE
  // =========================================================================

  @override
  Future<bool> removeFavorite(String productId) async {
    try {
      // Online-first: Try to remove via API
      if (await networkInfo.isConnected) {
        _debugPrint('Removing favorite via API: $productId');

        try {
          final success = await remoteDataSource.removeFromFavorites(productId);

          if (success) {
            _debugPrint('Removed favorite successfully: $productId');
          }

          return success;
        } on ServerException catch (e) {
          _debugPrint('API error removing favorite: $e');
          return false;
        } on NetworkException catch (e) {
          _debugPrint('Network error removing favorite: $e');
          return false;
        }
      } else {
        // Offline: Cannot remove
        _debugPrint('Offline - cannot remove favorite: $productId');
        return false;
      }
    } catch (e) {
      _debugPrint('Error removing favorite: $e');
      return false;
    }
  }
}

// ============================================================================
// DEBUG UTILITIES
// ============================================================================

/// Debug print helper
void _debugPrint(String message) {
  // ignore: avoid_print
  print('[FavoritesRepository] $message');
}
