import 'dart:async'; import 'package:flutter/material.dart'; import 'package:get_it/get_it.dart'; import 'package:superport/models/company_model.dart'; import 'package:superport/models/user_model.dart'; import 'package:superport/services/user_service.dart'; import 'package:superport/services/company_service.dart'; import 'package:superport/utils/constants.dart'; import 'package:superport/models/user_phone_field.dart'; // 사용자 폼의 상태 및 비즈니스 로직을 담당하는 컨트롤러 class UserFormController extends ChangeNotifier { final UserService _userService = GetIt.instance(); final CompanyService _companyService = GetIt.instance(); final GlobalKey formKey = GlobalKey(); // 상태 변수 bool _isLoading = false; String? _error; // API만 사용 // 폼 필드 bool isEditMode = false; int? userId; String name = ''; String username = ''; // 추가 String password = ''; // 추가 int? companyId; int? branchId; String role = UserRoles.member; String position = ''; String email = ''; // username 중복 확인 bool _isCheckingUsername = false; bool? _isUsernameAvailable; String? _lastCheckedUsername; Timer? _usernameCheckTimer; // 전화번호 관련 상태 final List phoneFields = []; final List phoneTypes = ['휴대폰', '사무실', '팩스', '기타']; List companies = []; List branches = []; // Getters bool get isLoading => _isLoading; String? get error => _error; bool get isCheckingUsername => _isCheckingUsername; bool? get isUsernameAvailable => _isUsernameAvailable; UserFormController({this.userId}) { isEditMode = userId != null; if (isEditMode) { loadUser(); } else { addPhoneField(); } loadCompanies(); } // 회사 목록 로드 Future loadCompanies() async { try { final result = await _companyService.getCompanies(); companies = result; notifyListeners(); } catch (e) { debugPrint('회사 목록 로드 실패: $e'); companies = []; notifyListeners(); } } // 회사 ID에 따라 지점 목록 로드 void loadBranches(int companyId) { final company = companies.firstWhere( (c) => c.id == companyId, orElse: () => Company( id: companyId, name: '알 수 없는 회사', branches: [], ), ); branches = company.branches ?? []; // 지점 변경 시 이전 선택 지점이 새 회사에 없으면 초기화 if (branchId != null && !branches.any((b) => b.id == branchId)) { branchId = null; } notifyListeners(); } // 사용자 정보 로드 (수정 모드) Future loadUser() async { if (userId == null) return; _isLoading = true; _error = null; notifyListeners(); try { final user = await _userService.getUser(userId!); if (user != null) { name = user.name; username = user.username ?? ''; companyId = user.companyId; branchId = user.branchId; role = user.role; position = user.position ?? ''; email = user.email ?? ''; if (companyId != null) { loadBranches(companyId!); } phoneFields.clear(); if (user.phoneNumbers.isNotEmpty) { for (var phone in user.phoneNumbers) { phoneFields.add( UserPhoneField( type: phone['type'] ?? '휴대폰', initialValue: phone['number'] ?? '', ), ); } } else { addPhoneField(); } } } catch (e) { _error = e.toString(); } finally { _isLoading = false; notifyListeners(); } } // 전화번호 필드 추가 void addPhoneField() { phoneFields.add(UserPhoneField(type: '휴대폰')); notifyListeners(); } // 전화번호 필드 삭제 void removePhoneField(int index) { if (phoneFields.length > 1) { phoneFields[index].dispose(); phoneFields.removeAt(index); notifyListeners(); } } // Username 중복 확인 void checkUsernameAvailability(String value) { if (value.isEmpty || value == _lastCheckedUsername) { return; } // 디바운싱 _usernameCheckTimer?.cancel(); _usernameCheckTimer = Timer(const Duration(milliseconds: 500), () async { _isCheckingUsername = true; notifyListeners(); try { final isDuplicate = await _userService.checkDuplicateUsername(value); _isUsernameAvailable = !isDuplicate; _lastCheckedUsername = value; } catch (e) { _isUsernameAvailable = null; } finally { _isCheckingUsername = false; notifyListeners(); } }); } // 사용자 저장 (UI에서 호출) Future saveUser(Function(String? error) onResult) async { if (formKey.currentState?.validate() != true) { onResult('폼 유효성 검사 실패'); return; } formKey.currentState?.save(); if (companyId == null) { onResult('소속 회사를 선택해주세요'); return; } // 신규 등록 시 username 중복 확인 if (!isEditMode) { if (username.isEmpty) { onResult('사용자명을 입력해주세요'); return; } if (_isUsernameAvailable == false) { onResult('이미 사용중인 사용자명입니다'); return; } if (password.isEmpty) { onResult('비밀번호를 입력해주세요'); return; } } _isLoading = true; _error = null; notifyListeners(); try { // 전화번호 목록 준비 String? phoneNumber; for (var phoneField in phoneFields) { if (phoneField.number.isNotEmpty) { phoneNumber = phoneField.number; break; // API는 단일 전화번호만 지원 } } if (isEditMode && userId != null) { // 사용자 수정 await _userService.updateUser( userId!, name: name, email: email.isNotEmpty ? email : null, phone: phoneNumber, companyId: companyId, branchId: branchId, role: role, position: position.isNotEmpty ? position : null, password: password.isNotEmpty ? password : null, ); } else { // 사용자 생성 await _userService.createUser( username: username, email: email, password: password, name: name, role: role, companyId: companyId!, branchId: branchId, phone: phoneNumber, position: position.isNotEmpty ? position : null, ); } onResult(null); } catch (e) { _error = e.toString(); onResult(_error); } finally { _isLoading = false; notifyListeners(); } } // 컨트롤러 해제 @override void dispose() { _usernameCheckTimer?.cancel(); for (var phoneField in phoneFields) { phoneField.dispose(); } super.dispose(); } // API 모드만 사용 (Mock 데이터 제거됨) // void toggleApiMode() 메서드 제거 }