import 'package:get_it/get_it.dart'; import 'package:injectable/injectable.dart'; import 'package:superport/core/errors/exceptions.dart'; import 'package:superport/core/errors/failures.dart'; import 'package:superport/data/datasources/remote/license_remote_datasource.dart'; import 'package:superport/data/models/license/license_dto.dart'; import 'package:superport/data/models/license/license_request_dto.dart'; import 'package:superport/models/license_model.dart'; @lazySingleton class LicenseService { final LicenseRemoteDataSource _remoteDataSource = GetIt.instance(); // 라이선스 목록 조회 Future> getLicenses({ int page = 1, int perPage = 20, bool? isActive, int? companyId, int? assignedUserId, String? licenseType, }) async { try { final response = await _remoteDataSource.getLicenses( page: page, perPage: perPage, isActive: isActive, companyId: companyId, assignedUserId: assignedUserId, licenseType: licenseType, ); return response.items.map((dto) => _convertDtoToLicense(dto)).toList(); } on ApiException catch (e) { throw Failure(message: e.message); } catch (e) { throw Failure(message: '라이선스 목록을 불러오는 데 실패했습니다: $e'); } } // 라이선스 상세 조회 Future getLicenseById(int id) async { try { final dto = await _remoteDataSource.getLicenseById(id); return _convertDtoToLicense(dto); } on ApiException catch (e) { throw Failure(message: e.message); } catch (e) { throw Failure(message: '라이선스 정보를 불러오는 데 실패했습니다: $e'); } } // 라이선스 생성 Future createLicense(License license) async { try { // Flutter 모델의 visitCycle과 durationMonths를 API 필드에 매핑 // visitCycle은 remark에 저장하고, durationMonths는 날짜 계산에 사용 final now = DateTime.now(); final expiryDate = now.add(Duration(days: license.durationMonths * 30)); final request = CreateLicenseRequest( licenseKey: license.name, // name을 licenseKey로 매핑 productName: '유지보수 계약', // 기본값 설정 licenseType: 'maintenance', // 유지보수 타입으로 고정 companyId: license.companyId, purchaseDate: now, expiryDate: expiryDate, remark: '방문주기: ${license.visitCycle}', // visitCycle을 remark에 저장 ); final dto = await _remoteDataSource.createLicense(request); return _convertDtoToLicense(dto); } on ApiException catch (e) { throw Failure(message: e.message); } catch (e) { throw Failure(message: '라이선스 생성에 실패했습니다: $e'); } } // 라이선스 수정 Future updateLicense(License license) async { try { if (license.id == null) { throw Failure(message: '라이선스 ID가 없습니다'); } // 기존 라이선스 정보를 먼저 조회 final existingDto = await _remoteDataSource.getLicenseById(license.id!); // 만료일 계산 (durationMonths가 변경된 경우) DateTime? newExpiryDate; if (existingDto.purchaseDate != null) { newExpiryDate = existingDto.purchaseDate!.add(Duration(days: license.durationMonths * 30)); } final request = UpdateLicenseRequest( licenseKey: license.name, expiryDate: newExpiryDate, remark: '방문주기: ${license.visitCycle}', ); final dto = await _remoteDataSource.updateLicense(license.id!, request); return _convertDtoToLicense(dto); } on ApiException catch (e) { throw Failure(message: e.message); } catch (e) { throw Failure(message: '라이선스 수정에 실패했습니다: $e'); } } // 라이선스 삭제 Future deleteLicense(int id) async { try { await _remoteDataSource.deleteLicense(id); } on ApiException catch (e) { throw Failure(message: e.message); } catch (e) { throw Failure(message: '라이선스 삭제에 실패했습니다: $e'); } } // 라이선스 할당 Future assignLicense(int licenseId, int userId) async { try { final request = AssignLicenseRequest(userId: userId); final dto = await _remoteDataSource.assignLicense(licenseId, request); return _convertDtoToLicense(dto); } on ApiException catch (e) { throw Failure(message: e.message); } catch (e) { throw Failure(message: '라이선스 할당에 실패했습니다: $e'); } } // 라이선스 할당 해제 Future unassignLicense(int licenseId) async { try { final dto = await _remoteDataSource.unassignLicense(licenseId); return _convertDtoToLicense(dto); } on ApiException catch (e) { throw Failure(message: e.message); } catch (e) { throw Failure(message: '라이선스 할당 해제에 실패했습니다: $e'); } } // 만료 예정 라이선스 조회 Future> getExpiringLicenses({ int days = 30, int page = 1, int perPage = 20, }) async { try { final response = await _remoteDataSource.getExpiringLicenses( days: days, page: page, perPage: perPage, ); return response.items.map((dto) => _convertExpiringDtoToLicense(dto)).toList(); } on ApiException catch (e) { throw Failure(message: e.message); } catch (e) { throw Failure(message: '만료 예정 라이선스를 불러오는 데 실패했습니다: $e'); } } // DTO를 Flutter 모델로 변환 License _convertDtoToLicense(LicenseDto dto) { // remark에서 방문주기 추출 String visitCycle = '미방문'; // 기본값 if (dto.remark != null && dto.remark!.contains('방문주기:')) { visitCycle = dto.remark!.split('방문주기:').last.trim(); } // 기간 계산 (purchaseDate와 expiryDate 차이) int durationMonths = 12; // 기본값 if (dto.purchaseDate != null && dto.expiryDate != null) { final difference = dto.expiryDate!.difference(dto.purchaseDate!); durationMonths = (difference.inDays / 30).round(); } return License( id: dto.id, companyId: dto.companyId ?? 0, name: dto.licenseKey, durationMonths: durationMonths, visitCycle: visitCycle, ); } // 만료 예정 DTO를 Flutter 모델로 변환 License _convertExpiringDtoToLicense(ExpiringLicenseDto dto) { return License( id: dto.id, companyId: 0, // ExpiringLicenseDto에는 companyId가 없으므로 기본값 사용 name: dto.licenseKey, durationMonths: 12, // 기본값 visitCycle: '미방문', // 기본값 ); } // 페이지네이션 정보 Future getTotalLicenses({ bool? isActive, int? companyId, int? assignedUserId, String? licenseType, }) async { try { final response = await _remoteDataSource.getLicenses( page: 1, perPage: 1, isActive: isActive, companyId: companyId, assignedUserId: assignedUserId, licenseType: licenseType, ); return response.total; } catch (e) { return 0; } } }