import 'package:dartz/dartz.dart';
import 'package:injectable/injectable.dart';
import '../../../data/models/license/license_dto.dart';
import '../../repositories/license_repository.dart';
import '../../../core/errors/failures.dart';
import '../base_usecase.dart';

/// 라이선스 만료일 체크 UseCase
@injectable
class CheckLicenseExpiryUseCase implements UseCase<LicenseExpiryResult, CheckLicenseExpiryParams> {
  final LicenseRepository repository;

  CheckLicenseExpiryUseCase(this.repository);

  @override
  Future<Either<Failure, LicenseExpiryResult>> call(CheckLicenseExpiryParams params) async {
    try {
      // 모든 라이선스 조회
      final allLicensesResult = await repository.getLicenses(
        page: 1,
        limit: 10000, // 모든 라이선스 조회
      );

      return allLicensesResult.fold(
        (failure) => Left(failure),
        (paginatedResponse) {
          final now = DateTime.now();
          final expiring30Days = <LicenseDto>[];
          final expiring60Days = <LicenseDto>[];
          final expiring90Days = <LicenseDto>[];
          final expired = <LicenseDto>[];

          for (final license in paginatedResponse.items) {
            final licenseDto = LicenseDto(
              id: license.id ?? 0,
              licenseKey: license.licenseKey,
              productName: license.productName,
              vendor: license.vendor,
              licenseType: license.licenseType,
              userCount: license.userCount,
              purchaseDate: license.purchaseDate,
              expiryDate: license.expiryDate,
              purchasePrice: license.purchasePrice,
              companyId: license.companyId,
              branchId: license.branchId,
              assignedUserId: license.assignedUserId,
              remark: license.remark,
              isActive: license.isActive ?? true,
              createdAt: license.createdAt ?? DateTime.now(),
              updatedAt: license.updatedAt ?? DateTime.now(),
              companyName: license.companyName,
              branchName: license.branchName,
              assignedUserName: license.assignedUserName,
            );

            if (licenseDto.expiryDate == null) continue;

            final daysUntilExpiry = licenseDto.expiryDate!.difference(now).inDays;

            if (daysUntilExpiry < 0) {
              expired.add(licenseDto);
            } else if (daysUntilExpiry <= 30) {
              expiring30Days.add(licenseDto);
            } else if (daysUntilExpiry <= 60) {
              expiring60Days.add(licenseDto);
            } else if (daysUntilExpiry <= 90) {
              expiring90Days.add(licenseDto);
            }
          }

          return Right(LicenseExpiryResult(
            expiring30Days: expiring30Days,
            expiring60Days: expiring60Days,
            expiring90Days: expiring90Days,
            expired: expired,
          ));
        },
      );
    } catch (e) {
      return Left(ServerFailure(message: e.toString()));
    }
  }
}

/// 라이선스 만료일 체크 파라미터
class CheckLicenseExpiryParams {
  final int? companyId;
  final String? equipmentType;

  CheckLicenseExpiryParams({
    this.companyId,
    this.equipmentType,
  });
}

/// 라이선스 만료일 체크 결과
class LicenseExpiryResult {
  final List<LicenseDto> expiring30Days;
  final List<LicenseDto> expiring60Days;
  final List<LicenseDto> expiring90Days;
  final List<LicenseDto> expired;

  LicenseExpiryResult({
    required this.expiring30Days,
    required this.expiring60Days,
    required this.expiring90Days,
    required this.expired,
  });

  int get totalExpiring => expiring30Days.length + expiring60Days.length + expiring90Days.length;
  int get totalExpired => expired.length;
}