import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../../../../core/constants/app_colors.dart';
import '../../../../core/constants/app_typography.dart';
import '../../../../domain/entities/restaurant.dart';
import '../../../view_models/add_restaurant_view_model.dart';
import 'add_restaurant_search_tab.dart';
import 'add_restaurant_url_tab.dart';
import 'fetched_restaurant_json_view.dart';

enum AddRestaurantDialogMode { naverLink, search }

/// 네이버 링크/검색 기반 맛집 추가 다이얼로그
class AddRestaurantDialog extends ConsumerStatefulWidget {
  final AddRestaurantDialogMode mode;

  const AddRestaurantDialog({super.key, required this.mode});

  @override
  ConsumerState<AddRestaurantDialog> createState() =>
      _AddRestaurantDialogState();
}

class _AddRestaurantDialogState extends ConsumerState<AddRestaurantDialog> {
  final _formKey = GlobalKey<FormState>();

  late final TextEditingController _nameController;
  late final TextEditingController _categoryController;
  late final TextEditingController _subCategoryController;
  late final TextEditingController _descriptionController;
  late final TextEditingController _phoneController;
  late final TextEditingController _roadAddressController;
  late final TextEditingController _jibunAddressController;
  late final TextEditingController _latitudeController;
  late final TextEditingController _longitudeController;
  late final TextEditingController _naverUrlController;
  late final TextEditingController _searchQueryController;

  @override
  void initState() {
    super.initState();
    _nameController = TextEditingController();
    _categoryController = TextEditingController();
    _subCategoryController = TextEditingController();
    _descriptionController = TextEditingController();
    _phoneController = TextEditingController();
    _roadAddressController = TextEditingController();
    _jibunAddressController = TextEditingController();
    _latitudeController = TextEditingController();
    _longitudeController = TextEditingController();
    _naverUrlController = TextEditingController();
    _searchQueryController = TextEditingController();

    WidgetsBinding.instance.addPostFrameCallback((_) {
      ref.read(addRestaurantViewModelProvider.notifier).reset();
    });
  }

  @override
  void dispose() {
    _nameController.dispose();
    _categoryController.dispose();
    _subCategoryController.dispose();
    _descriptionController.dispose();
    _phoneController.dispose();
    _roadAddressController.dispose();
    _jibunAddressController.dispose();
    _latitudeController.dispose();
    _longitudeController.dispose();
    _naverUrlController.dispose();
    _searchQueryController.dispose();
    super.dispose();
  }

  void _onFormDataChanged(String _) {
    final viewModel = ref.read(addRestaurantViewModelProvider.notifier);
    final formData = RestaurantFormData.fromControllers(
      nameController: _nameController,
      categoryController: _categoryController,
      subCategoryController: _subCategoryController,
      descriptionController: _descriptionController,
      phoneController: _phoneController,
      roadAddressController: _roadAddressController,
      jibunAddressController: _jibunAddressController,
      latitudeController: _latitudeController,
      longitudeController: _longitudeController,
      naverUrlController: _naverUrlController,
    );
    viewModel.updateFormData(formData);
  }

  Future<void> _fetchFromNaverUrl() async {
    final viewModel = ref.read(addRestaurantViewModelProvider.notifier);
    await viewModel.fetchFromNaverUrl(_naverUrlController.text);
    final state = ref.read(addRestaurantViewModelProvider);
    if (state.fetchedRestaurantData != null) {
      _updateFormControllers(state.formData);
    }
  }

  Future<void> _performSearch() async {
    final query = _searchQueryController.text.trim();
    await ref
        .read(addRestaurantViewModelProvider.notifier)
        .searchRestaurants(query);
  }

  void _selectSearchResult(Restaurant restaurant) {
    final viewModel = ref.read(addRestaurantViewModelProvider.notifier);
    viewModel.selectSearchResult(restaurant);
    final state = ref.read(addRestaurantViewModelProvider);
    _updateFormControllers(state.formData);
    _naverUrlController.text = restaurant.naverUrl ?? _naverUrlController.text;
  }

  void _updateFormControllers(RestaurantFormData formData) {
    _nameController.text = formData.name;
    _categoryController.text = formData.category;
    _subCategoryController.text = formData.subCategory;
    _descriptionController.text = formData.description;
    _phoneController.text = formData.phoneNumber;
    _roadAddressController.text = formData.roadAddress;
    _jibunAddressController.text = formData.jibunAddress;
    _latitudeController.text = formData.latitude;
    _longitudeController.text = formData.longitude;
    _naverUrlController.text = formData.naverUrl;
  }

  Future<void> _saveRestaurant() async {
    final state = ref.read(addRestaurantViewModelProvider);
    if (state.fetchedRestaurantData == null) {
      return;
    }

    if (_formKey.currentState?.validate() != true) {
      return;
    }

    final viewModel = ref.read(addRestaurantViewModelProvider.notifier);
    final success = await viewModel.saveRestaurant();

    if (!mounted) return;

    if (success) {
      Navigator.of(context).pop();
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Row(
            children: const [
              Icon(Icons.check_circle, color: Colors.white, size: 20),
              SizedBox(width: 8),
              Text('맛집이 추가되었습니다'),
            ],
          ),
          backgroundColor: Colors.green,
        ),
      );
    } else {
      final errorMessage =
          ref.read(addRestaurantViewModelProvider).errorMessage ??
          '맛집 저장에 실패했습니다.';
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(errorMessage),
          backgroundColor: Colors.redAccent,
        ),
      );
    }
  }

  String get _title {
    switch (widget.mode) {
      case AddRestaurantDialogMode.naverLink:
        return '네이버 지도 링크로 추가';
      case AddRestaurantDialogMode.search:
        return '상호명으로 검색';
    }
  }

  @override
  Widget build(BuildContext context) {
    final isDark = Theme.of(context).brightness == Brightness.dark;
    final state = ref.watch(addRestaurantViewModelProvider);

    return Dialog(
      backgroundColor: isDark ? AppColors.darkSurface : AppColors.lightSurface,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
      child: ConstrainedBox(
        constraints: const BoxConstraints(maxWidth: 420),
        child: SingleChildScrollView(
          padding: const EdgeInsets.all(24),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              Text(
                _title,
                style: AppTypography.heading1(isDark),
                textAlign: TextAlign.center,
              ),
              const SizedBox(height: 16),
              if (widget.mode == AddRestaurantDialogMode.naverLink)
                AddRestaurantUrlTab(
                  urlController: _naverUrlController,
                  isLoading: state.isLoading,
                  errorMessage: state.errorMessage,
                  onFetchPressed: _fetchFromNaverUrl,
                )
              else
                AddRestaurantSearchTab(
                  queryController: _searchQueryController,
                  isSearching: state.isSearching,
                  results: state.searchResults,
                  selectedRestaurant: state.fetchedRestaurantData,
                  onResultSelected: _selectSearchResult,
                  onSearch: _performSearch,
                  errorMessage: state.errorMessage,
                ),
              const SizedBox(height: 24),
              if (state.fetchedRestaurantData != null) ...[
                Form(
                  key: _formKey,
                  child: FetchedRestaurantJsonView(
                    isDark: isDark,
                    nameController: _nameController,
                    categoryController: _categoryController,
                    subCategoryController: _subCategoryController,
                    descriptionController: _descriptionController,
                    phoneController: _phoneController,
                    roadAddressController: _roadAddressController,
                    jibunAddressController: _jibunAddressController,
                    latitudeController: _latitudeController,
                    longitudeController: _longitudeController,
                    naverUrlController: _naverUrlController,
                    onFieldChanged: _onFormDataChanged,
                  ),
                ),
                const SizedBox(height: 24),
              ],
              Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: [
                  TextButton(
                    onPressed: state.isLoading
                        ? null
                        : () => Navigator.of(context).pop(),
                    child: const Text('취소'),
                  ),
                  const SizedBox(width: 8),
                  ElevatedButton(
                    onPressed:
                        state.isLoading || state.fetchedRestaurantData == null
                        ? null
                        : _saveRestaurant,
                    child: state.isLoading
                        ? const SizedBox(
                            width: 18,
                            height: 18,
                            child: CircularProgressIndicator(
                              strokeWidth: 2,
                              valueColor: AlwaysStoppedAnimation<Color>(
                                Colors.white,
                              ),
                            ),
                          )
                        : const Text('저장'),
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}
