import 'dart:async';

import 'package:flutter/material.dart';
import 'package:geocoding/geocoding.dart';
import 'package:maplibre_gl/maplibre_gl.dart';

import '../../core/location/location_access_service.dart';
import '../../core/maps/open_free_map.dart';
import '../../core/theme/app_theme.dart';
import 'tenant_location_data.dart';

Future<TenantLocationData?> showLocationPickerSheet(
  BuildContext context, {
  TenantLocationData? initialLocation,
  String title = 'Konum Seç',
}) {
  return showModalBottomSheet<TenantLocationData>(
    context: context,
    isScrollControlled: true,
    backgroundColor: Colors.transparent,
    builder: (_) => _LocationPickerSheet(
      initialLocation: initialLocation,
      title: title,
    ),
  );
}

class _LocationPickerSheet extends StatefulWidget {
  const _LocationPickerSheet({
    required this.initialLocation,
    required this.title,
  });

  final TenantLocationData? initialLocation;
  final String title;

  @override
  State<_LocationPickerSheet> createState() => _LocationPickerSheetState();
}

class _LocationPickerSheetState extends State<_LocationPickerSheet> {
  static const _fallback = LatLng(41.0082, 28.9784);

  MapLibreMapController? _mapController;
  TenantLocationData? _selection;
  bool _styleReady = false;
  bool _locating = false;
  bool _resolvingAddress = false;
  String? _error;

  LatLng get _selectedPoint => LatLng(
        _selection?.latitude ??
            widget.initialLocation?.latitude ??
            _fallback.latitude,
        _selection?.longitude ??
            widget.initialLocation?.longitude ??
            _fallback.longitude,
      );

  @override
  void initState() {
    super.initState();
    _selection = widget.initialLocation;
    if (_selection?.hasCoordinates == true &&
        ((_selection?.address ?? '').trim().isEmpty)) {
      unawaited(_updateAddress(_selectedPoint));
    }
  }

  Future<void> _pickCurrentLocation() async {
    setState(() {
      _locating = true;
      _error = null;
    });
    try {
      final position = await LocationAccessService.getCurrentPosition();
      final point = LatLng(position.latitude, position.longitude);
      await _moveCamera(point, 14);
      setState(() {
        _selection = (_selection ?? const TenantLocationData()).copyWith(
          latitude: point.latitude,
          longitude: point.longitude,
        );
      });
      await _refreshSelectionMarker();
      await _updateAddress(point);
    } catch (e) {
      setState(() => _error = e.toString());
    } finally {
      if (mounted) setState(() => _locating = false);
    }
  }

  Future<void> _moveCamera(LatLng point, double zoom) async {
    final controller = _mapController;
    if (controller == null) return;
    await controller.animateCamera(
      CameraUpdate.newLatLngZoom(point, zoom),
    );
  }

  Future<void> _refreshSelectionMarker() async {
    final controller = _mapController;
    if (controller == null ||
        !_styleReady ||
        _selection?.hasCoordinates != true) {
      return;
    }

    await controller.clearCircles();
    await controller.addCircle(
      CircleOptions(
        geometry: _selectedPoint,
        circleRadius: 8,
        circleColor: '#4F46E5',
        circleStrokeWidth: 3,
        circleStrokeColor: '#FFFFFF',
      ),
    );
  }

  Future<void> _selectPoint(LatLng point, {double zoom = 15}) async {
    setState(() {
      _selection = (_selection ?? const TenantLocationData()).copyWith(
        latitude: point.latitude,
        longitude: point.longitude,
      );
    });
    await _refreshSelectionMarker();
    await _moveCamera(point, zoom);
    await _updateAddress(point);
  }

  Future<void> _updateAddress(LatLng point) async {
    setState(() {
      _resolvingAddress = true;
      _error = null;
    });
    try {
      final placemarks = await placemarkFromCoordinates(
        point.latitude,
        point.longitude,
      );
      final placemark = placemarks.isNotEmpty ? placemarks.first : null;
      final addressParts = [
        placemark?.street,
        placemark?.subLocality,
        placemark?.locality,
      ].where((part) => (part ?? '').trim().isNotEmpty).cast<String>().toList();

      setState(() {
        _selection = (_selection ?? const TenantLocationData()).copyWith(
          latitude: point.latitude,
          longitude: point.longitude,
          address: addressParts.join(', '),
          district: placemark?.subAdministrativeArea?.trim().isNotEmpty == true
              ? placemark!.subAdministrativeArea!.trim()
              : placemark?.subLocality?.trim(),
          city: placemark?.administrativeArea?.trim().isNotEmpty == true
              ? placemark!.administrativeArea!.trim()
              : placemark?.locality?.trim(),
        );
      });
    } catch (_) {
      setState(() {
        _selection = (_selection ?? const TenantLocationData()).copyWith(
          latitude: point.latitude,
          longitude: point.longitude,
        );
      });
    } finally {
      if (mounted) setState(() => _resolvingAddress = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    final bottom = MediaQuery.paddingOf(context).bottom;

    return Container(
      height: MediaQuery.sizeOf(context).height * 0.88,
      decoration: const BoxDecoration(
        color: AppColors.surface,
        borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
      ),
      child: Column(
        children: [
          const SizedBox(height: 12),
          Container(
            width: 42,
            height: 4,
            decoration: BoxDecoration(
              color: AppColors.border,
              borderRadius: BorderRadius.circular(2),
            ),
          ),
          Padding(
            padding: const EdgeInsets.fromLTRB(16, 16, 16, 12),
            child: Row(
              children: [
                Expanded(
                  child: Text(
                    widget.title,
                    style: const TextStyle(
                      fontSize: 18,
                      fontWeight: FontWeight.w700,
                      color: AppColors.textPrimary,
                    ),
                  ),
                ),
                TextButton.icon(
                  onPressed: _locating ? null : _pickCurrentLocation,
                  icon: _locating
                      ? const SizedBox(
                          width: 16,
                          height: 16,
                          child: CircularProgressIndicator(strokeWidth: 2),
                        )
                      : const Icon(Icons.my_location_rounded, size: 18),
                  label: const Text('Konumum'),
                ),
              ],
            ),
          ),
          Expanded(
            child: Padding(
              padding: const EdgeInsets.symmetric(horizontal: 16),
              child: ClipRRect(
                borderRadius: BorderRadius.circular(16),
                child: Stack(
                  children: [
                    MapLibreMap(
                      styleString: OpenFreeMap.libertyStyle,
                      initialCameraPosition: CameraPosition(
                        target: _selectedPoint,
                        zoom: 13,
                      ),
                      onMapCreated: (controller) => _mapController = controller,
                      onStyleLoadedCallback: () async {
                        _styleReady = true;
                        await _refreshSelectionMarker();
                      },
                      onMapClick: (_, point) async {
                        await _selectPoint(point);
                      },
                      compassEnabled: false,
                      tiltGesturesEnabled: false,
                      rotateGesturesEnabled: false,
                      myLocationEnabled: false,
                      myLocationTrackingMode: MyLocationTrackingMode.none,
                    ),
                    Positioned(
                      top: 12,
                      left: 12,
                      right: 12,
                      child: Container(
                        padding: const EdgeInsets.symmetric(
                          horizontal: 12,
                          vertical: 10,
                        ),
                        decoration: BoxDecoration(
                          color: Colors.white.withValues(alpha: 0.92),
                          borderRadius: BorderRadius.circular(12),
                        ),
                        child: const Text(
                          'Haritada bir noktaya dokunarak konum seçin.',
                          style: TextStyle(
                            fontSize: 12,
                            color: AppColors.textSecondary,
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
          Padding(
            padding: const EdgeInsets.fromLTRB(16, 16, 16, 8),
            child: Container(
              width: double.infinity,
              padding: const EdgeInsets.all(14),
              decoration: BoxDecoration(
                color: AppColors.background,
                borderRadius: BorderRadius.circular(16),
                border: Border.all(color: AppColors.border),
              ),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Row(
                    children: [
                      const Icon(Icons.place_outlined,
                          size: 18, color: AppColors.accent),
                      const SizedBox(width: 8),
                      const Text(
                        'Seçilen Konum',
                        style: TextStyle(
                          fontWeight: FontWeight.w600,
                          color: AppColors.textPrimary,
                        ),
                      ),
                      if (_resolvingAddress) ...[
                        const SizedBox(width: 10),
                        const SizedBox(
                          width: 14,
                          height: 14,
                          child: CircularProgressIndicator(strokeWidth: 2),
                        ),
                      ],
                    ],
                  ),
                  const SizedBox(height: 10),
                  Text(
                    _selection?.fullLabel.isNotEmpty == true
                        ? _selection!.fullLabel
                        : 'Haritada bir nokta seçin.',
                    style: const TextStyle(color: AppColors.textSecondary),
                  ),
                  const SizedBox(height: 10),
                  Text(
                    'Koordinatlar: '
                    '${_selectedPoint.latitude.toStringAsFixed(6)}, '
                    '${_selectedPoint.longitude.toStringAsFixed(6)}',
                    style: const TextStyle(
                      fontSize: 12,
                      color: AppColors.textMuted,
                    ),
                  ),
                  if (_error != null) ...[
                    const SizedBox(height: 10),
                    Text(
                      _error!,
                      style: const TextStyle(color: AppColors.cancelled),
                    ),
                  ],
                ],
              ),
            ),
          ),
          Padding(
            padding: EdgeInsets.fromLTRB(16, 8, 16, bottom + 12),
            child: FilledButton(
              onPressed: _selection?.hasCoordinates == true
                  ? () => Navigator.of(context).pop(_selection)
                  : null,
              style: FilledButton.styleFrom(
                minimumSize: const Size(double.infinity, 50),
              ),
              child: const Text('Bu Konumu Kullan'),
            ),
          ),
        ],
      ),
    );
  }
}
