import 'package:get_it/get_it.dart';
import 'package:superport/core/errors/exceptions.dart';
import 'package:superport/core/errors/failures.dart';
import 'package:superport/data/datasources/remote/equipment_remote_datasource.dart';
import 'package:superport/data/models/equipment/equipment_history_dto.dart';
import 'package:superport/data/models/equipment/equipment_in_request.dart';
import 'package:superport/data/models/equipment/equipment_io_response.dart';
import 'package:superport/data/models/equipment/equipment_list_dto.dart';
import 'package:superport/data/models/equipment/equipment_out_request.dart';
import 'package:superport/data/models/equipment/equipment_request.dart';
import 'package:superport/data/models/equipment/equipment_response.dart';
import 'package:superport/models/equipment_unified_model.dart';

class EquipmentService {
  final EquipmentRemoteDataSource _remoteDataSource = GetIt.instance<EquipmentRemoteDataSource>();

  // 장비 목록 조회 (DTO 형태로 반환하여 status 정보 유지)
  Future<List<EquipmentListDto>> getEquipmentsWithStatus({
    int page = 1,
    int perPage = 20,
    String? status,
    int? companyId,
    int? warehouseLocationId,
    String? search,
  }) async {
    try {
      final dtoList = await _remoteDataSource.getEquipments(
        page: page,
        perPage: perPage,
        status: status,
        companyId: companyId,
        warehouseLocationId: warehouseLocationId,
        search: search,
      );

      return dtoList;
    } on ServerException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to fetch equipment list: $e');
    }
  }

  // 장비 목록 조회
  Future<List<Equipment>> getEquipments({
    int page = 1,
    int perPage = 20,
    String? status,
    int? companyId,
    int? warehouseLocationId,
    String? search,
  }) async {
    try {
      final dtoList = await _remoteDataSource.getEquipments(
        page: page,
        perPage: perPage,
        status: status,
        companyId: companyId,
        warehouseLocationId: warehouseLocationId,
        search: search,
      );

      return dtoList.map((dto) => _convertListDtoToEquipment(dto)).toList();
    } on ServerException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to fetch equipment list: $e');
    }
  }

  // 장비 생성
  Future<Equipment> createEquipment(Equipment equipment) async {
    try {
      final request = CreateEquipmentRequest(
        equipmentNumber: equipment.name, // Flutter model uses 'name' for equipment number
        category1: equipment.category,
        category2: equipment.subCategory,
        category3: equipment.subSubCategory,
        manufacturer: equipment.manufacturer,
        modelName: equipment.name,
        serialNumber: equipment.serialNumber,
        purchaseDate: equipment.inDate,
        purchasePrice: equipment.quantity.toDouble(), // Temporary mapping
        remark: equipment.remark,
      );

      final response = await _remoteDataSource.createEquipment(request);
      return _convertResponseToEquipment(response);
    } on ServerException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to create equipment: $e');
    }
  }

  // 장비 상세 조회
  Future<Equipment> getEquipmentDetail(int id) async {
    try {
      final response = await _remoteDataSource.getEquipmentDetail(id);
      return _convertResponseToEquipment(response);
    } on ServerException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to fetch equipment detail: $e');
    }
  }
  
  // 장비 조회 (getEquipmentDetail의 alias)
  Future<Equipment> getEquipment(int id) async {
    return getEquipmentDetail(id);
  }

  // 장비 수정
  Future<Equipment> updateEquipment(int id, Equipment equipment) async {
    try {
      final request = UpdateEquipmentRequest(
        category1: equipment.category,
        category2: equipment.subCategory,
        category3: equipment.subSubCategory,
        manufacturer: equipment.manufacturer,
        modelName: equipment.name,
        serialNumber: equipment.serialNumber,
        barcode: equipment.barcode,
        purchaseDate: equipment.inDate,
        purchasePrice: equipment.quantity.toDouble(), // Temporary mapping
        remark: equipment.remark,
      );

      final response = await _remoteDataSource.updateEquipment(id, request);
      return _convertResponseToEquipment(response);
    } on ServerException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to update equipment: $e');
    }
  }

  // 장비 삭제
  Future<void> deleteEquipment(int id) async {
    try {
      await _remoteDataSource.deleteEquipment(id);
    } on ServerException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to delete equipment: $e');
    }
  }

  // 장비 상태 변경
  Future<Equipment> changeEquipmentStatus(int id, String status, String? reason) async {
    try {
      final response = await _remoteDataSource.changeEquipmentStatus(id, status, reason);
      return _convertResponseToEquipment(response);
    } on ServerException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to change equipment status: $e');
    }
  }

  // 장비 이력 추가
  Future<EquipmentHistoryDto> addEquipmentHistory(int equipmentId, String type, int quantity, String? remarks) async {
    try {
      final request = CreateHistoryRequest(
        transactionType: type,
        quantity: quantity,
        transactionDate: DateTime.now(),
        remarks: remarks,
      );

      return await _remoteDataSource.addEquipmentHistory(equipmentId, request);
    } on ServerException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to add equipment history: $e');
    }
  }

  // 장비 이력 조회
  Future<List<EquipmentHistoryDto>> getEquipmentHistory(int equipmentId, {int page = 1, int perPage = 20}) async {
    try {
      return await _remoteDataSource.getEquipmentHistory(equipmentId, page: page, perPage: perPage);
    } on ServerException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to fetch equipment history: $e');
    }
  }

  // 장비 입고
  Future<EquipmentIoResponse> equipmentIn({
    required int equipmentId,
    required int quantity,
    int? warehouseLocationId,
    String? notes,
  }) async {
    try {
      final request = EquipmentInRequest(
        equipmentId: equipmentId,
        quantity: quantity,
        warehouseLocationId: warehouseLocationId,
        notes: notes,
      );

      return await _remoteDataSource.equipmentIn(request);
    } on ServerException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to process equipment in: $e');
    }
  }

  // 장비 출고
  Future<EquipmentIoResponse> equipmentOut({
    required int equipmentId,
    required int quantity,
    required int companyId,
    int? branchId,
    String? notes,
  }) async {
    try {
      final request = EquipmentOutRequest(
        equipmentId: equipmentId,
        quantity: quantity,
        companyId: companyId,
        branchId: branchId,
        notes: notes,
      );

      return await _remoteDataSource.equipmentOut(request);
    } on ServerException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to process equipment out: $e');
    }
  }

  // Private helper methods for model conversion
  Equipment _convertListDtoToEquipment(EquipmentListDto dto) {
    return Equipment(
      id: dto.id,
      manufacturer: dto.manufacturer,
      name: dto.modelName ?? dto.equipmentNumber,
      category: '', // Need to be fetched from detail or categories
      subCategory: '',
      subSubCategory: '',
      serialNumber: dto.serialNumber,
      barcode: null, // Not in list DTO
      quantity: 1, // Default quantity
      inDate: dto.createdAt,
      remark: null, // Not in list DTO
    );
  }

  Equipment _convertResponseToEquipment(EquipmentResponse response) {
    return Equipment(
      id: response.id,
      manufacturer: response.manufacturer,
      name: response.modelName ?? response.equipmentNumber,
      category: response.category1 ?? '',
      subCategory: response.category2 ?? '',
      subSubCategory: response.category3 ?? '',
      serialNumber: response.serialNumber,
      barcode: response.barcode,
      quantity: 1, // Default quantity, actual quantity should be tracked in history
      inDate: response.purchaseDate,
      remark: response.remark,
      // Warranty information would need to be fetched from license API if available
    );
  }

  // 장비 상태 상수
  static const Map<String, String> equipmentStatus = {
    'available': '사용 가능',
    'in_use': '사용 중',
    'maintenance': '유지보수 중',
    'repair': '수리 중',
    'disposed': '폐기',
  };
}