import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
import 'package:geocoding/geocoding.dart';
import 'dart:math' as math;
import 'package:url_launcher/url_launcher.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

class LocationResult {
  final String address;
  final double latitude;
  final double longitude;

  LocationResult({
    required this.address,
    required this.latitude,
    required this.longitude,
  });
}

class LocationPickerDialog extends StatefulWidget {
  final String? initialAddress;
  final double? initialLatitude;
  final double? initialLongitude;
  final bool fullscreen;

  const LocationPickerDialog({
    super.key,
    this.initialAddress,
    this.initialLatitude,
    this.initialLongitude,
    this.fullscreen = false,
  });

  @override
  State<LocationPickerDialog> createState() => _LocationPickerDialogState();
}

class _LocationPickerDialogState extends State<LocationPickerDialog> {
  late LatLng _selectedLatLng;
  String _selectedAddress = '';
  bool _isLoading = false;
  double _rotation = 0.0;
  final TextEditingController _searchController = TextEditingController();
  final MapController _mapController = MapController();

  @override
  void initState() {
    super.initState();
    _selectedLatLng = LatLng(
      widget.initialLatitude ?? -7.797068,
      widget.initialLongitude ?? 110.370529,
    );
    _selectedAddress = widget.initialAddress ?? '';
    _getAddressFromLatLng(_selectedLatLng.latitude, _selectedLatLng.longitude);
  }

  Future<void> _getAddressFromLatLng(double lat, double lng) async {
    setState(() => _isLoading = true);
    try {
      List<Placemark> placemarks = await placemarkFromCoordinates(lat, lng);
      if (placemarks.isNotEmpty) {
        Placemark place = placemarks[0];
        String address =
            '${place.street}, ${place.subLocality}, ${place.locality}, ${place.subAdministrativeArea}, ${place.administrativeArea} ${place.postalCode}, ${place.country}';
        address = address.replaceAll(RegExp(r', ,'), ',');
        address = address.replaceAll(RegExp(r',,'), ',');
        address = address.replaceAll(RegExp(r'^, '), '');
        setState(() {
          _selectedAddress = address;
        });
      }
    } catch (e) {
      setState(() {
        _selectedAddress = '';
      });
    }
    setState(() => _isLoading = false);
  }

  Future<void> _findLocation(String query) async {
    if (query.isEmpty) return;
    // Cek apakah input berupa koordinat lat,lng
    final coordReg = RegExp(r'^\s*(-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)\s*\$');
    final match = coordReg.firstMatch(query);
    if (match != null) {
      final lat = double.tryParse(match.group(1)!);
      final lng = double.tryParse(match.group(2)!);
      if (lat != null && lng != null) {
        final latLng = LatLng(lat, lng);
        setState(() {
          _selectedLatLng = latLng;
        });
        _mapController.move(latLng, 15.0);
        await _getAddressFromLatLng(lat, lng);
        return;
      }
    }
    setState(() => _isLoading = true);
    try {
      List<Location> locations = await locationFromAddress(query);
      if (locations.isNotEmpty) {
        final loc = locations.first;
        final latLng = LatLng(loc.latitude, loc.longitude);
        setState(() {
          _selectedLatLng = latLng;
        });
        _mapController.move(latLng, 15.0);
        await _getAddressFromLatLng(latLng.latitude, latLng.longitude);
      } else {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(SnackBar(content: Text('Lokasi tidak ditemukan!')));
      }
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Terjadi error saat mencari lokasi')),
      );
    }
    setState(() => _isLoading = false);
  }

  void _resetNorth() {
    setState(() {
      _rotation = 0.0;
    });
    _mapController.rotate(0.0);
  }

  Future<String?> _getMapillaryThumbnail(double lat, double lng) async {
    const accessToken =
        'MLY|24193737726928907|ec8688dd90eee0a7bd6231d281010d5c';
    final url =
        'https://graph.mapillary.com/images?access_token=$accessToken&fields=id,thumb_256_url&closeto=$lng,$lat&limit=1';
    final response = await http.get(Uri.parse(url));
    if (response.statusCode == 200) {
      final data = json.decode(response.body);
      if (data['data'] != null && data['data'].isNotEmpty) {
        return data['data'][0]['thumb_256_url'] as String?;
      }
    }
    return null;
  }

  Future<String> _getMapillaryViewerUrl(double lat, double lng) async {
    const accessToken =
        'MLY|24193737726928907|ec8688dd90eee0a7bd6231d281010d5c';
    final url =
        'https://graph.mapillary.com/images?access_token=$accessToken&fields=id&closeto=$lng,$lat&limit=1';
    final response = await http.get(Uri.parse(url));
    if (response.statusCode == 200) {
      final data = json.decode(response.body);
      if (data['data'] != null && data['data'].isNotEmpty) {
        final id = data['data'][0]['id'];
        return 'https://www.mapillary.com/app/?pKey=$id&focus=photo';
      }
    }
    return 'https://www.mapillary.com/app/?lat=$lat&lng=$lng&z=17.5';
  }

  @override
  Widget build(BuildContext context) {
    final isFullscreen = widget.fullscreen;
    final dialogContent = Column(
      children: [
        // Header
        Container(
          padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
          decoration: BoxDecoration(
            color: Theme.of(context).primaryColor,
            borderRadius:
                isFullscreen
                    ? null
                    : const BorderRadius.only(
                      topLeft: Radius.circular(16),
                      topRight: Radius.circular(16),
                    ),
          ),
          child: Row(
            children: [
              const Expanded(
                child: Text(
                  'Pilih Lokasi Lahan',
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 18,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ),
              if (!isFullscreen)
                IconButton(
                  icon: const Icon(Icons.open_in_full, color: Colors.white),
                  onPressed: () async {
                    final result = await Navigator.of(context).push(
                      MaterialPageRoute(
                        builder:
                            (ctx) => LocationPickerDialog(
                              initialAddress: _selectedAddress,
                              initialLatitude: _selectedLatLng.latitude,
                              initialLongitude: _selectedLatLng.longitude,
                              fullscreen: true,
                            ),
                      ),
                    );
                    if (result is LocationResult) {
                      Navigator.of(context).pop(result);
                    }
                  },
                ),
              IconButton(
                icon: Icon(
                  isFullscreen ? Icons.close : Icons.close,
                  color: Colors.white,
                ),
                onPressed: () => Navigator.of(context).pop(),
              ),
            ],
          ),
        ),
        // Search Bar
        Padding(
          padding: const EdgeInsets.all(16),
          child: Row(
            children: [
              Expanded(
                child: TextField(
                  controller: _searchController,
                  decoration: InputDecoration(
                    hintText: 'Cari lokasi…',
                    border: OutlineInputBorder(
                      borderRadius: BorderRadius.circular(8),
                    ),
                    contentPadding: const EdgeInsets.symmetric(
                      horizontal: 16,
                      vertical: 12,
                    ),
                  ),
                  onSubmitted: (value) => _findLocation(value),
                ),
              ),
              const SizedBox(width: 8),
              ElevatedButton(
                onPressed: () => _findLocation(_searchController.text),
                style: ElevatedButton.styleFrom(
                  backgroundColor: Theme.of(context).primaryColor,
                  foregroundColor: Colors.white,
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(8),
                  ),
                  padding: const EdgeInsets.symmetric(
                    vertical: 14,
                    horizontal: 16,
                  ),
                ),
                child: const Icon(Icons.search),
              ),
            ],
          ),
        ),
        // Map
        Expanded(
          child: Stack(
            children: [
              FlutterMap(
                mapController: _mapController,
                options: MapOptions(
                  center: _selectedLatLng,
                  zoom: 15.0,
                  interactiveFlags:
                      InteractiveFlag.all, // Aktifkan semua gesture
                  onTap: (tapPosition, point) async {
                    setState(() {
                      _selectedLatLng = point;
                    });
                    await _getAddressFromLatLng(
                      point.latitude,
                      point.longitude,
                    );
                  },
                ),
                children: [
                  TileLayer(
                    urlTemplate:
                        'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
                    userAgentPackageName: 'com.tanismart.tugas_akhir_supabase',
                  ),
                  MarkerLayer(
                    markers: [
                      Marker(
                        width: 40.0,
                        height: 40.0,
                        point: _selectedLatLng,
                        child: Icon(
                          Icons.location_on,
                          color: Colors.red,
                          size: 40,
                        ),
                      ),
                    ],
                  ),
                ],
              ),
              FutureBuilder<String?>(
                future: _getMapillaryThumbnail(
                  _selectedLatLng.latitude,
                  _selectedLatLng.longitude,
                ),
                builder: (context, snapshot) {
                  if (snapshot.connectionState == ConnectionState.waiting) {
                    return Positioned(
                      bottom: 16,
                      left: 16,
                      child: Container(
                        width: 120,
                        height: 70,
                        color: Colors.grey[300],
                        child: const Center(
                          child: CircularProgressIndicator(strokeWidth: 2),
                        ),
                      ),
                    );
                  }
                  if (snapshot.hasData && snapshot.data != null) {
                    final thumbUrl = snapshot.data!;
                    return Positioned(
                      bottom: 16,
                      left: 16,
                      child: GestureDetector(
                        onTap: () async {
                          final url = await _getMapillaryViewerUrl(
                            _selectedLatLng.latitude,
                            _selectedLatLng.longitude,
                          );
                          if (await canLaunch(url)) {
                            await launch(url);
                          }
                        },
                        child: ClipRRect(
                          borderRadius: BorderRadius.circular(8),
                          child: Image.network(
                            thumbUrl,
                            width: 120,
                            height: 70,
                            fit: BoxFit.cover,
                            errorBuilder:
                                (context, error, stack) => Container(
                                  color: Colors.grey[300],
                                  width: 120,
                                  height: 70,
                                  child: Icon(Icons.image_not_supported),
                                ),
                          ),
                        ),
                      ),
                    );
                  }
                  return SizedBox.shrink();
                },
              ),
              // Koordinat & Kompas di kanan atas
              Positioned(
                top: 12,
                right: 12,
                child: Container(
                  padding: const EdgeInsets.symmetric(
                    horizontal: 12,
                    vertical: 6,
                  ),
                  decoration: BoxDecoration(
                    color: Colors.white.withOpacity(0.85),
                    borderRadius: BorderRadius.circular(8),
                    boxShadow: [
                      BoxShadow(
                        color: Colors.black.withOpacity(0.1),
                        blurRadius: 4,
                      ),
                    ],
                  ),
                  child: Row(
                    children: [
                      Text(
                        '${_selectedLatLng.latitude.toStringAsFixed(6)}, ${_selectedLatLng.longitude.toStringAsFixed(6)}',
                        style: const TextStyle(
                          fontSize: 13,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                      const SizedBox(width: 8),
                      // Kompas
                      GestureDetector(
                        onTap: _resetNorth,
                        child: const Icon(
                          Icons.explore,
                          color: Colors.blue,
                          size: 24,
                        ),
                      ),
                    ],
                  ),
                ),
              ),
              if (_isLoading)
                const Positioned(
                  top: 0,
                  left: 0,
                  right: 0,
                  child: LinearProgressIndicator(),
                ),
            ],
          ),
        ),
        // Selected Location
        Container(
          padding: const EdgeInsets.all(16),
          decoration: BoxDecoration(
            color: Colors.white,
            boxShadow: [
              BoxShadow(
                color: Colors.black.withOpacity(0.1),
                blurRadius: 4,
                offset: const Offset(0, -2),
              ),
            ],
          ),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              const Text(
                'Lokasi Terpilih:',
                style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
              ),
              const SizedBox(height: 8),
              Text(
                _selectedAddress.isNotEmpty
                    ? _selectedAddress
                    : 'Belum ada lokasi terpilih',
                style: TextStyle(color: Colors.grey[700], fontSize: 14),
              ),
              const SizedBox(height: 8),
              Text(
                'Koordinat: ${_selectedLatLng.latitude.toStringAsFixed(6)}, ${_selectedLatLng.longitude.toStringAsFixed(6)}',
                style: TextStyle(color: Colors.grey[700], fontSize: 12),
              ),
              const SizedBox(height: 16),
              Row(
                children: [
                  Expanded(
                    child: ElevatedButton(
                      onPressed: () => Navigator.of(context).pop(),
                      style: ElevatedButton.styleFrom(
                        backgroundColor: Colors.grey[200],
                        foregroundColor: Colors.black,
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(8),
                        ),
                        padding: const EdgeInsets.symmetric(vertical: 12),
                      ),
                      child: const Text('Batal'),
                    ),
                  ),
                  const SizedBox(width: 16),
                  Expanded(
                    child: ElevatedButton(
                      onPressed: () {
                        Navigator.of(context).pop(
                          LocationResult(
                            address: _selectedAddress,
                            latitude: _selectedLatLng.latitude,
                            longitude: _selectedLatLng.longitude,
                          ),
                        );
                      },
                      style: ElevatedButton.styleFrom(
                        backgroundColor: Theme.of(context).primaryColor,
                        foregroundColor: Colors.white,
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(8),
                        ),
                        padding: const EdgeInsets.symmetric(vertical: 12),
                      ),
                      child: const Text('Pilih Lokasi'),
                    ),
                  ),
                ],
              ),
            ],
          ),
        ),
      ],
    );
    return isFullscreen
        ? Scaffold(
          backgroundColor: Colors.white,
          body: SafeArea(child: dialogContent),
        )
        : Dialog(
          backgroundColor: Colors.transparent,
          insetPadding: const EdgeInsets.all(16),
          child: Container(
            width: double.infinity,
            height: MediaQuery.of(context).size.height * 0.8,
            decoration: BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.circular(16),
            ),
            child: dialogContent,
          ),
        );
  }
}
