import 'package:dartz/dartz.dart';
import 'package:injectable/injectable.dart';
import '../../core/constants/app_constants.dart';
import '../../core/errors/failures.dart';
import '../../core/errors/exceptions.dart';
import '../../domain/repositories/equipment_repository.dart';
import '../datasources/remote/equipment_remote_datasource.dart';
import '../models/equipment/equipment_dto.dart';
import '../models/common/paginated_response.dart';

/// 장비 관리 Repository 구현체
/// 장비 정보 CRUD 작업을 처리하며 도메인 모델과 API DTO 간 변환을 담당
@Injectable(as: EquipmentRepository)
class EquipmentRepositoryImpl implements EquipmentRepository {
  final EquipmentRemoteDataSource remoteDataSource;

  EquipmentRepositoryImpl({required this.remoteDataSource});

  @override
  Future<Either<Failure, PaginatedResponse<EquipmentDto>>> getEquipments({
    int? page,
    int? limit,
    String? search,
  }) async {
    try {
      final result = await remoteDataSource.getEquipments(
        page: page ?? 1,
        perPage: limit ?? AppConstants.equipmentPageSize,
        search: search,
      );
      
      final paginatedResult = PaginatedResponse<EquipmentDto>(
        items: result.items,
        page: result.currentPage,
        size: result.pageSize ?? AppConstants.equipmentPageSize,
        totalElements: result.totalCount,
        totalPages: result.totalPages,
        first: result.currentPage == 1,
        last: result.currentPage == result.totalPages,
      );
      
      return Right(paginatedResult);
    } on ServerException catch (e) {
      return Left(ServerFailure(message: e.message));
    } catch (e) {
      return Left(ServerFailure(message: '장비 목록 조회 실패: $e'));
    }
  }

  @override
  Future<Either<Failure, EquipmentDto>> getEquipmentDetail(int id) async {
    try {
      final equipment = await remoteDataSource.getEquipmentDetail(id);
      return Right(equipment);
    } on ServerException catch (e) {
      return Left(ServerFailure(message: e.message));
    } catch (e) {
      return Left(ServerFailure(message: '장비 상세 조회 실패: $e'));
    }
  }

  @override
  Future<Either<Failure, EquipmentDto>> createEquipment(EquipmentRequestDto request) async {
    try {
      final equipment = await remoteDataSource.createEquipment(request);
      return Right(equipment);
    } on ServerException catch (e) {
      return Left(ServerFailure(message: e.message));
    } catch (e) {
      return Left(ServerFailure(message: '장비 생성 실패: $e'));
    }
  }

  @override
  Future<Either<Failure, EquipmentDto>> updateEquipment(int id, EquipmentUpdateRequestDto request) async {
    try {
      final equipment = await remoteDataSource.updateEquipment(id, request);
      return Right(equipment);
    } on ServerException catch (e) {
      return Left(ServerFailure(message: e.message));
    } catch (e) {
      return Left(ServerFailure(message: '장비 수정 실패: $e'));
    }
  }

  @override
  Future<Either<Failure, void>> deleteEquipment(int id) async {
    try {
      await remoteDataSource.deleteEquipment(id);
      return const Right(null);
    } on ServerException catch (e) {
      return Left(ServerFailure(message: e.message));
    } catch (e) {
      return Left(ServerFailure(message: '장비 삭제 실패: $e'));
    }
  }

  @override
  Future<Either<Failure, EquipmentDto>> restoreEquipment(int id) async {
    try {
      final result = await remoteDataSource.restoreEquipment(id);
      return Right(result);
    } on ServerException catch (e) {
      return Left(ServerFailure(message: e.message));
    } catch (e) {
      return Left(ServerFailure(message: '장비 복구 실패: $e'));
    }
  }

  @override
  Future<Either<Failure, EquipmentDto>> getEquipmentBySerial(String serial) async {
    try {
      final result = await remoteDataSource.getEquipmentBySerial(serial);
      return Right(result);
    } on ServerException catch (e) {
      return Left(ServerFailure(message: e.message));
    } catch (e) {
      return Left(ServerFailure(message: '시리얼 번호로 장비 검색 실패: $e'));
    }
  }

  @override
  Future<Either<Failure, EquipmentDto>> getEquipmentByBarcode(String barcode) async {
    try {
      final result = await remoteDataSource.getEquipmentByBarcode(barcode);
      return Right(result);
    } on ServerException catch (e) {
      return Left(ServerFailure(message: e.message));
    } catch (e) {
      return Left(ServerFailure(message: '바코드로 장비 검색 실패: $e'));
    }
  }

  @override
  Future<Either<Failure, List<EquipmentDto>>> getEquipmentsByCompany(int companyId) async {
    try {
      final result = await remoteDataSource.getEquipmentsByCompany(companyId);
      return Right(result);
    } on ServerException catch (e) {
      return Left(ServerFailure(message: e.message));
    } catch (e) {
      return Left(ServerFailure(message: '회사별 장비 조회 실패: $e'));
    }
  }
}