import 'package:injectable/injectable.dart';
import '../../core/constants/app_constants.dart';
import '../../data/models/rent_dto.dart';
import '../repositories/rent_repository.dart';

/// 임대 UseCase (백엔드 스키마 기반)
/// 백엔드 API와 100% 호환되는 단순한 CRUD 작업만 제공
@lazySingleton
class RentUseCase {
  final RentRepository _repository;

  RentUseCase(this._repository);

  /// 임대 목록 조회 (백엔드 실제 파라미터)
  Future<RentListResponse> getRents({
    int page = 1,
    int perPage = AppConstants.rentPageSize,
    int? equipmentId,
    int? companyId,
    bool? isActive,
    DateTime? dateFrom,
    DateTime? dateTo,
  }) async {
    return await _repository.getRents(
      page: page,
      perPage: perPage,
      equipmentId: equipmentId,
      companyId: companyId,
      isActive: isActive,
      dateFrom: dateFrom,
      dateTo: dateTo,
    );
  }

  /// 임대 상세 조회 (백엔드 스키마 기반)
  Future<RentDto> getRent(int id) async {
    if (id <= 0) {
      throw ArgumentError('유효하지 않은 임대 ID입니다.');
    }
    return await _repository.getRent(id);
  }

  /// 임대 생성 (백엔드 스키마 기반)
  Future<RentDto> createRent(RentRequestDto request) async {
    // 백엔드 스키마 기반 검증만
    _validateRentRequest(request);
    return await _repository.createRent(request);
  }

  /// 임대 수정 (백엔드 스키마 기반)
  Future<RentDto> updateRent(int id, RentUpdateRequestDto request) async {
    if (id <= 0) {
      throw ArgumentError('유효하지 않은 임대 ID입니다.');
    }
    _validateRentUpdateRequest(request);
    return await _repository.updateRent(id, request);
  }

  /// 임대 삭제 (백엔드에서 처리)
  Future<void> deleteRent(int id) async {
    if (id <= 0) {
      throw ArgumentError('유효하지 않은 임대 ID입니다.');
    }
    return await _repository.deleteRent(id);
  }

  /// 진행중인 임대 조회 (백엔드 실존 API)
  Future<List<RentDto>> getActiveRents() async {
    return await _repository.getActiveRents();
  }

  /// 장비별 임대 조회 (백엔드 필터링)
  Future<List<RentDto>> getRentsByEquipment(int equipmentId) async {
    final response = await getRents(
      perPage: 1000,
      equipmentId: equipmentId,
    );
    return response.items;
  }

  /// 회사별 임대 조회 (백엔드 필터링)  
  Future<List<RentDto>> getRentsByCompany(int companyId) async {
    final response = await getRents(
      perPage: 1000,
      companyId: companyId,
    );
    return response.items;
  }

  /// 특정 기간 내 임대 조회 (백엔드 날짜 필터링)
  Future<List<RentDto>> getRentsByDateRange({
    required DateTime dateFrom,
    required DateTime dateTo,
    int? equipmentId,
    int? companyId,
  }) async {
    final response = await getRents(
      perPage: 1000,
      equipmentId: equipmentId,
      companyId: companyId,
      dateFrom: dateFrom,
      dateTo: dateTo,
    );
    
    return response.items;
  }

  /// 현재 진행 중인 임대 조회 (백엔드 계산값 활용)
  Future<List<RentDto>> getCurrentRents({int? equipmentId, int? companyId}) async {
    final response = await getRents(
      perPage: 1000,
      equipmentId: equipmentId,
      companyId: companyId,
      isActive: true, // 백엔드 필터링
    );
    
    return response.items;
  }

  /// 종료된 임대 조회 (백엔드 필터링)
  Future<List<RentDto>> getCompletedRents({int? equipmentId, int? companyId}) async {
    final response = await getRents(
      perPage: 1000,
      equipmentId: equipmentId,
      companyId: companyId,
      isActive: false, // 백엔드 필터링
    );
    
    return response.items;
  }

  /// 예정된 임대 조회 (백엔드 필터링)
  Future<List<RentDto>> getUpcomingRents({int? equipmentId, int? companyId}) async {
    final now = DateTime.now();
    final tomorrow = now.add(Duration(days: 1));
    
    final response = await getRents(
      perPage: 1000,
      equipmentId: equipmentId,
      companyId: companyId,
      dateFrom: tomorrow, // 내일부터 시작하는 임대
    );
    
    return response.items;
  }

  /// 임대 기간 계산 (일수)
  int calculateRentDays(RentDto rent) {
    return rent.endedAt.difference(rent.startedAt).inDays;
  }

  /// 남은 임대 기간 계산 (일수)
  int calculateRemainingDays(RentDto rent) {
    final now = DateTime.now();
    if (rent.endedAt.isBefore(now)) {
      return 0; // 이미 종료됨
    }
    return rent.endedAt.difference(now).inDays;
  }

  /// 임대 통계 조회 (백엔드 계산값 활용)
  Future<RentStatistics> getRentStatistics() async {
    final response = await getRents(perPage: 1000);
    final rents = response.items;
    
    // 백엔드 계산 필드 활용
    int totalCount = rents.length;
    int currentCount = rents.where((rent) => rent.isActive == true).length;
    int completedCount = rents.where((rent) => rent.isActive == false && rent.endedAt.isBefore(DateTime.now())).length;
    int upcomingCount = rents.where((rent) => rent.startedAt.isAfter(DateTime.now())).length;
    
    return RentStatistics(
      totalCount: totalCount,
      currentCount: currentCount,
      completedCount: completedCount,
      upcomingCount: upcomingCount,
    );
  }

  /// Private 헬퍼 메서드
  void _validateRentRequest(RentRequestDto request) {
    // 날짜 검증 (백엔드 스키마 기반)
    if (request.endedAt.isBefore(request.startedAt) || 
        request.endedAt.isAtSameMomentAs(request.startedAt)) {
      throw ArgumentError('종료일은 시작일보다 이후여야 합니다.');
    }
  }

  void _validateRentUpdateRequest(RentUpdateRequestDto request) {
    // 날짜 검증 (선택적 필드)
    if (request.startedAt != null && request.endedAt != null) {
      if (request.endedAt!.isBefore(request.startedAt!) || 
          request.endedAt!.isAtSameMomentAs(request.startedAt!)) {
        throw ArgumentError('종료일은 시작일보다 이후여야 합니다.');
      }
    }
  }
}

/// 임대 통계 모델 (단순화)
class RentStatistics {
  final int totalCount;
  final int currentCount;
  final int completedCount;
  final int upcomingCount;
  
  RentStatistics({
    required this.totalCount,
    required this.currentCount,
    required this.completedCount,
    required this.upcomingCount,
  });
}