import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../domain/notifiers/profile_notifier.dart'; class EditProfilePage extends ConsumerStatefulWidget { const EditProfilePage({super.key}); @override ConsumerState createState() => _EditProfilePageState(); } class _EditProfilePageState extends ConsumerState { final _formKey = GlobalKey(); late TextEditingController _nameController; late TextEditingController _phoneController; late TextEditingController _codeController; late TextEditingController _departmentController; String? _initialPhone; bool _isPhoneChanged = false; bool _isPhoneVerified = false; bool _isCodeSent = false; bool _isVerifying = false; @override void initState() { super.initState(); final profile = ref.read(profileProvider).value; _initialPhone = profile?.phone ?? ''; _nameController = TextEditingController(text: profile?.name ?? ''); _phoneController = TextEditingController(text: _initialPhone); _codeController = TextEditingController(); _departmentController = TextEditingController(text: profile?.department ?? ''); _phoneController.addListener(() { setState(() { _isPhoneChanged = _phoneController.text != _initialPhone; if (_isPhoneChanged) { _isPhoneVerified = false; } }); }); } @override void dispose() { _nameController.dispose(); _phoneController.dispose(); _codeController.dispose(); _departmentController.dispose(); super.dispose(); } Future _sendCode() async { final phone = _phoneController.text; if (phone.isEmpty) return; setState(() => _isVerifying = true); try { await ref.read(profileRepositoryProvider).sendUpdateCode(phone); setState(() { _isCodeSent = true; _isVerifying = false; }); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('인증번호가 전송되었습니다.')), ); } } catch (e) { setState(() => _isVerifying = false); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('전송 실패: $e')), ); } } } Future _verifyCode() async { final phone = _phoneController.text; final code = _codeController.text; if (code.isEmpty) return; setState(() => _isVerifying = true); try { await ref.read(profileRepositoryProvider).verifyUpdateCode(phone, code); setState(() { _isPhoneVerified = true; _isVerifying = false; }); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('인증되었습니다.')), ); } } catch (e) { setState(() => _isVerifying = false); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('인증 실패: $e')), ); } } } Future _save() async { if (!_formKey.currentState!.validate()) return; if (_isPhoneChanged && !_isPhoneVerified) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('휴대폰 번호 인증이 필요합니다.')), ); return; } try { await ref.read(profileProvider.notifier).updateProfile( name: _nameController.text, phone: _phoneController.text, department: _departmentController.text, ); if (mounted) { context.pop(); ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('정보가 수정되었습니다.')), ); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('수정 실패: $e')), ); } } } @override Widget build(BuildContext context) { final profileState = ref.watch(profileProvider); final isUpdating = profileState.isLoading; return Scaffold( appBar: AppBar( title: const Text('내 정보 수정'), actions: [ TextButton( onPressed: (isUpdating || (_isPhoneChanged && !_isPhoneVerified)) ? null : _save, child: const Text('저장'), ), ], ), body: Padding( padding: const EdgeInsets.all(16.0), child: Form( key: _formKey, child: ListView( children: [ TextFormField( controller: _nameController, decoration: const InputDecoration( labelText: '이름', prefixIcon: Icon(Icons.person_outline), ), validator: (value) => (value == null || value.isEmpty) ? '이름을 입력해주세요.' : null, ), const SizedBox(height: 24), // Phone Number Field Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ Expanded( child: TextFormField( controller: _phoneController, decoration: InputDecoration( labelText: '휴대폰 번호', hintText: '01012345678', prefixIcon: const Icon(Icons.phone_android), suffixIcon: _isPhoneVerified ? const Icon(Icons.check_circle, color: Colors.green) : null, ), keyboardType: TextInputType.phone, enabled: !_isPhoneVerified, ), ), const SizedBox(width: 8), if (_isPhoneChanged && !_isPhoneVerified) ElevatedButton( onPressed: _isVerifying ? null : _sendCode, child: Text(_isCodeSent ? '재전송' : '인증요청'), ), ], ), // OTP Code Field if (_isCodeSent && !_isPhoneVerified) ...[ const SizedBox(height: 16), Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ Expanded( child: TextFormField( controller: _codeController, decoration: const InputDecoration( labelText: '인증번호', hintText: '6자리 입력', prefixIcon: Icon(Icons.security), ), keyboardType: TextInputType.number, ), ), const SizedBox(width: 8), ElevatedButton( onPressed: _isVerifying ? null : _verifyCode, style: ElevatedButton.styleFrom(backgroundColor: Colors.blue[700], foregroundColor: Colors.white), child: const Text('확인'), ), ], ), ], if (_isPhoneChanged && !_isPhoneVerified) const Padding( padding: EdgeInsets.only(top: 8.0, left: 4.0), child: Text( '휴대폰 번호를 변경하려면 SMS 인증이 필요합니다.', style: TextStyle(color: Colors.orange, fontSize: 12), ), ), const SizedBox(height: 24), TextFormField( controller: _departmentController, decoration: const InputDecoration( labelText: '소속 (부서)', prefixIcon: Icon(Icons.business), ), ), const SizedBox(height: 40), if (isUpdating || _isVerifying) const Center(child: CircularProgressIndicator()), ], ), ), ), ); } }