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/company_remote_datasource.dart'; import 'package:superport/data/models/company/company_dto.dart'; import 'package:superport/data/models/company/company_list_dto.dart'; import 'package:superport/data/models/company/branch_dto.dart'; import 'package:superport/models/company_model.dart'; import 'package:superport/models/address_model.dart'; @lazySingleton class CompanyService { final CompanyRemoteDataSource _remoteDataSource; CompanyService(this._remoteDataSource); // 회사 목록 조회 Future> getCompanies({ int page = 1, int perPage = 20, String? search, bool? isActive, }) async { try { final response = await _remoteDataSource.getCompanies( page: page, perPage: perPage, search: search, isActive: isActive, ); return response.items.map((dto) => _convertListDtoToCompany(dto)).toList(); } on ApiException catch (e) { debugPrint('[CompanyService] ApiException: ${e.message}'); throw ServerFailure(message: e.message); } catch (e, stackTrace) { debugPrint('[CompanyService] Error loading companies: $e'); debugPrint('[CompanyService] Stack trace: $stackTrace'); throw ServerFailure(message: 'Failed to fetch company list: $e'); } } // 회사 생성 Future createCompany(Company company) async { try { final request = CreateCompanyRequest( name: company.name, address: company.address.toString(), contactName: company.contactName ?? '', contactPosition: company.contactPosition ?? '', contactPhone: company.contactPhone ?? '', contactEmail: company.contactEmail ?? '', companyTypes: company.companyTypes.map((e) => e.toString().split('.').last).toList(), remark: company.remark, ); debugPrint('[CompanyService] Creating company with request: ${request.toJson()}'); final response = await _remoteDataSource.createCompany(request); debugPrint('[CompanyService] Company created with ID: ${response.id}'); return _convertResponseToCompany(response); } on ApiException catch (e) { debugPrint('[CompanyService] ApiException during company creation: ${e.message}'); throw ServerFailure(message: e.message); } catch (e, stackTrace) { debugPrint('[CompanyService] Unexpected error during company creation: $e'); debugPrint('[CompanyService] Stack trace: $stackTrace'); throw ServerFailure(message: 'Failed to create company: $e'); } } // 회사 상세 조회 Future getCompanyDetail(int id) async { try { final response = await _remoteDataSource.getCompanyDetail(id); return _convertResponseToCompany(response); } on ApiException catch (e) { throw ServerFailure(message: e.message); } catch (e) { throw ServerFailure(message: 'Failed to fetch company detail: $e'); } } // 회사와 지점 정보 함께 조회 Future getCompanyWithBranches(int id) async { try { final response = await _remoteDataSource.getCompanyWithBranches(id); final company = _convertResponseToCompany(response.company); final branches = response.branches.map((dto) => _convertBranchDtoToBranch(dto)).toList(); return company.copyWith(branches: branches); } on ApiException catch (e) { throw ServerFailure(message: e.message); } catch (e) { throw ServerFailure(message: 'Failed to fetch company with branches: $e'); } } // 회사 수정 Future updateCompany(int id, Company company) async { try { final request = UpdateCompanyRequest( name: company.name, address: company.address.toString(), contactName: company.contactName, contactPosition: company.contactPosition, contactPhone: company.contactPhone, contactEmail: company.contactEmail, companyTypes: company.companyTypes.map((e) => e.toString().split('.').last).toList(), remark: company.remark, ); final response = await _remoteDataSource.updateCompany(id, request); return _convertResponseToCompany(response); } on ApiException catch (e) { throw ServerFailure(message: e.message); } catch (e) { throw ServerFailure(message: 'Failed to update company: $e'); } } // 회사 삭제 Future deleteCompany(int id) async { try { await _remoteDataSource.deleteCompany(id); } on ApiException catch (e) { throw ServerFailure(message: e.message); } catch (e) { throw ServerFailure(message: 'Failed to delete company: $e'); } } // 회사명 목록 조회 (드롭다운용) Future>> getCompanyNames() async { try { final dtoList = await _remoteDataSource.getCompanyNames(); return dtoList.map((dto) => { 'id': dto.id, 'name': dto.name, }).toList(); } on ApiException catch (e) { throw ServerFailure(message: e.message); } catch (e) { throw ServerFailure(message: 'Failed to fetch company names: $e'); } } // 지점 관련 메서드들 Future createBranch(int companyId, Branch branch) async { try { final request = CreateBranchRequest( branchName: branch.name, address: branch.address.toString(), phone: branch.contactPhone ?? '', managerName: branch.contactName, managerPhone: branch.contactPhone, remark: branch.remark, ); final response = await _remoteDataSource.createBranch(companyId, request); return _convertBranchResponseToBranch(response); } on ApiException catch (e) { throw ServerFailure(message: e.message); } catch (e) { throw ServerFailure(message: 'Failed to create branch: $e'); } } Future getBranchDetail(int companyId, int branchId) async { try { final response = await _remoteDataSource.getBranchDetail(companyId, branchId); return _convertBranchResponseToBranch(response); } on ApiException catch (e) { throw ServerFailure(message: e.message); } catch (e) { throw ServerFailure(message: 'Failed to fetch branch detail: $e'); } } Future updateBranch(int companyId, int branchId, Branch branch) async { try { final request = UpdateBranchRequest( branchName: branch.name, address: branch.address.toString(), phone: branch.contactPhone, managerName: branch.contactName, managerPhone: branch.contactPhone, remark: branch.remark, ); final response = await _remoteDataSource.updateBranch(companyId, branchId, request); return _convertBranchResponseToBranch(response); } on ApiException catch (e) { throw ServerFailure(message: e.message); } catch (e) { throw ServerFailure(message: 'Failed to update branch: $e'); } } Future deleteBranch(int companyId, int branchId) async { try { await _remoteDataSource.deleteBranch(companyId, branchId); } on ApiException catch (e) { throw ServerFailure(message: e.message); } catch (e) { throw ServerFailure(message: 'Failed to delete branch: $e'); } } Future> getCompanyBranches(int companyId) async { try { final dtoList = await _remoteDataSource.getCompanyBranches(companyId); return dtoList.map((dto) => _convertBranchDtoToBranch(dto)).toList(); } on ApiException catch (e) { throw ServerFailure(message: e.message); } catch (e) { throw ServerFailure(message: 'Failed to fetch company branches: $e'); } } // 회사-지점 전체 정보 조회 Future> getCompaniesWithBranches() async { try { return await _remoteDataSource.getCompaniesWithBranches(); } on ApiException catch (e) { throw ServerFailure(message: e.message); } catch (e) { throw ServerFailure(message: 'Failed to fetch companies with branches: $e'); } } // 회사명 중복 확인 Future checkDuplicateCompany(String name) async { try { return await _remoteDataSource.checkDuplicateCompany(name); } on ApiException catch (e) { throw ServerFailure(message: e.message); } catch (e) { throw ServerFailure(message: 'Failed to check duplicate: $e'); } } // 회사 검색 Future> searchCompanies(String query) async { try { final dtoList = await _remoteDataSource.searchCompanies(query); return dtoList.map((dto) => _convertListDtoToCompany(dto)).toList(); } on ApiException catch (e) { throw ServerFailure(message: e.message); } catch (e) { throw ServerFailure(message: 'Failed to search companies: $e'); } } // 회사 활성 상태 변경 Future updateCompanyStatus(int id, bool isActive) async { try { await _remoteDataSource.updateCompanyStatus(id, isActive); } on ApiException catch (e) { throw ServerFailure(message: e.message); } catch (e) { throw ServerFailure(message: 'Failed to update company status: $e'); } } // 변환 헬퍼 메서드들 Company _convertListDtoToCompany(CompanyListDto dto) { return Company( id: dto.id, name: dto.name, address: Address.fromFullAddress(dto.address), contactName: dto.contactName, contactPhone: dto.contactPhone, companyTypes: [CompanyType.customer], // 기본값, 실제로는 API에서 받아와야 함 branches: [], // branches는 빈 배열로 초기화 ); } Company _convertResponseToCompany(CompanyResponse dto) { final companyTypes = dto.companyTypes.map((typeStr) { if (typeStr.contains('partner')) return CompanyType.partner; return CompanyType.customer; }).toList(); return Company( id: dto.id, name: dto.name, address: Address.fromFullAddress(dto.address), contactName: dto.contactName, contactPosition: dto.contactPosition, contactPhone: dto.contactPhone, contactEmail: dto.contactEmail, companyTypes: companyTypes.isEmpty ? [CompanyType.customer] : companyTypes, remark: dto.remark, branches: [], // branches는 빈 배열로 초기화 ); } Branch _convertBranchDtoToBranch(BranchListDto dto) { return Branch( id: dto.id, companyId: dto.companyId, name: dto.branchName, address: Address.fromFullAddress(dto.address), contactName: dto.managerName, contactPhone: dto.phone, ); } Branch _convertBranchResponseToBranch(BranchResponse dto) { return Branch( id: dto.id, companyId: dto.companyId, name: dto.branchName, address: Address.fromFullAddress(dto.address), contactName: dto.managerName, contactPhone: dto.phone, remark: dto.remark, ); } } // Company 모델에 copyWith 메서드가 없다면 extension으로 추가 extension CompanyExtension on Company { Company copyWith({ int? id, String? name, Address? address, String? contactName, String? contactPosition, String? contactPhone, String? contactEmail, List? branches, List? companyTypes, String? remark, }) { return Company( id: id ?? this.id, name: name ?? this.name, address: address ?? this.address, contactName: contactName ?? this.contactName, contactPosition: contactPosition ?? this.contactPosition, contactPhone: contactPhone ?? this.contactPhone, contactEmail: contactEmail ?? this.contactEmail, branches: branches ?? this.branches, companyTypes: companyTypes ?? this.companyTypes, remark: remark ?? this.remark, ); } }