import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:latlong2/latlong.dart';

import '../../core/constants/auth_constants.dart';
import '../../core/models/colonia.dart';
import '../../core/theme/app_theme.dart';
import '../../core/widgets/app_widgets.dart';
import '../home/colonias_data.dart';
import 'colonias_provider.dart';

const Map<String, String> _cpToColonia = {
  '38000': 'Zona Centro',
  '38060': 'Las Arboledas',
  '38027': 'San Juanico',
  '38037': 'Los Olivos',
  '38090': 'Rancho Seco',
  '38080': 'Las Insurgentes',
  '38086': 'Trojes',
};

class AddAddressPage extends ConsumerStatefulWidget {
  const AddAddressPage({super.key});

  @override
  ConsumerState<AddAddressPage> createState() => _AddAddressPageState();
}

class _AddAddressPageState extends ConsumerState<AddAddressPage> {
  final _mapController = MapController();
  final _cpCtrl = TextEditingController();
  final _calleCtrl = TextEditingController();
  final _labelCtrl = TextEditingController(text: 'Mi Casa');

  Colonia? _selectedColonia;
  LatLng? _selectedLocation;
  bool _loading = false;

  @override
  void dispose() {
    _mapController.dispose();
    _cpCtrl.dispose();
    _calleCtrl.dispose();
    _labelCtrl.dispose();
    super.dispose();
  }

  Future<void> _fetchStreetName(LatLng latlng) async {
    setState(() => _selectedLocation = latlng);
    try {
      final dio = Dio();
      final response = await dio.get(
        'https://nominatim.openstreetmap.org/reverse',
        queryParameters: {
          'lat': latlng.latitude,
          'lon': latlng.longitude,
          'format': 'json',
          'addressdetails': 1,
        },
        options: kIsWeb
            ? null
            : Options(headers: {'User-Agent': 'com.onlineshack.recolecta'}),
      );
      if (response.data?['address'] != null) {
        final addr = response.data['address'] as Map;
        final road = addr['road'] ?? addr['pedestrian'] ?? addr['street'] ?? '';
        final num = addr['house_number'] ?? '';
        if ((road as String).isNotEmpty) {
          setState(() => _calleCtrl.text = '$road $num'.trim());
        }
      }
    } catch (e) {
      debugPrint('Nominatim error: $e');
    }
  }

  void _validarCP(String cp, List<Colonia> colonias) {
    if (cp.length != 5) {
      if (_selectedColonia != null) {
        setState(() {
          _selectedColonia = null;
          _selectedLocation = null;
          _calleCtrl.clear();
        });
      }
      return;
    }

    final nombre = _cpToColonia[cp];
    if (nombre == null) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text('Código postal fuera de nuestra zona de servicio.'),
          backgroundColor: AppTheme.danger,
          behavior: SnackBarBehavior.floating,
        ),
      );
      setState(() {
        _selectedColonia = null;
        _selectedLocation = null;
      });
      return;
    }

    final backendC = colonias
        .where((c) => c.nombre.toLowerCase() == nombre.toLowerCase())
        .firstOrNull;
    if (backendC == null) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text('Esta colonia aún no tiene horarios configurados.'),
          backgroundColor: AppTheme.danger,
          behavior: SnackBarBehavior.floating,
        ),
      );
      setState(() {
        _selectedColonia = null;
        _selectedLocation = null;
      });
      return;
    }

    setState(() {
      _selectedColonia = backendC;
      _selectedLocation = kColoniasCoordinates[nombre];
    });
    FocusScope.of(context).unfocus();
  }

  Future<void> _guardar() async {
    if (_calleCtrl.text.trim().isEmpty || _selectedColonia == null) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text('Ingresa tu calle y selecciona una colonia'),
          behavior: SnackBarBehavior.floating,
        ),
      );
      return;
    }

    setState(() => _loading = true);
    try {
      const storage = FlutterSecureStorage();
      final token = await storage.read(key: authTokenStorageKey) ?? '';

      final dio = Dio(
        BaseOptions(
          baseUrl: const String.fromEnvironment(
            'API_BASE_URL',
            defaultValue: 'http://localhost:8000',
          ),
          headers: {'Authorization': 'Bearer $token'},
        ),
      );

      final body = <String, dynamic>{
        'label': _labelCtrl.text.trim().isEmpty
            ? 'Mi Casa'
            : _labelCtrl.text.trim(),
        'calle': _calleCtrl.text.trim(),
        'colonia': _selectedColonia!.nombre,
      };
      await dio.post('/addresses', data: body);

      if (mounted) Navigator.pop(context, true);
    } on DioException catch (e) {
      if (mounted) {
        final msg = (e.response?.data is Map)
            ? e.response!.data['detail'] ?? 'Error al guardar'
            : 'Error al guardar la dirección';
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text(msg),
            backgroundColor: AppTheme.danger,
            behavior: SnackBarBehavior.floating,
          ),
        );
      }
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('Error: $e'),
            backgroundColor: AppTheme.danger,
            behavior: SnackBarBehavior.floating,
          ),
        );
      }
    } finally {
      if (mounted) setState(() => _loading = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    final coloniasList = ref.watch(coloniasProvider).value ?? [];

    final baseCenter = _selectedColonia != null
        ? kColoniaCenter(_selectedColonia!.nombre)
        : const LatLng(20.5222, -100.8123);
    final mapCenter = _selectedLocation ?? baseCenter;

    final bounds = _selectedColonia != null
        ? LatLngBounds(
            LatLng(baseCenter.latitude - 0.01, baseCenter.longitude - 0.01),
            LatLng(baseCenter.latitude + 0.01, baseCenter.longitude + 0.01),
          )
        : null;

    return Scaffold(
      backgroundColor: AppTheme.background,
      body: CustomScrollView(
        slivers: [
          SliverToBoxAdapter(child: _buildPageHeader(context)),
          SliverPadding(
            padding: const EdgeInsets.fromLTRB(24, 24, 24, 0),
            sliver: SliverList(
              delegate: SliverChildListDelegate([
                AppFormCard(
                  icon: Icons.home_outlined,
                  title: 'Dirección de tu casa',
                  child: Column(
                    children: [
                      AppFormField(
                        label: 'Etiqueta',
                        hint: 'Ej. Mi Casa, Trabajo',
                        controller: _labelCtrl,
                      ),
                      const SizedBox(height: 14),
                      AppFormField(
                        label: 'Código Postal',
                        hint: 'Ej. 38000',
                        controller: _cpCtrl,
                        keyboardType: TextInputType.number,
                        onChanged: (v) => _validarCP(v, coloniasList),
                      ),
                      if (_selectedColonia != null) ...[
                        const SizedBox(height: 14),
                        Container(
                          padding: const EdgeInsets.all(14),
                          decoration: BoxDecoration(
                            color: AppTheme.primaryLight.withValues(alpha: 0.5),
                            borderRadius:
                                BorderRadius.circular(AppTheme.radiusSm),
                            border: Border.all(color: AppTheme.primaryMid),
                          ),
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Row(
                                children: [
                                  const Icon(
                                    Icons.check_circle_outline,
                                    color: AppTheme.primary,
                                    size: 18,
                                  ),
                                  const SizedBox(width: 8),
                                  Expanded(
                                    child: Text(
                                      'Colonia: ${_selectedColonia!.nombre}',
                                      style: const TextStyle(
                                        fontWeight: FontWeight.w600,
                                        color: AppTheme.primaryDark,
                                      ),
                                    ),
                                  ),
                                ],
                              ),
                              if (_selectedColonia!.horarioEstimado !=
                                  null) ...[
                                const SizedBox(height: 8),
                                Text(
                                  'Horario ${_selectedColonia!.turno?.toLowerCase() ?? ''}',
                                  style: const TextStyle(
                                    fontSize: 13,
                                    color: AppTheme.textPrimary,
                                  ),
                                ),
                                Text(
                                  _selectedColonia!.horarioEstimado!,
                                  style: const TextStyle(
                                    fontSize: 14,
                                    fontWeight: FontWeight.bold,
                                    color: AppTheme.textPrimary,
                                  ),
                                ),
                              ],
                            ],
                          ),
                        ),
                        const SizedBox(height: 14),
                        AppFormField(
                          label: 'Calle y número',
                          hint: 'Av. Insurgentes 245',
                          controller: _calleCtrl,
                        ),
                        const SizedBox(height: 16),
                        const Text(
                          'Toca el mapa para ubicar tu casa exacta:',
                          style: TextStyle(
                            fontSize: 12,
                            fontWeight: FontWeight.w500,
                            color: AppTheme.textSecondary,
                          ),
                        ),
                        const SizedBox(height: 8),
                        Container(
                          height: 220,
                          decoration: BoxDecoration(
                            borderRadius:
                                BorderRadius.circular(AppTheme.radiusMd),
                            border: Border.all(color: AppTheme.border),
                            boxShadow: AppTheme.softShadow,
                          ),
                          clipBehavior: Clip.hardEdge,
                          child: FlutterMap(
                            mapController: _mapController,
                            options: MapOptions(
                              initialCenter: mapCenter,
                              initialZoom: 15.0,
                              cameraConstraint: bounds != null
                                  ? CameraConstraint.containCenter(
                                      bounds: bounds)
                                  : const CameraConstraint.unconstrained(),
                              onTap: (_, latlng) => _fetchStreetName(latlng),
                            ),
                            children: [
                              TileLayer(
                                urlTemplate:
                                    'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
                                userAgentPackageName:
                                    'com.onlineshack.recolecta',
                              ),
                              if (_selectedLocation != null)
                                MarkerLayer(
                                  markers: [
                                    Marker(
                                      point: _selectedLocation!,
                                      width: 40,
                                      height: 40,
                                      child: const Icon(
                                        Icons.location_on,
                                        color: AppTheme.danger,
                                        size: 40,
                                      ),
                                    ),
                                  ],
                                ),
                            ],
                          ),
                        ),
                      ] else ...[
                        const SizedBox(height: 24),
                        const Center(
                          child: Text(
                            'Ingresa un código postal con servicio\npara asignar tu colonia.',
                            textAlign: TextAlign.center,
                            style: TextStyle(
                              color: AppTheme.textSecondary,
                              fontSize: 13,
                            ),
                          ),
                        ),
                      ],
                    ],
                  ),
                ),
                const SizedBox(height: 32),
              ]),
            ),
          ),
        ],
      ),
      bottomNavigationBar: _buildSaveButton(),
    );
  }

  Widget _buildPageHeader(BuildContext context) {
    return Container(
      padding: EdgeInsets.fromLTRB(
        20,
        MediaQuery.of(context).padding.top + 12,
        20,
        24,
      ),
      decoration: const BoxDecoration(
        gradient: LinearGradient(
          colors: [Color(0xFF4A0E26), Color(0xFF9B1B4A)],
          begin: Alignment.topLeft,
          end: Alignment.bottomRight,
        ),
        borderRadius: BorderRadius.only(
          bottomLeft: Radius.circular(28),
          bottomRight: Radius.circular(28),
        ),
      ),
      child: Row(
        children: [
          GestureDetector(
            onTap: () => Navigator.of(context).pop(),
            child: Container(
              width: 36,
              height: 36,
              decoration: BoxDecoration(
                color: Colors.white.withValues(alpha: 0.15),
                borderRadius: BorderRadius.circular(10),
              ),
              child: const Icon(
                Icons.arrow_back,
                color: Colors.white,
                size: 20,
              ),
            ),
          ),
          const SizedBox(width: 14),
          const Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  'Agregar dirección',
                  style: TextStyle(
                    fontSize: 20,
                    fontWeight: FontWeight.w700,
                    color: Colors.white,
                  ),
                ),
                SizedBox(height: 2),
                Text(
                  'Registra tu domicilio de recolección',
                  style: TextStyle(fontSize: 13, color: Colors.white70),
                ),
              ],
            ),
          ),
          Container(
            width: 44,
            height: 44,
            decoration: BoxDecoration(
              color: Colors.white.withValues(alpha: 0.15),
              borderRadius: BorderRadius.circular(12),
            ),
            child: const Icon(
              Icons.add_home_outlined,
              color: Colors.white,
              size: 22,
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildSaveButton() {
    return SafeArea(
      child: Padding(
        padding: const EdgeInsets.fromLTRB(24, 12, 24, 16),
        child: SizedBox(
          width: double.infinity,
          child: ElevatedButton(
            onPressed: _loading ? null : _guardar,
            child: AnimatedSwitcher(
              duration: const Duration(milliseconds: 200),
              child: _loading
                  ? const SizedBox(
                      key: ValueKey('loading'),
                      width: 20,
                      height: 20,
                      child: CircularProgressIndicator(
                        strokeWidth: 2,
                        color: Colors.white,
                      ),
                    )
                  : const Row(
                      key: ValueKey('text'),
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        Icon(Icons.check, size: 18),
                        SizedBox(width: 8),
                        Text('Guardar dirección'),
                      ],
                    ),
            ),
          ),
        ),
      ),
    );
  }
}
