import 'package:injectable/injectable.dart';
import 'package:superport/data/models/maintenance_dto.dart';
import 'package:superport/data/repositories/maintenance_repository.dart';

@lazySingleton
class MaintenanceUseCase {
  final MaintenanceRepository _repository;

  MaintenanceUseCase({required MaintenanceRepository repository})
      : _repository = repository;

  // 유지보수 목록 조회
  Future<MaintenanceListResponse> getMaintenances({
    int page = 1,
    int perPage = 20,
    int? equipmentId,
    String? maintenanceType,
    bool? isExpired,
    int? expiringDays,
    bool includeDeleted = false,
  }) async {
    return await _repository.getMaintenances(
      page: page,
      perPage: perPage,
      equipmentId: equipmentId,
      maintenanceType: maintenanceType,
      isExpired: isExpired,
      expiringDays: expiringDays,
      includeDeleted: includeDeleted,
    );
  }

  // 특정 유지보수 상세 조회
  Future<MaintenanceDto> getMaintenanceDetail(int id) async {
    return await _repository.getMaintenanceDetail(id);
  }

  // 유지보수 생성
  Future<MaintenanceDto> createMaintenance(MaintenanceRequestDto request) async {
    // 기본 검증
    _validateMaintenanceRequest(request);
    
    return await _repository.createMaintenance(request);
  }

  // 유지보수 수정
  Future<MaintenanceDto> updateMaintenance(
      int id, MaintenanceUpdateRequestDto request) async {
    // 기본 검증
    if (request.periodMonth != null && request.periodMonth! <= 0) {
      throw Exception('유지보수 주기는 1개월 이상이어야 합니다.');
    }
    
    // 날짜 검증
    if (request.startedAt != null && request.endedAt != null) {
      if (request.endedAt!.isBefore(request.startedAt!)) {
        throw Exception('종료일은 시작일 이후여야 합니다.');
      }
    }
    
    // 유지보수 타입 검증
    if (request.maintenanceType != null && 
        !MaintenanceType.allTypes.contains(request.maintenanceType!)) {
      throw Exception('올바른 유지보수 타입을 선택해주세요.');
    }
    
    return await _repository.updateMaintenance(id, request);
  }

  // 유지보수 삭제 (소프트 삭제)
  Future<void> deleteMaintenance(int id) async {
    return await _repository.deleteMaintenance(id);
  }

  // 만료 예정 유지보수 조회
  Future<List<MaintenanceDto>> getExpiringMaintenances({int days = 30}) async {
    return await _repository.getExpiringMaintenances(days: days);
  }

  // 활성 유지보수만 조회 (is_deleted = false)
  Future<MaintenanceListResponse> getActiveMaintenances({
    int page = 1,
    int perPage = 20,
    int? equipmentId,
    String? maintenanceType,
  }) async {
    return await getMaintenances(
      page: page,
      perPage: perPage,
      equipmentId: equipmentId,
      maintenanceType: maintenanceType,
      includeDeleted: false, // 삭제된 항목 제외
    );
  }

  // 만료된 유지보수 조회
  Future<MaintenanceListResponse> getExpiredMaintenances({
    int page = 1,
    int perPage = 20,
  }) async {
    return await getMaintenances(
      page: page,
      perPage: perPage,
      isExpired: true,
      includeDeleted: false,
    );
  }

  // 특정 장비의 유지보수 내역 조회
  Future<MaintenanceListResponse> getMaintenancesByEquipment({
    required int equipmentId,
    int page = 1,
    int perPage = 20,
    bool includeDeleted = false,
  }) async {
    return await getMaintenances(
      page: page,
      perPage: perPage,
      equipmentId: equipmentId,
      includeDeleted: includeDeleted,
    );
  }

  // Private 검증 메서드
  void _validateMaintenanceRequest(MaintenanceRequestDto request) {
    // 유지보수 주기 검증
    if (request.periodMonth <= 0 || request.periodMonth > 120) {
      throw Exception('유지보수 주기는 1-120개월 사이여야 합니다.');
    }
    
    // 날짜 검증
    if (request.endedAt.isBefore(request.startedAt)) {
      throw Exception('종료일은 시작일 이후여야 합니다.');
    }
    
    // 유지보수 타입 검증 (백엔드와 일치)
    if (!MaintenanceType.allTypes.contains(request.maintenanceType)) {
      throw Exception('유지보수 타입은 ${MaintenanceType.allTypes.join(', ')} 중 하나여야 합니다.');
    }
  }

  // 유지보수 통계 조회
  Future<MaintenanceStatistics> getMaintenanceStatistics() async {
    // 첫 번째 페이지로 전체 개수 확인
    final response = await getMaintenances(perPage: 1);
    final totalCount = response.totalCount;
    
    // 전체 데이터 조회 (페이지 크기를 총 개수로 설정)
    final allDataResponse = await getMaintenances(
      perPage: totalCount > 0 ? totalCount : 1000,
      includeDeleted: false,
    );
    
    final maintenances = allDataResponse.items;
    
    int activeCount = maintenances.where((m) => m.isActive).length;
    int visitCount = maintenances.where((m) => m.maintenanceType == MaintenanceType.visit).length;
    int remoteCount = maintenances.where((m) => m.maintenanceType == MaintenanceType.remote).length;
    int expiredCount = maintenances.where((m) => m.isExpired).length;
    
    return MaintenanceStatistics(
      totalCount: totalCount,
      activeCount: activeCount,
      visitCount: visitCount,
      remoteCount: remoteCount,
      expiredCount: expiredCount,
    );
  }
}

/// 유지보수 통계 모델 (V/R 시스템)
class MaintenanceStatistics {
  final int totalCount;
  final int activeCount;
  final int visitCount;       // 방문 유지보수
  final int remoteCount;      // 원격 유지보수
  final int expiredCount;     // 만료된 것
  
  MaintenanceStatistics({
    required this.totalCount,
    required this.activeCount,
    required this.visitCount,
    required this.remoteCount,
    required this.expiredCount,
  });
}