import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:location/location.dart';
import 'package:latlong2/latlong.dart';
import 'package:lba/res/colors.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:lba/gen/assets.gen.dart';
import 'package:lba/widgets/app_snackbar.dart';
import 'dart:math' as math;

class LocationRadiusScreen extends StatefulWidget {
  const LocationRadiusScreen({super.key});

  @override
  State<LocationRadiusScreen> createState() => _LocationRadiusScreenState();
}

class _LocationRadiusScreenState extends State<LocationRadiusScreen>
    with TickerProviderStateMixin {
  final MapController _mapController = MapController();
  LatLng _currentCenter = const LatLng(25.1972, 55.2744); // Default: Dubai
  double _radiusInKm = 1.0;
  bool _isCustomRadius = false;
  bool _isLoadingLocation = true;
  bool _mapLoadError = false;
  int _currentTileProvider = 0; 
  
  Location location = Location();
  late bool _serviceEnabled;
  late PermissionStatus _permissionGranted;
  late LocationData _locationData;

  late AnimationController _animationController;
  late List<Animation<double>> _animations;

  final List<Map<String, dynamic>> _tileProviders = [
    {
      'name': 'Stamen Terrain',
      'lightUrl':
          'https://stamen-tiles-{s}.a.ssl.fastly.net/terrain/{z}/{x}/{y}{r}.png',
      'darkUrl':
          'https://stamen-tiles-{s}.a.ssl.fastly.net/toner/{z}/{x}/{y}{r}.png',
      'subdomains': ['a', 'b', 'c', 'd'],
    },
    {
      'name': 'CartoDB',
      'lightUrl':
          'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png',
      'darkUrl':
          'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png',
      'subdomains': ['a', 'b', 'c', 'd'],
    },
    {
      'name': 'Google Maps',
      'lightUrl': 'https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}',
      'darkUrl': 'https://mt1.google.com/vt/lyrs=y&x={x}&y={y}&z={z}',
      'subdomains': ['mt0', 'mt1', 'mt2', 'mt3'],
    },
  ];

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

    _animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 1200),
    );

    _animations = List.generate(6, (index) {
      final double startTime = (index / 6) * 0.5;
      final double endTime = (startTime + 0.6).clamp(0.0, 1.0);
      return Tween<double>(begin: 0.0, end: 1.0).animate(
        CurvedAnimation(
          parent: _animationController,
          curve: Interval(startTime, endTime, curve: Curves.easeOutCubic),
        ),
      );
    });

    _currentTileProvider =
        _currentTileProvider.clamp(0, _tileProviders.length - 1);

    _determinePosition();
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  Future<void> _determinePosition() async {
    setState(() => _isLoadingLocation = true);

    try {
      _serviceEnabled = await location.serviceEnabled();
      if (!_serviceEnabled) {
        _serviceEnabled = await location.requestService();
        if (!_serviceEnabled) {
          _showLocationMessage(
              'Location services are disabled. Please enable it in settings.',
              type: SnackBarType.warning);
          setState(() => _isLoadingLocation = false);
          _animationController.forward();
          return;
        }
      }

      _permissionGranted = await location.hasPermission();
      if (_permissionGranted == PermissionStatus.denied) {
        _permissionGranted = await location.requestPermission();
        if (_permissionGranted != PermissionStatus.granted) {
          _showLocationMessage('Location permissions are denied.',
              type: SnackBarType.error);
          setState(() => _isLoadingLocation = false);
          _animationController.forward();
          return;
        }
      }

      _locationData = await location.getLocation();

      setState(() {
        _currentCenter =
            LatLng(_locationData.latitude!, _locationData.longitude!);
        _isLoadingLocation = false;
      });

      _showLocationMessage('Location found successfully!',
          type: SnackBarType.success);

      _mapController.move(_currentCenter, 14.0);
    } catch (e) {
      _showLocationMessage('Unable to get your location. Using default location.',
          type: SnackBarType.info);
      setState(() {
        _isLoadingLocation = false;
      });
    } finally {
      if (mounted) {
        _animationController.forward();
      }
    }
  }

  void _showLocationMessage(String message,
      {SnackBarType type = SnackBarType.error}) {
    if (mounted) {
      AppSnackBar.show(
        context: context,
        message: message,
        type: type,
        duration: const Duration(seconds: 3),
      );
    }
  }

  Widget _buildAnimatedWidget(Widget child, int index) {
    return FadeTransition(
      opacity: _animations[index],
      child: SlideTransition(
        position: Tween<Offset>(
          begin: const Offset(0.0, 0.5),
          end: Offset.zero,
        ).animate(_animations[index]),
        child: child,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: AppColors.scaffoldBackground,
      appBar: AppBar(
        title: Text(
          "Choose a location to see what's available",
          style: TextStyle(
              color: AppColors.textPrimary,
              fontWeight: FontWeight.normal,
              fontSize: 15),
        ),
        backgroundColor: AppColors.surface,
        elevation: 0,
        leading: IconButton(
          icon: SvgPicture.asset(
            Assets.icons.arrowLeft.path,
            color: AppColors.textPrimary,
          ),
          onPressed: () => Navigator.of(context).pop(),
        ),
      ),
      body: Stack(
        children: [
          _mapLoadError
              ? _buildMapErrorFallback()
              : Container(
                  padding: const EdgeInsets.only(bottom: 240),
                  child: FlutterMap(
                    mapController: _mapController,
                    options: MapOptions(
                      initialCenter: _currentCenter,
                      initialZoom: 14.0,
                      onPositionChanged: (position, hasGesture) {
                        if (hasGesture) {
                          setState(() {
                            _currentCenter = position.center;
                          });
                        }
                      },
                    ),
                    children: [
                      TileLayer(
                        urlTemplate:
                            'https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png',
                        userAgentPackageName: 'com.example.lba',
                        subdomains: const ['a', 'b', 'c', 'd'],
                        additionalOptions: const {
                          'attribution':
                              '© CARTO © OpenStreetMap contributors',
                        },
                      ),
                      CircleLayer(
                        circles: [
                          CircleMarker(
                            point: _currentCenter,
                            radius: _radiusInKm * 1000,
                            useRadiusInMeter: true,
                            color: _isCustomRadius
                                ? AppColors.primary.withOpacity(0.15)
                                : AppColors.offerTimer.withOpacity(0.15),
                            borderColor: Colors.transparent,
                            borderStrokeWidth: 0,
                          ),
                        ],
                      ),
                      MarkerLayer(
                        markers: [
                          Marker(
                            width: _calculateCirclePixelSize(),
                            height: _calculateCirclePixelSize(),
                            point: _currentCenter,
                            child: CustomPaint(
                              painter: DashedCirclePainter(
                                color: _isCustomRadius
                                    ? AppColors.primary
                                    : AppColors.offerTimer,
                                strokeWidth: 3.0,
                                dashLength: 9.0,
                                gapLength: 5.0,
                              ),
                            ),
                          ),
                        ],
                      ),
                    ],
                  ),
                ),
          if (_isLoadingLocation)
            Container(
              color: AppColors.scaffoldBackground.withOpacity(0.8),
              child: Center(
                child: CircularProgressIndicator(
                  valueColor: AlwaysStoppedAnimation<Color>(AppColors.primary),
                ),
              ),
            ),
          _buildControlsPanel(),
        ],
      ),
    );
  }

  Widget _buildMapErrorFallback() {
    return Container(
      width: double.infinity,
      height: double.infinity,
      decoration: BoxDecoration(
        color: AppColors.cardBackground,
        border: Border.all(color: AppColors.divider),
      ),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        children: [
          const SizedBox(height: 40),
          Container(
            width: 120,
            height: 120,
            decoration: BoxDecoration(
              shape: BoxShape.circle,
              border: Border.all(
                color:
                    _isCustomRadius ? AppColors.primary : AppColors.offerTimer,
                width: 4,
              ),
              color: (_isCustomRadius
                      ? AppColors.primary
                      : AppColors.offerTimer)
                  .withOpacity(0.08),
              boxShadow: [
                BoxShadow(
                  color: AppColors.shadowColor,
                  blurRadius: 12,
                  offset: const Offset(0, 4),
                ),
              ],
            ),
            child: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Container(
                    padding: const EdgeInsets.all(10),
                    decoration: BoxDecoration(
                      color: _isCustomRadius
                          ? AppColors.primary
                          : AppColors.offerTimer,
                      shape: BoxShape.circle,
                      boxShadow: [
                        BoxShadow(
                          color: AppColors.shadowColor,
                          blurRadius: 8,
                          offset: const Offset(0, 2),
                        ),
                      ],
                    ),
                    child: Icon(
                      Icons.location_on,
                      color: AppColors.surface,
                      size: 24,
                    ),
                  ),
                  const SizedBox(height: 8),
                  Text(
                    '${_radiusInKm.toStringAsFixed(1)} km',
                    style: TextStyle(
                      fontSize: 14,
                      fontWeight: FontWeight.bold,
                      color: AppColors.textPrimary,
                    ),
                  ),
                  Text(
                    'radius',
                    style: TextStyle(
                      fontSize: 10,
                      color: AppColors.textSecondary,
                    ),
                  ),
                ],
              ),
            ),
          ),
          const Spacer(),
        ],
      ),
    );
  }

  Widget _buildControlsPanel() {
    return Positioned(
      bottom: 0,
      left: 0,
      right: 0,
      child: SlideTransition(
        position: Tween<Offset>(
          begin: const Offset(0, 1),
          end: Offset.zero,
        ).animate(CurvedAnimation(
          parent: _animationController,
          curve: Curves.easeOutCubic,
        )),
        child: Container(
          padding: const EdgeInsets.all(16.0),
          decoration: BoxDecoration(
            color: AppColors.surface,
            borderRadius: const BorderRadius.vertical(top: Radius.circular(20)),
            boxShadow: [
              BoxShadow(
                color: AppColors.shadowColor,
                blurRadius: 10,
                offset: const Offset(0, -2),
              ),
            ],
          ),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              _buildAnimatedWidget(
                Text(
                  "Preset Radius Cards",
                  style: TextStyle(
                    fontWeight: FontWeight.bold,
                    fontSize: 16,
                    color: AppColors.nearbyPopuphint,
                  ),
                ),
                0,
              ),
              const SizedBox(height: 8),
              if (_mapLoadError)
                _buildAnimatedWidget(
                  Container(
                    padding: const EdgeInsets.all(8),
                    decoration: BoxDecoration(
                      color: AppColors.errorColor.withOpacity(0.1),
                      borderRadius: BorderRadius.circular(8),
                      border: Border.all(
                        color: AppColors.errorColor.withOpacity(0.3),
                      ),
                    ),
                    child: Row(
                      children: [
                        Icon(
                          Icons.warning_amber_rounded,
                          color: AppColors.errorColor,
                          size: 16,
                        ),
                        const SizedBox(width: 8),
                        Expanded(
                          child: Text(
                            'Map tiles blocked. Using fallback display.',
                            style: TextStyle(
                              color: AppColors.errorColor,
                              fontSize: 12,
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                  1,
                ),
              const SizedBox(height: 12),
              _buildAnimatedWidget(
                Row(
                  children: [
                    _buildRadiusToggleChip(
                        "Nearby (1 km)", !_isCustomRadius, () {
                      setState(() {
                        _isCustomRadius = false;
                        _radiusInKm = 1.0;
                      });
                    }),
                    const SizedBox(width: 8),
                    _buildRadiusToggleChip("Custom Radius", _isCustomRadius,
                        () {
                      setState(() {
                        _isCustomRadius = true;
                        if (_radiusInKm == 1.0) _radiusInKm = 5.0;
                      });
                    }),
                  ],
                ),
                2,
              ),
              const SizedBox(height: 16),
              _buildAnimatedWidget(
                Row(
                  children: [
                    Expanded(
                      child: Slider(
                        value: _radiusInKm,
                        min: 1.0,
                        max: 25.0,
                        divisions: 24,
                        activeColor: _isCustomRadius
                            ? AppColors.primary
                            : AppColors.divider,
                        inactiveColor: AppColors.divider.withOpacity(0.5),
                        onChanged: _isCustomRadius
                            ? (value) {
                                setState(() {
                                  _radiusInKm = value;
                                });
                              }
                            : null,
                      ),
                    ),
                    const SizedBox(width: 16),
                    Text(
                      "${_radiusInKm.toStringAsFixed(1)} km",
                      style: TextStyle(
                        fontWeight: FontWeight.bold,
                        color: AppColors.textPrimary,
                      ),
                    ),
                  ],
                ),
                3,
              ),
              _buildAnimatedWidget(
                Center(
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: [
                      TextButton.icon(
                        onPressed: _determinePosition,
                        icon: SvgPicture.asset(
                          Assets.icons.currentLoc.path,
                          color: AppColors.primary,
                        ),
                        label: Text(
                          "Use my current location",
                          style: TextStyle(
                              color: AppColors.primary,
                              fontWeight: FontWeight.bold),
                        ),
                      ),
                    ],
                  ),
                ),
                4,
              ),
              const SizedBox(height: 8),
              _buildAnimatedWidget(
                SizedBox(
                  width: double.infinity,
                  height: 50,
                  child: ElevatedButton(
                    onPressed: () {
                      Navigator.of(context).pop();
                    },
                    style: ElevatedButton.styleFrom(
                      backgroundColor: AppColors.confirmButton,
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(27),
                      ),
                    ),
                    child: Text(
                      'Apply',
                      style: TextStyle(
                        color: AppColors.surface,
                        fontSize: 18,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                  ),
                ),
                5,
              ),
              const SizedBox(
                height: 30,
              )
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildRadiusToggleChip(
      String label, bool isSelected, VoidCallback onTap) {
    return ChoiceChip(
      label: Text(label),
      selected: isSelected,
      onSelected: (selected) {
        if (selected) onTap();
      },
      selectedColor: isSelected && !_isCustomRadius
          ? AppColors.primary
          : AppColors.primary,
      backgroundColor: AppColors.cardBackground,
      labelStyle: TextStyle(
        color: isSelected ? AppColors.nearbyPopup : AppColors.textSecondary,
        fontWeight: FontWeight.bold,
      ),
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(20),
        side: BorderSide(
          color: isSelected ? Colors.transparent : AppColors.divider,
        ),
      ),
      showCheckmark: false,
    );
  }

  double _calculateCirclePixelSize() {
    try {
      final double currentZoom = _mapController.camera.zoom;
      final double pixelsPerMeter = 256 *
          math.pow(2, currentZoom) /
          (2 *
              math.pi *
              6378137 *
              math.cos(_currentCenter.latitude * math.pi / 180));
      final double radiusInMeters = _radiusInKm * 1000;
      final double radiusInPixels = radiusInMeters * pixelsPerMeter;
      return radiusInPixels * 2;
    } catch (e) {
      const double pixelsPerKmAtZoom14 = 100.0;
      return _radiusInKm * pixelsPerKmAtZoom14 * 2;
    }
  }
}

class DashedCirclePainter extends CustomPainter {
  final Color color;
  final double strokeWidth;
  final double dashLength;
  final double gapLength;

  DashedCirclePainter({
    required this.color,
    required this.strokeWidth,
    required this.dashLength,
    required this.gapLength,
  });

  @override
  void paint(Canvas canvas, Size size) {
    final Paint paint = Paint()
      ..color = color
      ..strokeWidth = strokeWidth
      ..style = PaintingStyle.stroke;

    final double radius = (size.width - strokeWidth) / 2;
    final Offset center = Offset(size.width / 2, size.height / 2);

    final double circumference = 2 * math.pi * radius;
    final double totalDashLength = dashLength + gapLength;
    final int dashCount = (circumference / totalDashLength).floor();

    for (int i = 0; i < dashCount; i++) {
      final double startAngle = (i * totalDashLength / radius);
      final double sweepAngle = dashLength / radius;

      canvas.drawArc(
        Rect.fromCircle(center: center, radius: radius),
        startAngle,
        sweepAngle,
        false,
        paint,
      );
    }
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}