import 'package:dio/dio.dart';
import 'package:injectable/injectable.dart';
import 'package:superport/core/constants/api_endpoints.dart';
import 'package:superport/data/models/equipment_history_dto.dart';

abstract class EquipmentHistoryRepository {
  Future<EquipmentHistoryListResponse> getEquipmentHistories({
    int? page,
    int? pageSize,
    int? equipmentsId,
    int? warehousesId,
    int? companiesId,
    String? transactionType,
    String? startDate,
    String? endDate,
  });
  
  Future<EquipmentHistoryDto> getEquipmentHistoryById(int id);
  
  Future<List<EquipmentHistoryDto>> getEquipmentHistoriesByEquipmentId(int equipmentId);
  
  Future<List<EquipmentHistoryDto>> getEquipmentHistoriesByWarehouseId(int warehouseId);
  
  // InventoryStatusDto 관련 메서드들 제거 (백엔드에 해당 개념 없음)
  
  Future<EquipmentHistoryDto> createEquipmentHistory(
    EquipmentHistoryRequestDto request,
  );
  
  Future<EquipmentHistoryDto> updateEquipmentHistory(
    int id,
    EquipmentHistoryUpdateRequestDto request,
  );
  
  Future<void> deleteEquipmentHistory(int id);
  
  Future<EquipmentHistoryDto> createStockIn({
    required int equipmentsId,
    required int warehousesId,
    required int quantity,
    DateTime? transactedAt,
    String? remark,
  });
  
  Future<EquipmentHistoryDto> createStockOut({
    required int equipmentsId,
    required int warehousesId,
    required int quantity,
    DateTime? transactedAt,
    String? remark,
  });
}

@LazySingleton(as: EquipmentHistoryRepository)
class EquipmentHistoryRepositoryImpl implements EquipmentHistoryRepository {
  final Dio _dio;
  
  EquipmentHistoryRepositoryImpl(this._dio);
  
  @override
  Future<EquipmentHistoryListResponse> getEquipmentHistories({
    int? page,
    int? pageSize,
    int? equipmentsId,
    int? warehousesId,
    int? companiesId,
    String? transactionType,
    String? startDate,
    String? endDate,
  }) async {
    try {
      final queryParams = <String, dynamic>{};
      
      if (page != null) queryParams['page'] = page;
      if (pageSize != null) queryParams['page_size'] = pageSize;
      if (equipmentsId != null) queryParams['equipments_id'] = equipmentsId;
      if (warehousesId != null) queryParams['warehouses_id'] = warehousesId;
      if (companiesId != null) queryParams['companies_id'] = companiesId;
      if (transactionType != null) queryParams['transaction_type'] = transactionType;
      if (startDate != null) queryParams['start_date'] = startDate;
      if (endDate != null) queryParams['end_date'] = endDate;
      
      final response = await _dio.get(
        ApiEndpoints.equipmentHistory,
        queryParameters: queryParams,
      );
      
      return EquipmentHistoryListResponse.fromJson(response.data);
    } on DioException catch (e) {
      throw _handleError(e);
    }
  }
  
  @override
  Future<EquipmentHistoryDto> getEquipmentHistoryById(int id) async {
    try {
      final response = await _dio.get('${ApiEndpoints.equipmentHistory}/$id');
      return EquipmentHistoryDto.fromJson(response.data);
    } on DioException catch (e) {
      throw _handleError(e);
    }
  }
  
  @override
  Future<List<EquipmentHistoryDto>> getEquipmentHistoriesByEquipmentId(
    int equipmentId,
  ) async {
    try {
      final response = await _dio.get(
        '${ApiEndpoints.equipmentHistory}/by-equipment/$equipmentId',
      );
      
      final List<dynamic> data = response.data is List 
          ? response.data 
          : response.data['data'] ?? [];
          
      return data.map((json) => EquipmentHistoryDto.fromJson(json)).toList();
    } on DioException catch (e) {
      throw _handleError(e);
    }
  }
  
  @override
  Future<List<EquipmentHistoryDto>> getEquipmentHistoriesByWarehouseId(
    int warehouseId,
  ) async {
    try {
      final response = await _dio.get(
        '${ApiEndpoints.equipmentHistory}/by-warehouse/$warehouseId',
      );
      
      final List<dynamic> data = response.data is List 
          ? response.data 
          : response.data['data'] ?? [];
          
      return data.map((json) => EquipmentHistoryDto.fromJson(json)).toList();
    } on DioException catch (e) {
      throw _handleError(e);
    }
  }
  
  // InventoryStatusDto 관련 메서드들 제거 (백엔드에 해당 개념 없음)
  
  @override
  Future<EquipmentHistoryDto> createEquipmentHistory(
    EquipmentHistoryRequestDto request,
  ) async {
    try {
      final response = await _dio.post(
        ApiEndpoints.equipmentHistory,
        data: request.toJson(),
      );
      return EquipmentHistoryDto.fromJson(response.data);
    } on DioException catch (e) {
      throw _handleError(e);
    }
  }
  
  @override
  Future<EquipmentHistoryDto> updateEquipmentHistory(
    int id,
    EquipmentHistoryUpdateRequestDto request,
  ) async {
    try {
      final response = await _dio.put(
        '${ApiEndpoints.equipmentHistory}/$id',
        data: request.toJson(),
      );
      return EquipmentHistoryDto.fromJson(response.data);
    } on DioException catch (e) {
      throw _handleError(e);
    }
  }
  
  @override
  Future<void> deleteEquipmentHistory(int id) async {
    try {
      await _dio.delete('${ApiEndpoints.equipmentHistory}/$id');
    } on DioException catch (e) {
      throw _handleError(e);
    }
  }
  
  @override
  Future<EquipmentHistoryDto> createStockIn({
    required int equipmentsId,
    required int warehousesId,
    required int quantity,
    DateTime? transactedAt,
    String? remark,
  }) async {
    final request = EquipmentHistoryRequestDto(
      equipmentsId: equipmentsId,
      warehousesId: warehousesId,
      quantity: quantity,
      transactionType: 'I', // 입고
      transactedAt: transactedAt ?? DateTime.now(),
      remark: remark,
    );
    
    return createEquipmentHistory(request);
  }
  
  @override
  Future<EquipmentHistoryDto> createStockOut({
    required int equipmentsId,
    required int warehousesId,
    required int quantity,
    DateTime? transactedAt,
    String? remark,
  }) async {
    // 재고 확인 로직 제거 (백엔드에서 처리)
    final request = EquipmentHistoryRequestDto(
      equipmentsId: equipmentsId,
      warehousesId: warehousesId,
      quantity: quantity,
      transactionType: 'O', // 출고
      transactedAt: transactedAt ?? DateTime.now(),
      remark: remark,
    );
    
    return createEquipmentHistory(request);
  }
  
  Exception _handleError(DioException e) {
    if (e.response != null) {
      final statusCode = e.response!.statusCode;
      final message = e.response!.data['message'] ?? '오류가 발생했습니다.';
      
      switch (statusCode) {
        case 400:
          return Exception('잘못된 요청: $message');
        case 401:
          return Exception('인증이 필요합니다.');
        case 403:
          return Exception('권한이 없습니다.');
        case 404:
          return Exception('재고 이력을 찾을 수 없습니다.');
        case 409:
          return Exception('재고 충돌: $message');
        case 500:
          return Exception('서버 오류가 발생했습니다.');
        default:
          return Exception('오류가 발생했습니다: $message');
      }
    }
    return Exception('네트워크 오류가 발생했습니다.');
  }
}