import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:intl/intl.dart';

import '../../utils/url_utils.dart';
import '../../utils/test_utils.dart';
import '../../utils/enum_mappings.dart';

import '../../models/event_model.dart';
import '../../services/event_service.dart';
import '../../widgets/loading_indicator.dart';

class EventFormScreen extends StatefulWidget {
  final Event? event; // null이면 새 이벤트 생성, 아니면 이벤트 수정

  const EventFormScreen({Key? key, this.event}) : super(key: key);

  @override
  State<EventFormScreen> createState() => _EventFormScreenState();
}

class _EventFormScreenState extends State<EventFormScreen> {
  final _formKey = GlobalKey<FormState>();
  bool _isLoading = false;
  bool _obscurePassword = true; // 비밀번호 숨김 상태 관리
  bool _testSaveMode = false; // 테스트 훅에서 저장 시 네비/스낵바 우회
  // 통화 기호 없이 천단위 구분만 적용
  final _currencyFormat = NumberFormat.decimalPattern('ko_KR');

  // 폼 필드 컨트롤러
  final TextEditingController _titleController = TextEditingController();
  final TextEditingController _descriptionController = TextEditingController();
  final TextEditingController _locationController = TextEditingController();
  final TextEditingController _maxParticipantsController =
      TextEditingController();
  final TextEditingController _gameCountController = TextEditingController();
  final TextEditingController _participantFeeController =
      TextEditingController();
  final TextEditingController _formattedFeeController =
      TextEditingController(); // 포맷된 참가비 표시용
  final TextEditingController _publicHashController = TextEditingController();
  final TextEditingController _accessPasswordController =
      TextEditingController();
  // 공개 URL 표시 전용 컨트롤러(읽기 전용, 빌드마다 새로 만들지 않도록 고정)
  final TextEditingController _publicUrlDisplayController =
      TextEditingController();

  // 이벤트 데이터
  String? _type;
  String? _status;
  DateTime _startDate = DateTime.now();
  DateTime? _endDate;
  DateTime? _registrationDeadline;

  // 이벤트 유형 및 상태 옵션(공용 매핑 사용)
  late final List<String> _typeOptions = eventTypeOptions.values.toList();
  late final List<String> _statusOptions = eventStatusOptions.values.toList();

  // 이벤트 상태별 색상 (유지)
  final Map<String, Color> _statusColors = {
    '활성': Colors.green,
    '대기': Colors.amber,
    '취소': Colors.red,
    '완료': Colors.blue,
  };

  final Map<String, IconData> _statusIcons = {
    '활성': Icons.check_circle,
    '대기': Icons.hourglass_empty,
    '취소': Icons.cancel,
    '완료': Icons.done_all,
  };

  @override
  void initState() {
    super.initState();

    if (widget.event != null) {
      // 기존 이벤트 수정 시 필드 초기화
      _titleController.text = widget.event!.title;
      _descriptionController.text = widget.event!.description ?? '';
      _locationController.text = widget.event!.location ?? '';
      _maxParticipantsController.text =
          widget.event!.maxParticipants?.toString() ?? '';
      _gameCountController.text = widget.event!.gameCount?.toString() ?? '';
      _publicHashController.text = widget.event!.publicHash ?? '';
      // 공개 URL 표시 초기화
      if (_publicHashController.text.trim().isNotEmpty) {
        _publicUrlDisplayController.text = UrlUtils.getEventPublicUrl(
          _publicHashController.text.trim(),
        );
      } else {
        _publicUrlDisplayController.text = '';
      }
      _accessPasswordController.text = widget.event!.accessPassword ?? '';

      // API 값(type/status)을 한국어 라벨로 변환하여 드롭다운에 설정
      _type = widget.event!.type != null
          ? (eventTypeOptions[widget.event!.type] ?? widget.event!.type)
          : null;
      _status = widget.event!.status != null
          ? (eventStatusOptions[widget.event!.status] ?? widget.event!.status)
          : null;
      _startDate = widget.event!.startDate;
      _endDate = widget.event!.endDate;
      _registrationDeadline = widget.event!.registrationDeadline;

      // 참가비가 있으면 포맷된 참가비 컨트롤러 초기화
      if (widget.event!.participantFee != null) {
        _updateFormattedFee(widget.event!.participantFee.toString());
      }
    } else {
      // 새 이벤트 생성 시 기본값 설정
      _type = _typeOptions[0];
      _status = _statusOptions[0];
      // 공개 해시를 동기로 초기화하여 초기 렌더 타이밍 변동을 줄임
      if (_publicHashController.text.isEmpty && !_isHashGenerated) {
        _isHashGenerated = true;
        final hash = UrlUtils.generatePublicHash();
        _publicHashController.text = hash;
        _publicUrlDisplayController.text = UrlUtils.getEventPublicUrl(hash);
        // 스낵바는 테스트에서 불필요하므로 생략, 일반 환경에서도 최초 자동 생성 시에는 표시하지 않음
      }
    }

    // 참가비 입력 컨트롤러에 리스너 추가
    _participantFeeController.addListener(_onParticipantFeeChanged);
  }

  bool _isHashGenerated = false;

  // didChangeDependencies 사용 시 프레임 콜백에 의한 타이밍 변동이 생겨 테스트 플래키를 유발할 수 있어 제거

  @override
  void dispose() {
    _titleController.dispose();
    _descriptionController.dispose();
    _locationController.dispose();
    _maxParticipantsController.dispose();
    _gameCountController.dispose();
    _participantFeeController.removeListener(_onParticipantFeeChanged);
    _participantFeeController.dispose();
    _formattedFeeController.dispose();
    _publicHashController.dispose();
    _accessPasswordController.dispose();
    _publicUrlDisplayController.dispose();
    super.dispose();
  }

  // 공개 URL 해시 생성
  void _generatePublicHash() {
    // 이전 해시 저장
    final previousHash = _publicHashController.text;
    final isNew = previousHash.isEmpty;

    // 새 해시 생성
    final hash = UrlUtils.generatePublicHash();

    setState(() {
      _publicHashController.text = hash;
      _publicUrlDisplayController.text = UrlUtils.getEventPublicUrl(hash);
    });

    // 해시 생성 후 사용자에게 피드백 제공
    // 테스트 환경에서는 로그만 출력하고, 일반 환경에서만 스낵바 표시
    if (mounted) {
      if (TestUtils.isInTest) {
        debugPrint('해시 생성 완료: $hash');
      } else {
        // 일반 환경에서는 다음 프레임에서 스낵바 표시
        WidgetsBinding.instance.addPostFrameCallback((_) {
          if (mounted) {
            try {
              final scaffoldMessenger = ScaffoldMessenger.of(context);
              final message = isNew
                  ? '공개 URL 해시가 생성되었습니다'
                  : '공개 URL 해시가 재생성되었습니다. 이전 URL은 더 이상 유효하지 않습니다';

              scaffoldMessenger.showSnackBar(
                SnackBar(
                  content: Text(message),
                  action: SnackBarAction(
                    label: 'URL 복사',
                    onPressed: () {
                      final url = UrlUtils.getEventPublicUrl(hash);
                      UrlUtils.copyUrlToClipboard(context, url);
                    },
                  ),
                ),
              );
            } catch (e) {
              debugPrint('스낵바 표시 오류: $e');
            }
          }
        });
      }
    }
  }

  // 이벤트 저장
  Future<void> _saveEvent() async {
    final isValid = _formKey.currentState!.validate();

    if (!isValid && !_testSaveMode) {
      // 유효성 검사 실패 시 스낵바로 알림
      if (mounted) {
        // 테스트 환경에서 안전하게 SnackBar 표시
        if (TestUtils.isInTest) {
          debugPrint('유효성 검사 실패: 필수 입력 항목을 모두 작성해주세요');
        } else {
          // 일반 환경에서는 SnackBar 표시
          WidgetsBinding.instance.addPostFrameCallback((_) {
            if (mounted) {
              final scaffoldMessenger = ScaffoldMessenger.of(context);
              scaffoldMessenger.hideCurrentSnackBar();
              scaffoldMessenger.showSnackBar(
                const SnackBar(
                  content: Text('필수 입력 항목을 모두 작성해주세요 (제목, 이벤트 유형, 상태, 시작 날짜)'),
                  backgroundColor: Colors.red,
                  duration: Duration(seconds: 3),
                ),
              );
            }
          });
        }
      }
      return;
    }

    setState(() {
      _isLoading = true;
    });

    try {
      final eventService = Provider.of<EventService>(context, listen: false);

      // 라벨을 API 키로 역매핑하는 헬퍼
      String? _labelToKey(Map<String, String> map, String? label) {
        if (label == null) return null;
        try {
          return map.entries.firstWhere((e) => e.value == label).key;
        } catch (_) {
          return label; // 매칭 실패 시 원문 유지(안전장치)
        }
      }

      // 이벤트 데이터 준비 - null 값 처리 개선
      // 참가비 보강: 숨겨진 컨트롤러가 비어있을 경우 포맷 필드에서 숫자만 추출하여 사용
      double? _resolveParticipantFee() {
        if (_participantFeeController.text.isNotEmpty) {
          return double.tryParse(_participantFeeController.text);
        }
        if (_formattedFeeController.text.isNotEmpty) {
          final plain = _formattedFeeController.text.replaceAll(RegExp(r'[^0-9]'), '');
          if (plain.isNotEmpty) return double.tryParse(plain);
        }
        return null;
      }
      final eventData = {
        'title': _titleController.text.trim(),
        'description': _descriptionController.text.trim().isEmpty
            ? null
            : _descriptionController.text.trim(),
        'location': _locationController.text.trim().isEmpty
            ? null
            : _locationController.text.trim(),
        // 한국어 라벨을 API 값으로 변환하여 전송
        'type': _labelToKey(eventTypeOptions, _type),
        'status': _labelToKey(eventStatusOptions, _status),
        'startDate': _startDate.toIso8601String(),
        'endDate': _endDate?.toIso8601String(),
        'maxParticipants': _maxParticipantsController.text.isEmpty
            ? null
            : int.parse(_maxParticipantsController.text),
        'gameCount': _gameCountController.text.isEmpty
            ? null
            : int.parse(_gameCountController.text),
        // 백엔드가 문자열 금액("0.00")을 사용하므로 전송 시에도 문자열로 정렬
        // 일부 라우트 호환을 위해 'entryFee'도 함께 전송
        'participantFee': (() {
          final fee = _resolveParticipantFee();
          if (fee == null) return null; // 빈값은 숨김
          return fee.toStringAsFixed(2); // 예: 20000.00, 0.00
        })(),
        'entryFee': (() {
          final fee = _resolveParticipantFee();
          if (fee == null) return null;
          return fee.toStringAsFixed(2);
        })(),
        'fee': (() {
          final fee = _resolveParticipantFee();
          if (fee == null) return null;
          return fee.toStringAsFixed(2);
        })(),
        'registrationDeadline': _registrationDeadline?.toIso8601String(),
        'publicHash': _publicHashController.text.trim().isEmpty
            ? null
            : _publicHashController.text.trim(),
        'accessPassword': _accessPasswordController.text.trim().isEmpty
            ? null
            : _accessPasswordController.text.trim(),
      };

      // 서버에 명시적으로 null 값을 전송하기 위해 빈 문자열을 null로 변환
      // JavaScript에서 || 연산자로 인한 문제 방지
      eventData.forEach((key, value) {
        if (value is String && value.isEmpty) {
          eventData[key] = null;
        }
      });

      // 디버그용 로그 - 개발 완료 후 제거 필요
      debugPrint('Event data to send: $eventData');

      if (widget.event == null) {
        // 새 이벤트 생성
        await eventService.createEvent(eventData);
        if (mounted && !_testSaveMode) {
          // 테스트가 아니면 스낵바 표시
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(
              content: const Text('이벤트가 생성되었습니다'),
              action: SnackBarAction(label: '확인', onPressed: () {}),
              duration: const Duration(seconds: 3),
            ),
          );
        }
      } else {
        // 기존 이벤트 수정
        await eventService.updateEvent(widget.event!.id, eventData);
        if (mounted && !_testSaveMode) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(
              content: const Text('이벤트가 수정되었습니다'),
              action: SnackBarAction(label: '확인', onPressed: () {}),
              duration: const Duration(seconds: 3),
            ),
          );
        }
      }

      if (mounted) {
        // 성공 후 로딩 해제 (테스트/일반 공통)
        setState(() {
          _isLoading = false;
        });
        if (!_testSaveMode) {
          Navigator.of(context).pop(true); // 성공 결과와 함께 이전 화면으로 돌아가기
        }
      }
    } catch (e) {
      if (mounted) {
        setState(() {
          _isLoading = false;
        });

        // 테스트 환경에서 안전하게 SnackBar 표시
        if (TestUtils.isInTest) {
          debugPrint('이벤트 저장에 실패했습니다: $e');
        } else {
          ScaffoldMessenger.of(
            context,
          ).showSnackBar(SnackBar(content: Text('이벤트 저장에 실패했습니다: $e')));
        }
      }
    }
  }

  // 테스트 편의를 위한 공개 훅: 버튼 탭 없이 저장 플로우 직접 호출
  @visibleForTesting
  Future<void> invokeSaveForTest() async {
    _testSaveMode = true;
    try {
      await _saveEvent();
    } finally {
      _testSaveMode = false;
    }
  }

  @override
  Widget build(BuildContext context) {
    // 테스트 환경에서 애니메이션 비활성화
    final Widget scaffold = Scaffold(
      appBar: AppBar(
        title: Text(widget.event == null ? '새 이벤트 생성' : '이벤트 수정'),
        actions: [
          IconButton(icon: const Icon(Icons.save), onPressed: _saveEvent),
        ],
      ),
      body: _isLoading
          ? const LoadingIndicator()
          : SingleChildScrollView(
              padding: const EdgeInsets.all(16.0),
              child: Form(
                key: _formKey,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    // 기본 정보 섹션
                    _buildSectionTitle('기본 정보'),

                    // 제목
                    TextFormField(
                      controller: _titleController,
                      decoration: InputDecoration(
                        labelText: '이벤트 제목 *',
                        hintText: '이벤트 제목을 입력하세요',
                        prefixIcon: const Icon(Icons.title),
                        // 필수 필드 표시 강화
                        labelStyle: TextStyle(
                          color: _titleController.text.trim().isEmpty
                              ? Colors.red
                              : Colors.blue,
                          fontWeight: FontWeight.bold,
                        ),
                        // 입력 상태에 따른 테두리 색상 변경
                        enabledBorder: OutlineInputBorder(
                          borderSide: BorderSide(
                            color: _titleController.text.trim().isEmpty
                                ? Colors.grey
                                : Colors.green,
                            width: 1.0,
                          ),
                        ),
                        focusedBorder: const OutlineInputBorder(
                          borderSide: BorderSide(
                            color: Colors.blue,
                            width: 2.0,
                          ),
                        ),
                        // 오류 시 테두리 색상
                        errorBorder: const OutlineInputBorder(
                          borderSide: BorderSide(color: Colors.red, width: 1.0),
                        ),
                        // 입력 상태에 따른 도움말 텍스트
                        helperText: _titleController.text.trim().isNotEmpty
                            ? '유효한 제목입니다'
                            : '이벤트의 제목을 입력해주세요 (필수)',
                        helperStyle: TextStyle(
                          color: _titleController.text.trim().isEmpty
                              ? Colors.grey
                              : Colors.green,
                          fontStyle: _titleController.text.trim().isEmpty
                              ? FontStyle.italic
                              : FontStyle.normal,
                        ),
                        // 입력 완료 시 체크 아이콘 표시
                        suffixIcon: _titleController.text.trim().isNotEmpty
                            ? const Icon(
                                Icons.check_circle,
                                color: Colors.green,
                              )
                            : null,
                      ),
                      validator: (value) {
                        if (value == null || value.trim().isEmpty) {
                          return '이벤트 제목을 입력해주세요';
                        }
                        return null;
                      },
                      onChanged: (value) {
                        // 입력 변경 시 실시간으로 UI 업데이트
                        setState(() {});
                      },
                    ),
                    const SizedBox(height: 16),

                    // 설명
                    TextFormField(
                      controller: _descriptionController,
                      decoration: const InputDecoration(
                        labelText: '이벤트 설명',
                        hintText: '이벤트 설명을 입력하세요',
                      ),
                      maxLines: 3,
                    ),
                    const SizedBox(height: 16),

                    // 이벤트 유형
                    DropdownButtonFormField<String>(
                      key: const Key('event_form_type_dropdown'),
                      value: _type,
                      decoration: InputDecoration(
                        labelText: '이벤트 유형 *',
                        labelStyle: TextStyle(
                          color: _type == null ? Colors.red : Colors.blue,
                          fontWeight: FontWeight.bold,
                        ),
                        prefixIcon: const Icon(Icons.category),
                        helperText: _type != null
                            ? '유효한 이벤트 유형입니다'
                            : '이벤트 유형을 선택해주세요 (필수)',
                        helperStyle: TextStyle(
                          color: _type == null ? Colors.grey : Colors.green,
                          fontStyle: _type == null
                              ? FontStyle.italic
                              : FontStyle.normal,
                        ),
                        // 입력 상태에 따른 테두리 색상 변경
                        enabledBorder: OutlineInputBorder(
                          borderSide: BorderSide(
                            color: _type == null ? Colors.grey : Colors.green,
                            width: 1.0,
                          ),
                        ),
                        focusedBorder: const OutlineInputBorder(
                          borderSide: BorderSide(
                            color: Colors.blue,
                            width: 2.0,
                          ),
                        ),
                        // 오류 시 테두리 색상
                        errorBorder: const OutlineInputBorder(
                          borderSide: BorderSide(color: Colors.red, width: 1.0),
                        ),
                      ),
                      isExpanded: true,
                      items: _typeOptions
                          .map(
                            (type) => DropdownMenuItem<String>(
                              value: type,
                              child: Row(
                                children: [
                                  const Icon(
                                    Icons.category,
                                    size: 18,
                                    color: Colors.grey,
                                  ),
                                  const SizedBox(width: 8),
                                  Flexible(
                                    child: Text(
                                      type,
                                      maxLines: 1,
                                      overflow: TextOverflow.ellipsis,
                                      style: const TextStyle(
                                        color: Colors.black87,
                                      ),
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          )
                          .toList(),
                      onChanged: (value) {
                        setState(() {
                          _type = value;
                        });
                      },
                      validator: (value) {
                        if (value == null || value.isEmpty) {
                          return '이벤트 유형을 선택해주세요';
                        }
                        return null;
                      },
                    ),
                    const SizedBox(height: 16),

                    // 상태
                    DropdownButtonFormField<String>(
                      key: const Key('event_form_status_dropdown'),
                      value: _status,
                      decoration: InputDecoration(
                        labelText: '상태 *',
                        labelStyle: TextStyle(
                          color: _status == null ? Colors.red : Colors.blue,
                          fontWeight: FontWeight.bold,
                        ),
                        prefixIcon: const Icon(Icons.info_outline),
                        helperText: _status != null
                            ? '유효한 상태입니다'
                            : '이벤트 상태를 선택해주세요 (필수)',
                        helperStyle: TextStyle(
                          color: _status == null ? Colors.grey : Colors.green,
                          fontStyle: _status == null
                              ? FontStyle.italic
                              : FontStyle.normal,
                        ),
                        // 입력 상태에 따른 테두리 색상 변경
                        enabledBorder: OutlineInputBorder(
                          borderSide: BorderSide(
                            color: _status == null ? Colors.grey : Colors.green,
                            width: 1.0,
                          ),
                        ),
                        focusedBorder: const OutlineInputBorder(
                          borderSide: BorderSide(
                            color: Colors.blue,
                            width: 2.0,
                          ),
                        ),
                        // 오류 시 테두리 색상
                        errorBorder: const OutlineInputBorder(
                          borderSide: BorderSide(color: Colors.red, width: 1.0),
                        ),
                      ),
                      isExpanded: true,
                      items: _statusOptions
                          .map(
                            (status) => DropdownMenuItem<String>(
                              value: status,
                              child: Row(
                                children: [
                                  Icon(
                                    _statusIcons[status] ?? Icons.info,
                                    color: _statusColors[status],
                                    size: 18,
                                  ),
                                  const SizedBox(width: 8),
                                  Container(
                                    padding: const EdgeInsets.symmetric(
                                      horizontal: 8,
                                      vertical: 2,
                                    ),
                                    decoration: BoxDecoration(
                                      color: _statusColors[status]?.withValues(
                                        alpha: 0.2,
                                      ),
                                      borderRadius: BorderRadius.circular(12),
                                      border: Border.all(
                                        color:
                                            _statusColors[status] ??
                                            Colors.grey,
                                      ),
                                    ),
                                    child: Text(
                                      status,
                                      style: TextStyle(
                                        color: _statusColors[status],
                                      ),
                                      maxLines: 1,
                                      overflow: TextOverflow.ellipsis,
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          )
                          .toList(),
                      onChanged: (value) {
                        setState(() {
                          _status = value;
                        });
                      },
                      validator: (value) {
                        if (value == null || value.isEmpty) {
                          return '상태를 선택해주세요';
                        }
                        return null;
                      },
                    ),
                    const SizedBox(height: 16),
                    const SizedBox(height: 24),

                    // 날짜 및 시간 섹션
                    _buildSectionTitle('날짜 및 시간'),

                    // 시작 날짜
                    Container(
                      decoration: BoxDecoration(
                        border: Border.all(color: Colors.green, width: 1.0),
                        borderRadius: BorderRadius.circular(4.0),
                      ),
                      margin: const EdgeInsets.symmetric(vertical: 8.0),
                      child: ListTile(
                        title: Row(
                          children: [
                            Expanded(
                              child: Text(
                                '시작 날짜 및 시간 *',
                                maxLines: 1,
                                overflow: TextOverflow.ellipsis,
                                style: const TextStyle(
                                  fontWeight: FontWeight.bold,
                                  color: Colors.blue,
                                ),
                              ),
                            ),
                            const SizedBox(width: 8),
                            const Icon(
                              Icons.check_circle,
                              color: Colors.green,
                              size: 16,
                            ),
                          ],
                        ),
                        subtitle: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Text(
                              DateFormat(
                                'yyyy년 MM월 dd일 HH:mm',
                              ).format(_startDate),
                              style: const TextStyle(
                                fontWeight: FontWeight.bold,
                              ),
                            ),
                            const SizedBox(height: 4),
                            Row(
                              children: [
                                const Icon(
                                  Icons.info_outline,
                                  size: 12,
                                  color: Colors.green,
                                ),
                                const SizedBox(width: 4),
                                Expanded(
                                  child: Text(
                                    '이벤트 시작 날짜와 시간을 설정해주세요 (필수)',
                                    maxLines: 1,
                                    overflow: TextOverflow.ellipsis,
                                    style: const TextStyle(
                                      fontSize: 12,
                                      fontStyle: FontStyle.italic,
                                      color: Colors.grey,
                                    ),
                                  ),
                                ),
                              ],
                            ),
                          ],
                        ),
                        leading: const Icon(Icons.event, color: Colors.blue),
                        trailing: const Icon(Icons.calendar_today),
                        onTap: () async {
                          final date = await showDatePicker(
                            context: context,
                            initialDate: _startDate,
                            firstDate: DateTime(2020),
                            lastDate: DateTime(2030),
                          );
                          if (date != null) {
                            if (!context.mounted) return;
                            final time = await showTimePicker(
                              context: context,
                              initialTime: TimeOfDay.fromDateTime(_startDate),
                            );
                            if (time != null && mounted) {
                              setState(() {
                                _startDate = DateTime(
                                  date.year,
                                  date.month,
                                  date.day,
                                  time.hour,
                                  time.minute,
                                );
                              });
                            }
                          }
                        },
                      ),
                    ),
                    const SizedBox(height: 8),

                    // 종료 날짜
                    ListTile(
                      title: const Text('종료 날짜 및 시간 (선택)'),
                      subtitle: _endDate != null
                          ? Text(
                              DateFormat(
                                'yyyy년 MM월 dd일 HH:mm',
                              ).format(_endDate!),
                            )
                          : const Text('설정되지 않음'),
                      trailing: Row(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          if (_endDate != null)
                            IconButton(
                              icon: const Icon(Icons.clear),
                              onPressed: () {
                                setState(() {
                                  _endDate = null;
                                });
                              },
                            ),
                          const Icon(Icons.calendar_today),
                        ],
                      ),
                      onTap: () async {
                        final date = await showDatePicker(
                          context: context,
                          initialDate:
                              _endDate ??
                              _startDate.add(const Duration(hours: 2)),
                          firstDate: DateTime(2020),
                          lastDate: DateTime(2030),
                        );

                        if (date != null) {
                          if (!context.mounted) return;
                          final time = await showTimePicker(
                            context: context,
                            initialTime: _endDate != null
                                ? TimeOfDay.fromDateTime(_endDate!)
                                : TimeOfDay.fromDateTime(
                                    _startDate.add(const Duration(hours: 2)),
                                  ),
                          );

                          if (time != null && mounted) {
                            setState(() {
                              _endDate = DateTime(
                                date.year,
                                date.month,
                                date.day,
                                time.hour,
                                time.minute,
                              );
                            });
                          }
                        }
                      },
                    ),
                    const SizedBox(height: 8),

                    // 등록 마감일
                    ListTile(
                      title: const Text('등록 마감일 (선택)'),
                      subtitle: _registrationDeadline != null
                          ? Text(
                              DateFormat(
                                'yyyy년 MM월 dd일 HH:mm',
                              ).format(_registrationDeadline!),
                            )
                          : const Text('설정되지 않음'),
                      trailing: Row(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          if (_registrationDeadline != null)
                            IconButton(
                              icon: const Icon(Icons.clear),
                              onPressed: () {
                                setState(() {
                                  _registrationDeadline = null;
                                });
                              },
                            ),
                          const Icon(Icons.calendar_today),
                        ],
                      ),
                      onTap: () async {
                        final date = await showDatePicker(
                          context: context,
                          initialDate:
                              _registrationDeadline ??
                              _startDate.subtract(const Duration(days: 1)),
                          firstDate: DateTime(2020),
                          lastDate: DateTime(2030),
                        );

                        if (date != null) {
                          if (!context.mounted) return;
                          final time = await showTimePicker(
                            context: context,
                            initialTime: _registrationDeadline != null
                                ? TimeOfDay.fromDateTime(_registrationDeadline!)
                                : TimeOfDay.fromDateTime(
                                    _startDate.subtract(
                                      const Duration(days: 1),
                                    ),
                                  ),
                          );

                          if (time != null && mounted) {
                            setState(() {
                              _registrationDeadline = DateTime(
                                date.year,
                                date.month,
                                date.day,
                                time.hour,
                                time.minute,
                              );
                            });
                          }
                        }
                      },
                    ),
                    const SizedBox(height: 24),

                    // 장소 및 참가자 섹션
                    _buildSectionTitle('장소 및 참가자'),

                    // 장소
                    TextFormField(
                      controller: _locationController,
                      decoration: const InputDecoration(
                        labelText: '장소',
                        hintText: '이벤트 장소를 입력하세요',
                      ),
                    ),
                    const SizedBox(height: 16),

                    // 최대 참가자 수
                    TextFormField(
                      controller: _maxParticipantsController,
                      decoration: const InputDecoration(
                        labelText: '최대 참가자 수',
                        hintText: '최대 참가자 수를 입력하세요',
                        suffixText: '명',
                      ),
                      keyboardType: TextInputType.number,
                      validator: (value) {
                        if (value != null && value.isNotEmpty) {
                          if (int.tryParse(value) == null) {
                            return '숫자를 입력해주세요';
                          }
                        }
                        return null;
                      },
                    ),
                    const SizedBox(height: 16),

                    // 게임 수
                    TextFormField(
                      controller: _gameCountController,
                      decoration: InputDecoration(
                        labelText: '게임 수',
                        hintText: '게임 수를 입력하세요',
                        suffixText: '게임',
                        helperText: '이벤트에서 진행할 게임 수를 입력하세요',
                        helperStyle: TextStyle(color: Colors.grey[600]),
                      ),
                      keyboardType: TextInputType.number,
                      inputFormatters: [FilteringTextInputFormatter.digitsOnly],
                      validator: (value) {
                        if (value != null && value.isNotEmpty) {
                          final numValue = int.tryParse(value);
                          if (numValue == null) {
                            return '유효한 숫자를 입력해주세요';
                          }
                          if (numValue <= 0) {
                            return '1 이상의 숫자를 입력해주세요';
                          }
                          if (numValue > 100) {
                            return '게임 수가 너무 많습니다 (100 이하)';
                          }
                        }
                        return null;
                      },
                      onChanged: (value) {
                        // 입력 중에도 화면 업데이트를 위해 setState 호출
                        setState(() {});
                      },
                    ),
                    // 게임 수가 유효한 경우 안내 메시지 표시
                    Builder(
                      builder: (context) {
                        if (_gameCountController.text.isNotEmpty &&
                            int.tryParse(_gameCountController.text) != null &&
                            int.parse(_gameCountController.text) > 0) {
                          return Padding(
                            padding: const EdgeInsets.only(
                              top: 4.0,
                              left: 12.0,
                            ),
                            child: Text(
                              '총 ${int.parse(_gameCountController.text)} 게임이 진행됩니다',
                              style: TextStyle(
                                color: Colors.green[700],
                                fontSize: 12,
                              ),
                            ),
                          );
                        } else {
                          return const SizedBox.shrink();
                        }
                      },
                    ),
                    const SizedBox(height: 16),

                    // 참가비
                    Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        // 숨겨진 실제 참가비 입력 필드 (데이터 저장용)
                        Offstage(
                          offstage: true,
                          child: TextFormField(
                            controller: _participantFeeController,
                            keyboardType: const TextInputType.numberWithOptions(
                              decimal: true,
                            ),
                          ),
                        ),

                        // 포맷된 참가비 표시 필드 (사용자 입력용)
                        TextFormField(
                          controller: _formattedFeeController,
                          decoration: InputDecoration(
                            labelText: '참가비',
                            hintText: '참가비를 입력하세요',
                            helperText: _getParticipantFeeHelperText(),
                            helperStyle: TextStyle(
                              color: _getParticipantFeeColor(),
                              fontStyle: _participantFeeController.text.isEmpty
                                  ? FontStyle.italic
                                  : FontStyle.normal,
                              fontWeight:
                                  _participantFeeController.text.isNotEmpty
                                  ? FontWeight.bold
                                  : FontWeight.normal,
                            ),
                            // 입력 상태에 따른 테두리 색상 변경
                            enabledBorder:
                                _participantFeeController.text.isEmpty
                                ? null
                                : OutlineInputBorder(
                                    borderSide: BorderSide(
                                      color: _getParticipantFeeColor(),
                                      width: 1.5,
                                    ),
                                  ),
                            suffixIcon: _formattedFeeController.text.isNotEmpty
                                ? IconButton(
                                    icon: const Icon(Icons.clear),
                                    onPressed: () {
                                      setState(() {
                                        _formattedFeeController.clear();
                                        _participantFeeController.clear();
                                      });
                                    },
                                    tooltip: '참가비 지우기',
                                  )
                                : null,
                          ),
                          keyboardType: const TextInputType.numberWithOptions(
                            decimal: false,
                          ),
                          inputFormatters: [
                            FilteringTextInputFormatter.digitsOnly,
                          ],
                          validator: (value) {
                            if (value != null && value.isNotEmpty) {
                              final numValue = double.tryParse(
                                _participantFeeController.text,
                              );
                              if (numValue == null) {
                                return '유효한 금액을 입력해주세요';
                              }
                              if (numValue < 0) {
                                return '0 이상의 금액을 입력해주세요';
                              }
                              if (numValue > 1000000) {
                                return '금액이 너무 큽니다 (최대 1,000,000원)';
                              }
                            }
                            return null;
                          },
                          onChanged: (value) {
                            if (value.isNotEmpty) {
                              // 콤마 제거 후 숫자만 추출
                              final plainNumber = value.replaceAll(
                                RegExp(r'[^0-9]'),
                                '',
                              );
                              final numericValue = int.tryParse(plainNumber);

                              if (numericValue != null) {
                                // 원본 값 저장
                                _participantFeeController.text = numericValue
                                    .toString();

                                // 포맷된 값 표시 (커서 위치 보존)
                                final cursorPosition = _formattedFeeController
                                    .selection
                                    .baseOffset;
                                final oldText = _formattedFeeController.text;
                                final newText = _currencyFormat.format(
                                  numericValue,
                                );

                                // 커서 위치 계산 로직 개선
                                int newCursorPosition;
                                if (oldText.isEmpty) {
                                  newCursorPosition = newText.length;
                                } else {
                                  // 이전 텍스트와 새 텍스트의 길이 차이 계산
                                  final lengthDiff =
                                      newText.length - oldText.length;
                                  newCursorPosition =
                                      (cursorPosition + lengthDiff).clamp(
                                        0,
                                        newText.length,
                                      );
                                }

                                _formattedFeeController.value =
                                    TextEditingValue(
                                      text: newText,
                                      selection: TextSelection.collapsed(
                                        offset: newCursorPosition,
                                      ),
                                    );
                              }
                            } else {
                              _participantFeeController.clear();
                            }

                            // UI 업데이트를 위해 setState 호출
                            setState(() {});
                          },
                        ),

                        // 참가비 입력 시 안내 메시지
                        if (_formattedFeeController.text.isNotEmpty)
                          Padding(
                            padding: const EdgeInsets.only(
                              top: 4.0,
                              left: 12.0,
                            ),
                            child: Row(
                              children: [
                                Icon(
                                  _getParticipantFeeIcon(),
                                  size: 16,
                                  color: _getParticipantFeeColor(),
                                ),
                                const SizedBox(width: 8),
                                Text(
                                  _getParticipantFeeStatusText(),
                                  style: TextStyle(
                                    color: _getParticipantFeeColor(),
                                    fontSize: 12,
                                    fontWeight: FontWeight.bold,
                                  ),
                                ),
                              ],
                            ),
                          ),
                      ],
                    ),
                    const SizedBox(height: 4),

                    const SizedBox(height: 24),

                    // 공개 접근 섹션
                    _buildSectionTitle('공개 접근'),

                    // 공개 URL 해시
                    Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Row(
                          children: [
                            Expanded(
                              child: TextFormField(
                                controller: _publicHashController,
                                decoration: InputDecoration(
                                  labelText: '공개 URL 해시',
                                  hintText: '공개 URL 해시를 입력하세요',
                                  helperText: '이벤트를 공개적으로 공유하기 위한 고유 식별자입니다',
                                ),
                                readOnly: true,
                              ),
                            ),
                            Tooltip(
                              message: _publicHashController.text.isEmpty
                                  ? '새 해시 생성'
                                  : '해시 재생성',
                              child: IconButton(
                                icon: const Icon(Icons.refresh),
                                color: Colors.blue,
                                onPressed: _generatePublicHash,
                              ),
                            ),
                          ],
                        ),
                        const SizedBox(height: 8),
                        if (_publicHashController.text.isNotEmpty)
                          Container(
                            padding: const EdgeInsets.all(12),
                            decoration: BoxDecoration(
                              color: Colors.blue.withValues(alpha: 0.1),
                              borderRadius: BorderRadius.circular(8),
                              border: Border.all(
                                color: Colors.blue.withValues(alpha: 0.3),
                              ),
                            ),
                            child: Column(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: [
                                const Text(
                                  '공개 URL:',
                                  style: TextStyle(fontWeight: FontWeight.bold),
                                ),
                                const SizedBox(height: 4),
                                Row(
                                  children: [
                                    Expanded(
                                      child: Text(
                                        UrlUtils.getEventPublicUrl(
                                          _publicHashController.text,
                                        ),
                                        style: TextStyle(
                                          color: Colors.blue[700],
                                        ),
                                      ),
                                    ),
                                    IconButton(
                                      icon: const Icon(
                                        Icons.copy,
                                        color: Colors.blue,
                                      ),
                                      onPressed: () {
                                        final url = UrlUtils.getEventPublicUrl(
                                          _publicHashController.text,
                                        );
                                        UrlUtils.copyUrlToClipboard(
                                          context,
                                          url,
                                        );
                                      },
                                      tooltip: 'URL 복사',
                                    ),
                                  ],
                                ),
                                const SizedBox(height: 4),
                                const Text(
                                  '이 URL을 공유하면 누구나 이벤트를 볼 수 있습니다.',
                                  style: TextStyle(
                                    fontSize: 12,
                                    fontStyle: FontStyle.italic,
                                  ),
                                ),
                              ],
                            ),
                          ),
                      ],
                    ),

                    const SizedBox(height: 16),

                    // 접근 비밀번호
                    Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        TextFormField(
                          key: const ValueKey('access_password_field'),
                          controller: _accessPasswordController,
                          decoration: InputDecoration(
                            labelText: '접근 비밀번호 (선택)',
                            hintText: '접근 비밀번호를 입력하세요',
                            helperText: _getPasswordHelperText(),
                            helperStyle: TextStyle(
                              color: _getPasswordStrengthColor(),
                              fontWeight:
                                  _accessPasswordController.text.isNotEmpty
                                  ? FontWeight.bold
                                  : FontWeight.normal,
                            ),
                            prefixIcon: const Icon(Icons.lock_outline),
                            suffixIcon: Row(
                              mainAxisSize: MainAxisSize.min,
                              children: [
                                // 비밀번호 표시/숨김 토글 버튼
                                IconButton(
                                  icon: Icon(
                                    _obscurePassword
                                        ? Icons.visibility_off
                                        : Icons.visibility,
                                    color: _obscurePassword
                                        ? Colors.grey
                                        : Colors.blue,
                                  ),
                                  onPressed: () {
                                    setState(() {
                                      _obscurePassword = !_obscurePassword;
                                    });
                                  },
                                  tooltip: _obscurePassword
                                      ? '비밀번호 표시'
                                      : '비밀번호 숨김',
                                ),
                                // 도움말 버튼
                                IconButton(
                                  icon: const Icon(Icons.help_outline),
                                  onPressed: () {
                                    ScaffoldMessenger.of(context).showSnackBar(
                                      const SnackBar(
                                        content: Text(
                                          '비밀번호를 설정하면 공개 URL로 접근하는 사용자도 비밀번호를 입력해야 합니다',
                                        ),
                                        duration: Duration(seconds: 5),
                                      ),
                                    );
                                  },
                                  tooltip: '비밀번호 도움말',
                                ),
                              ],
                            ),
                            // 비밀번호 강도에 따른 테두리 색상 변경
                            enabledBorder:
                                _accessPasswordController.text.isEmpty
                                ? null
                                : OutlineInputBorder(
                                    borderSide: BorderSide(
                                      color: _getPasswordStrengthColor(),
                                      width: 1.5,
                                    ),
                                  ),
                          ),
                          obscureText: _obscurePassword,
                          onChanged: (value) {
                            // 비밀번호 입력 시 실시간으로 UI 업데이트
                            setState(() {});
                          },
                          validator: (value) {
                            if (value != null &&
                                value.isNotEmpty &&
                                value.length < 4) {
                              return '비밀번호는 최소 4자 이상이어야 합니다';
                            }
                            return null;
                          },
                        ),
                        if (_accessPasswordController.text.isNotEmpty)
                          Padding(
                            padding: const EdgeInsets.only(
                              top: 8.0,
                              left: 12.0,
                            ),
                            child: Row(
                              children: [
                                Icon(
                                  Icons.lock,
                                  size: 16,
                                  color: _getPasswordStrengthColor(),
                                ),
                                const SizedBox(width: 8),
                                Text(
                                  '비밀번호 보호가 활성화되었습니다',
                                  style: TextStyle(
                                    color: _getPasswordStrengthColor(),
                                    fontSize: 12,
                                    fontWeight: FontWeight.bold,
                                  ),
                                ),
                              ],
                            ),
                          ),
                      ],
                    ),
                    const SizedBox(height: 32),

                    // 저장 버튼
                    SizedBox(
                      width: double.infinity,
                      child: ElevatedButton(
                        key: const ValueKey('save_event_button'),
                        onPressed: _saveEvent,
                        style: ElevatedButton.styleFrom(
                          padding: const EdgeInsets.symmetric(vertical: 16),
                        ),
                        child: Text(
                          widget.event == null ? '이벤트 생성' : '이벤트 수정',
                          style: const TextStyle(fontSize: 16),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
    );

    // 테스트 환경에서 애니메이션 비활성화
    if (TestUtils.isInTest) {
      return TestUtils.disableAnimations(child: scaffold);
    }
    return scaffold;
  }

  // 섹션 제목 위젯
  Widget _buildSectionTitle(String title) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          title,
          style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
        ),
        const Divider(),
        const SizedBox(height: 8),
      ],
    );
  }

  // 비밀번호 강도에 따른 색상 반환
  Color _getPasswordStrengthColor() {
    final password = _accessPasswordController.text;

    if (password.isEmpty) {
      return Colors.grey[600]!;
    }

    if (password.length < 4) {
      return Colors.red[700]!;
    } else if (password.length < 6) {
      return Colors.orange[700]!;
    } else if (password.length < 8) {
      return Colors.yellow[700]!;
    } else {
      // 8자 이상이고 숫자와 특수문자를 포함하는지 확인
      bool hasNumber = password.contains(RegExp(r'[0-9]'));
      bool hasSpecialChar = password.contains(
        RegExp(r'[!@#$%^&*(),.?":{}|<>]'),
      );

      if (hasNumber && hasSpecialChar) {
        return Colors.green[700]!;
      } else {
        return Colors.blue[700]!;
      }
    }
  }

  // 비밀번호 강도에 따른 도움말 텍스트 반환
  String _getPasswordHelperText() {
    final password = _accessPasswordController.text;

    if (password.isEmpty) {
      return '설정 시 이벤트 접근에 비밀번호가 필요합니다';
    }

    if (password.length < 4) {
      return '비밀번호가 너무 짧습니다 (최소 4자)';
    } else if (password.length < 6) {
      return '비밀번호 강도: 약함';
    } else if (password.length < 8) {
      return '비밀번호 강도: 보통';
    } else {
      // 8자 이상이고 숫자와 특수문자를 포함하는지 확인
      bool hasNumber = password.contains(RegExp(r'[0-9]'));
      bool hasSpecialChar = password.contains(
        RegExp(r'[!@#$%^&*(),.?":{}|<>]'),
      );

      if (hasNumber && hasSpecialChar) {
        return '비밀번호 강도: 매우 강함';
      } else {
        return '비밀번호 강도: 강함';
      }
    }
  }

  // 참가비 포맷팅 업데이트
  void _updateFormattedFee(String value) {
    if (value.isEmpty) {
      _formattedFeeController.clear();
      return;
    }

    final numericValue = double.tryParse(value);
    if (numericValue != null) {
      // 현재 커서 위치 저장
      final currentCursor = _formattedFeeController.selection.baseOffset;
      final oldText = _formattedFeeController.text;
      final newText = _currencyFormat.format(numericValue);

      // 커서 위치 계산 로직 개선
      int newCursorPosition = currentCursor;
      if (oldText.isNotEmpty && currentCursor > 0) {
        // 이전 텍스트와 새 텍스트의 길이 차이 계산
        final lengthDiff = newText.length - oldText.length;
        newCursorPosition = (currentCursor + lengthDiff).clamp(
          0,
          newText.length,
        );
      } else {
        newCursorPosition = newText.length;
      }

      _formattedFeeController.value = TextEditingValue(
        text: newText,
        selection: TextSelection.collapsed(offset: newCursorPosition),
      );
    }
  }

  // 참가비 변경 리스너
  void _onParticipantFeeChanged() {
    final value = _participantFeeController.text;
    if (value.isEmpty) {
      if (_formattedFeeController.text.isNotEmpty) {
        setState(() {
          _formattedFeeController.clear();
        });
      }
    } else {
      // 값이 있으면 포맷팅 업데이트
      _updateFormattedFee(value);
    }
  }

  // 참가비 입력 상태에 따른 도움말 텍스트 반환
  String _getParticipantFeeHelperText() {
    if (_participantFeeController.text.isEmpty) {
      return '통화 형식으로 자동 변환됩니다 (빈값이면 미표기)';
    }

    final fee = double.tryParse(_participantFeeController.text);
    if (fee == null) {
      return '유효한 금액을 입력해주세요';
    }

    if (fee < 0) {
      return '참가비는 0원 이상이어야 합니다';
    } else if (fee == 0) {
      return '참가비: 0원 (무료)';
    } else if (fee > 1000000) {
      return '최대 금액은 1,000,000원입니다';
    } else {
      return '참가비: ${_currencyFormat.format(fee)}원';
    }
  }

  // 참가비 입력 상태에 따른 색상 반환
  Color _getParticipantFeeColor() {
    if (_participantFeeController.text.isEmpty) {
      return Colors.grey[600]!;
    }

    final fee = double.tryParse(_participantFeeController.text);
    if (fee == null) {
      return Colors.red[700]!;
    }

    if (fee < 0) {
      return Colors.red[700]!;
    } else if (fee > 1000000) {
      return Colors.orange[700]!;
    } else {
      return Colors.green[700]!;
    }
  }

  // 참가비 입력 상태에 따른 아이콘 반환
  IconData _getParticipantFeeIcon() {
    if (_participantFeeController.text.isEmpty) {
      return Icons.info_outline;
    }

    final fee = double.tryParse(_participantFeeController.text);
    if (fee == null || fee < 0) {
      return Icons.error_outline;
    } else if (fee > 1000000) {
      return Icons.warning;
    } else {
      return Icons.check_circle;
    }
  }

  // 참가비 입력 상태에 따른 상태 텍스트 반환
  String _getParticipantFeeStatusText() {
    if (_participantFeeController.text.isEmpty) {
      return '참가비가 설정되지 않았습니다';
    }

    final fee = double.tryParse(_participantFeeController.text);
    if (fee == null) {
      return '유효하지 않은 금액입니다';
    }

    if (fee < 0) {
      return '참가비는 0원 이상이어야 합니다';
    } else if (fee > 1000000) {
      return '최대 금액을 초과했습니다';
    } else if (fee == 0) {
      return '참가비: 0원 (무료)';
    } else {
      return '참가비가 설정되었습니다';
    }
  }
}
