/// Repository Implementation: Products Repository
///
/// Concrete implementation of the products repository interface.
/// Handles data from remote datasource (Frappe API) and converts to domain entities.
library;

import 'package:worker/features/products/data/datasources/products_local_datasource.dart';
import 'package:worker/features/products/data/datasources/products_remote_datasource.dart';
import 'package:worker/features/products/domain/entities/category.dart';
import 'package:worker/features/products/domain/entities/product.dart';
import 'package:worker/features/products/domain/repositories/products_repository.dart';

/// Products Repository Implementation
///
/// Implements the repository interface defined in the domain layer.
/// Uses remote datasource (Frappe API) for fetching products.
/// Local datasource is kept for categories (mock data).
class ProductsRepositoryImpl implements ProductsRepository {
  final ProductsLocalDataSource localDataSource;
  final ProductsRemoteDataSource remoteDataSource;

  const ProductsRepositoryImpl({
    required this.localDataSource,
    required this.remoteDataSource,
  });

  @override
  Future<List<Product>> getAllProducts({
    int limitStart = 0,
    int limitPageLength = 12,
  }) async {
    try {
      // Fetch from Frappe API with pagination
      final productModels = await remoteDataSource.getAllProducts(
        limitStart: limitStart,
        limitPageLength: limitPageLength,
      );
      return productModels.map((model) => model.toEntity()).toList();
    } catch (e) {
      print('[ProductsRepository] Error getting products: $e');
      rethrow; // Re-throw to let providers handle the error
    }
  }

  @override
  Future<List<Product>> searchProducts(
    String query, {
    int limitStart = 0,
    int limitPageLength = 12,
  }) async {
    try {
      // Search via remote API with pagination
      final productModels = await remoteDataSource.searchProducts(
        query,
        limitStart: limitStart,
        limitPageLength: limitPageLength,
      );
      return productModels.map((model) => model.toEntity()).toList();
    } catch (e) {
      print('[ProductsRepository] Error searching products: $e');
      rethrow;
    }
  }

  @override
  Future<List<Product>> getProductsByCategory(
    String categoryId, {
    int limitStart = 0,
    int limitPageLength = 12,
  }) async {
    try {
      // Filter by category via remote API with pagination
      final productModels = await remoteDataSource.getProductsByCategory(
        categoryId,
        limitStart: limitStart,
        limitPageLength: limitPageLength,
      );
      return productModels.map((model) => model.toEntity()).toList();
    } catch (e) {
      print('[ProductsRepository] Error getting products by category: $e');
      rethrow;
    }
  }

  @override
  Future<Product> getProductById(String id) async {
    try {
      // Fetch product detail from Frappe API
      final productModel = await remoteDataSource.getProductDetail(id);
      return productModel.toEntity();
    } catch (e) {
      print('[ProductsRepository] Error getting product: $e');
      rethrow;
    }
  }

  @override
  Future<List<Category>> getCategories() async {
    try {
      // For now, use local mock categories
      // TODO: Fetch categories from Frappe API if available
      final categoryModels = await localDataSource.getCategories();
      return categoryModels.map((model) => model.toEntity()).toList();
    } catch (e) {
      print('[ProductsRepository] Error getting categories: $e');
      rethrow;
    }
  }

  @override
  Future<List<Product>> getProductsWithFilters({
    int limitStart = 0,
    int limitPageLength = 12,
    List<String>? itemGroups,
    List<String>? brands,
    List<Map<String, String>>? itemAttributes,
    String? searchKeyword,
  }) async {
    try {
      // Fetch from Frappe API with all filters and pagination
      final productModels = await remoteDataSource.getProductsWithFilters(
        limitStart: limitStart,
        limitPageLength: limitPageLength,
        itemGroups: itemGroups,
        brands: brands,
        itemAttributes: itemAttributes,
        searchKeyword: searchKeyword,
      );
      return productModels.map((model) => model.toEntity()).toList();
    } catch (e) {
      print('[ProductsRepository] Error getting filtered products: $e');
      rethrow;
    }
  }
}
