import 'package:dartz/dartz.dart';
import '../../../../core/errors/exceptions.dart';
import '../../../../core/errors/failures.dart';
import '../../domain/entities/product_entity.dart';
import '../../domain/entities/product_stage_entity.dart';
import '../../domain/repositories/products_repository.dart';
import '../datasources/products_remote_datasource.dart';
import '../models/create_product_warehouse_request.dart';
import '../models/product_detail_request_model.dart';

/// Implementation of ProductsRepository
/// Handles data operations and error conversion
class ProductsRepositoryImpl implements ProductsRepository {
  final ProductsRemoteDataSource remoteDataSource;

  ProductsRepositoryImpl(this.remoteDataSource);

  @override
  Future<Either<Failure, List<ProductEntity>>> getProducts(
    int warehouseId,
    String type,
  ) async {
    try {
      // Fetch products from remote data source
      final products = await remoteDataSource.getProducts(warehouseId, type);

      // Convert models to entities and return success
      return Right(products.map((model) => model.toEntity()).toList());
    } on ServerException catch (e) {
      // Convert ServerException to ServerFailure
      return Left(ServerFailure(e.message));
    } on NetworkException catch (e) {
      // Convert NetworkException to NetworkFailure
      return Left(NetworkFailure(e.message));
    } catch (e) {
      // Handle any other exceptions
      return Left(ServerFailure('Unexpected error: ${e.toString()}'));
    }
  }

  @override
  Future<Either<Failure, List<ProductStageEntity>>> getProductDetail(
    int warehouseId,
    int productId,
  ) async {
    try {
      // Create request model
      final request = ProductDetailRequestModel(
        warehouseId: warehouseId,
        productId: productId,
      );

      // Fetch product stages from remote data source
      final stages = await remoteDataSource.getProductDetail(request);

      // Convert models to entities and return success
      return Right(stages.map((stage) => stage.toEntity()).toList());
    } on ServerException catch (e) {
      // Convert ServerException to ServerFailure
      return Left(ServerFailure(e.message));
    } on NetworkException catch (e) {
      // Convert NetworkException to NetworkFailure
      return Left(NetworkFailure(e.message));
    } catch (e) {
      // Handle any other exceptions
      return Left(ServerFailure('Unexpected error: ${e.toString()}'));
    }
  }

  @override
  Future<Either<Failure, void>> createProductWarehouse(
    CreateProductWarehouseRequest request,
  ) async {
    try {
      // Call remote data source to create product warehouse
      await remoteDataSource.createProductWarehouse(request);

      // Return success
      return const Right(null);
    } on ServerException catch (e) {
      // Convert ServerException to ServerFailure
      return Left(ServerFailure(e.message));
    } on NetworkException catch (e) {
      // Convert NetworkException to NetworkFailure
      return Left(NetworkFailure(e.message));
    } catch (e) {
      // Handle any other exceptions
      return Left(ServerFailure('Unexpected error: ${e.toString()}'));
    }
  }
}
