import 'package:injectable/injectable.dart'; import 'package:superport/core/errors/exceptions.dart'; import 'package:superport/data/datasources/remote/user_remote_datasource.dart'; import 'package:superport/data/models/user/user_dto.dart'; import 'package:superport/models/user_model.dart'; @lazySingleton class UserService { final UserRemoteDataSource _userRemoteDataSource; UserService() : _userRemoteDataSource = UserRemoteDataSource(); /// 사용자 목록 조회 Future> getUsers({ int page = 1, int perPage = 20, bool? isActive, int? companyId, String? role, }) async { try { final response = await _userRemoteDataSource.getUsers( page: page, perPage: perPage, isActive: isActive, companyId: companyId, role: role != null ? _mapRoleToApi(role) : null, ); return response.users.map((dto) => _userDtoToModel(dto)).toList(); } catch (e) { throw Exception('사용자 목록 조회 실패: ${e.toString()}'); } } /// 특정 사용자 조회 Future getUser(int id) async { try { final dto = await _userRemoteDataSource.getUser(id); return _userDtoToModel(dto); } catch (e) { throw Exception('사용자 조회 실패: ${e.toString()}'); } } /// 사용자 생성 Future createUser({ required String username, required String email, required String password, required String name, required String role, required int companyId, int? branchId, String? phone, String? position, }) async { try { final request = CreateUserRequest( username: username, email: email, password: password, name: name, role: _mapRoleToApi(role), companyId: companyId, branchId: branchId, phone: phone, ); final dto = await _userRemoteDataSource.createUser(request); return _userDtoToModel(dto); } catch (e) { throw Exception('사용자 생성 실패: ${e.toString()}'); } } /// 사용자 정보 수정 Future updateUser( int id, { String? name, String? email, String? password, String? phone, int? companyId, int? branchId, String? role, String? position, }) async { try { final request = UpdateUserRequest( name: name, email: email, password: password, phone: phone, companyId: companyId, branchId: branchId, role: role != null ? _mapRoleToApi(role) : null, ); final dto = await _userRemoteDataSource.updateUser(id, request); return _userDtoToModel(dto); } catch (e) { throw Exception('사용자 수정 실패: ${e.toString()}'); } } /// 사용자 삭제 Future deleteUser(int id) async { try { await _userRemoteDataSource.deleteUser(id); } catch (e) { throw Exception('사용자 삭제 실패: ${e.toString()}'); } } /// 사용자 상태 변경 Future changeUserStatus(int id, bool isActive) async { try { final request = ChangeStatusRequest(isActive: isActive); final dto = await _userRemoteDataSource.changeUserStatus(id, request); return _userDtoToModel(dto); } catch (e) { throw Exception('사용자 상태 변경 실패: ${e.toString()}'); } } /// 비밀번호 변경 Future changePassword( int id, String currentPassword, String newPassword, ) async { try { final request = ChangePasswordRequest( currentPassword: currentPassword, newPassword: newPassword, ); await _userRemoteDataSource.changePassword(id, request); } catch (e) { throw Exception('비밀번호 변경 실패: ${e.toString()}'); } } /// 사용자명 중복 확인 Future checkDuplicateUsername(String username) async { try { return await _userRemoteDataSource.checkDuplicateUsername(username); } catch (e) { throw Exception('중복 확인 실패: ${e.toString()}'); } } /// 사용자 검색 Future> searchUsers({ required String query, int? companyId, String? status, String? permissionLevel, int page = 1, int perPage = 20, }) async { try { final response = await _userRemoteDataSource.searchUsers( query: query, companyId: companyId, status: status, permissionLevel: permissionLevel != null ? _mapRoleToApi(permissionLevel) : null, page: page, perPage: perPage, ); return response.users.map((dto) => _userDtoToModel(dto)).toList(); } catch (e) { throw Exception('사용자 검색 실패: ${e.toString()}'); } } /// DTO를 Model로 변환 User _userDtoToModel(UserDto dto) { return User( id: dto.id, companyId: dto.companyId ?? 0, branchId: dto.branchId, name: dto.name, role: _mapRoleFromApi(dto.role), position: null, // API에서 position 정보가 없음 email: dto.email, phoneNumbers: dto.phone != null ? [{'type': '기본', 'number': dto.phone!}] : [], username: dto.username, isActive: dto.isActive, createdAt: dto.createdAt, updatedAt: dto.updatedAt, ); } /// 권한을 API 형식으로 변환 String _mapRoleToApi(String role) { switch (role) { case 'S': return 'admin'; case 'M': return 'staff'; default: return 'staff'; } } /// API 권한을 앱 형식으로 변환 String _mapRoleFromApi(String role) { switch (role) { case 'admin': return 'S'; case 'manager': return 'M'; case 'staff': return 'M'; default: return 'M'; } } /// 전화번호 목록에서 첫 번째 전화번호 추출 String? getPhoneForApi(List> phoneNumbers) { if (phoneNumbers.isEmpty) return null; return phoneNumbers.first['number']; } }