import 'package:get_it/get_it.dart'; import 'package:flutter/foundation.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/common/paginated_response.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; LicenseService(this._remoteDataSource); // 라이선스 목록 조회 Future> getLicenses({ int page = 1, int perPage = 20, bool? isActive, int? companyId, int? assignedUserId, String? licenseType, bool includeInactive = false, }) async { debugPrint('\n╔════════════════════════════════════════════════════════════'); debugPrint('║ 📤 LICENSE API REQUEST'); debugPrint('╟────────────────────────────────────────────────────────────'); debugPrint('║ Endpoint: GET /licenses'); debugPrint('║ Parameters:'); debugPrint('║ - page: $page'); debugPrint('║ - perPage: $perPage'); if (isActive != null) debugPrint('║ - isActive: $isActive'); if (companyId != null) debugPrint('║ - companyId: $companyId'); if (assignedUserId != null) debugPrint('║ - assignedUserId: $assignedUserId'); if (licenseType != null) debugPrint('║ - licenseType: $licenseType'); debugPrint('║ - includeInactive: $includeInactive'); debugPrint('╚════════════════════════════════════════════════════════════\n'); try { final response = await _remoteDataSource.getLicenses( page: page, perPage: perPage, isActive: isActive ?? !includeInactive, companyId: companyId, assignedUserId: assignedUserId, licenseType: licenseType, ); final licenses = response.items.map((dto) => _convertDtoToLicense(dto)).toList(); debugPrint('\n╔════════════════════════════════════════════════════════════'); debugPrint('║ 📥 LICENSE API RESPONSE'); debugPrint('╟────────────────────────────────────────────────────────────'); debugPrint('║ Status: SUCCESS'); debugPrint('║ Total Items: ${response.total}'); debugPrint('║ Current Page: ${response.page}'); debugPrint('║ Total Pages: ${response.totalPages}'); debugPrint('║ Returned Items: ${licenses.length}'); if (licenses.isNotEmpty) { debugPrint('║ Sample Data:'); final sample = licenses.first; debugPrint('║ - ID: ${sample.id}'); debugPrint('║ - Product: ${sample.productName}'); debugPrint('║ - Company: ${sample.companyName ?? "N/A"}'); } debugPrint('╚════════════════════════════════════════════════════════════\n'); return PaginatedResponse( items: licenses, page: response.page, size: response.perPage, totalElements: response.total, totalPages: response.totalPages, first: response.page == 1, last: response.page >= response.totalPages, ); } on ApiException catch (e) { debugPrint('\n╔════════════════════════════════════════════════════════════'); debugPrint('║ ❌ LICENSE API ERROR'); debugPrint('╟────────────────────────────────────────────────────────────'); debugPrint('║ Type: ApiException'); debugPrint('║ Message: ${e.message}'); debugPrint('╚════════════════════════════════════════════════════════════\n'); throw ServerFailure(message: e.message); } catch (e) { debugPrint('\n╔════════════════════════════════════════════════════════════'); debugPrint('║ ❌ LICENSE API ERROR'); debugPrint('╟────────────────────────────────────────────────────────────'); debugPrint('║ Type: Unknown'); debugPrint('║ Error: $e'); debugPrint('╚════════════════════════════════════════════════════════════\n'); throw ServerFailure(message: '라이선스 목록을 불러오는 데 실패했습니다: $e'); } } // 라이선스 상세 조회 Future getLicenseById(int id) async { try { final dto = await _remoteDataSource.getLicenseById(id); return _convertDtoToLicense(dto); } on ApiException catch (e) { throw ServerFailure(message: e.message); } catch (e) { throw ServerFailure(message: '라이선스 정보를 불러오는 데 실패했습니다: $e'); } } // 라이선스 생성 Future createLicense(License license) async { debugPrint('\n╔════════════════════════════════════════════════════════════'); debugPrint('║ 📤 LICENSE CREATE REQUEST'); debugPrint('╟────────────────────────────────────────────────────────────'); debugPrint('║ Endpoint: POST /licenses'); debugPrint('║ Request Data:'); debugPrint('║ - licenseKey: ${license.licenseKey}'); debugPrint('║ - productName: ${license.productName}'); debugPrint('║ - vendor: ${license.vendor}'); debugPrint('║ - companyId: ${license.companyId}'); debugPrint('║ - expiryDate: ${license.expiryDate?.toIso8601String()}'); debugPrint('╚════════════════════════════════════════════════════════════\n'); try { final request = CreateLicenseRequest( 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, remark: license.remark, ); final dto = await _remoteDataSource.createLicense(request); final createdLicense = _convertDtoToLicense(dto); debugPrint('\n╔════════════════════════════════════════════════════════════'); debugPrint('║ 📥 LICENSE CREATE RESPONSE'); debugPrint('╟────────────────────────────────────────────────────────────'); debugPrint('║ Status: SUCCESS'); debugPrint('║ Created License:'); debugPrint('║ - ID: ${createdLicense.id}'); debugPrint('║ - Key: ${createdLicense.licenseKey}'); debugPrint('║ - Product: ${createdLicense.productName}'); debugPrint('╚════════════════════════════════════════════════════════════\n'); return createdLicense; } on ApiException catch (e) { debugPrint('\n╔════════════════════════════════════════════════════════════'); debugPrint('║ ❌ LICENSE CREATE ERROR'); debugPrint('╟────────────────────────────────────────────────────────────'); debugPrint('║ Type: ApiException'); debugPrint('║ Message: ${e.message}'); debugPrint('╚════════════════════════════════════════════════════════════\n'); throw ServerFailure(message: e.message); } catch (e) { debugPrint('\n╔════════════════════════════════════════════════════════════'); debugPrint('║ ❌ LICENSE CREATE ERROR'); debugPrint('╟────────────────────────────────────────────────────────────'); debugPrint('║ Type: Unknown'); debugPrint('║ Error: $e'); debugPrint('╚════════════════════════════════════════════════════════════\n'); throw ServerFailure(message: '라이선스 생성에 실패했습니다: $e'); } } // 라이선스 수정 Future updateLicense(License license) async { try { if (license.id == null) { throw BusinessFailure(message: '라이선스 ID가 없습니다'); } final request = UpdateLicenseRequest( licenseKey: license.licenseKey, productName: license.productName, vendor: license.vendor, licenseType: license.licenseType, userCount: license.userCount, purchaseDate: license.purchaseDate, expiryDate: license.expiryDate, purchasePrice: license.purchasePrice, remark: license.remark, isActive: license.isActive, ); final dto = await _remoteDataSource.updateLicense(license.id!, request); return _convertDtoToLicense(dto); } on ApiException catch (e) { throw ServerFailure(message: e.message); } catch (e) { throw ServerFailure(message: '라이선스 수정에 실패했습니다: $e'); } } // 라이선스 삭제 Future deleteLicense(int id) async { try { await _remoteDataSource.deleteLicense(id); } on ApiException catch (e) { throw ServerFailure(message: e.message); } catch (e) { throw ServerFailure(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 ServerFailure(message: e.message); } catch (e) { throw ServerFailure(message: '라이선스 할당에 실패했습니다: $e'); } } // 라이선스 할당 해제 Future unassignLicense(int licenseId) async { try { final dto = await _remoteDataSource.unassignLicense(licenseId); return _convertDtoToLicense(dto); } on ApiException catch (e) { throw ServerFailure(message: e.message); } catch (e) { throw ServerFailure(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 ServerFailure(message: e.message); } catch (e) { throw ServerFailure(message: '만료 예정 라이선스를 불러오는 데 실패했습니다: $e'); } } // DTO를 Flutter 모델로 변환 License _convertDtoToLicense(LicenseDto dto) { return License( id: dto.id, licenseKey: dto.licenseKey, productName: dto.productName, vendor: dto.vendor, licenseType: dto.licenseType, userCount: dto.userCount, purchaseDate: dto.purchaseDate, expiryDate: dto.expiryDate, purchasePrice: dto.purchasePrice, companyId: dto.companyId, branchId: dto.branchId, assignedUserId: dto.assignedUserId, remark: dto.remark, isActive: dto.isActive ?? true, createdAt: dto.createdAt, updatedAt: dto.updatedAt, companyName: dto.companyName, branchName: dto.branchName, assignedUserName: dto.assignedUserName, ); } // 만료 예정 DTO를 Flutter 모델로 변환 License _convertExpiringDtoToLicense(ExpiringLicenseDto dto) { return License( id: dto.id, licenseKey: dto.licenseKey, productName: dto.productName, vendor: null, licenseType: null, userCount: null, purchaseDate: null, expiryDate: dto.expiryDate, purchasePrice: null, companyId: null, branchId: null, assignedUserId: null, remark: null, isActive: dto.isActive ?? true, createdAt: null, updatedAt: null, companyName: dto.companyName, branchName: null, assignedUserName: null, ); } // 페이지네이션 정보 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; } } }