// lib/widgets/map/measure_layer.dart
//
// Távolság és terület mérés — rögzítés nélkül, csak memóriában
//
// - Pontok: koppintásra kerülnek a térképre
// - Vonalak: azonnal megjelennek a szakaszok
// - Hossz: minden szakasz felezőpontján buborékban
// - Terület: centroidon m² / ha (+ kerület zárójelben)

import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:get/get.dart';
import 'package:latlong2/latlong.dart';
import 'package:terepi_seged/enums/map_measure_type.dart';

import '../../pages/map_survey/presentations/controllers/map_survey_controller.dart';

class DistanceOrAreaMeasureLayer extends StatelessWidget {
  final MapSurveyController controller;
  const DistanceOrAreaMeasureLayer({super.key, required this.controller});

  @override
  Widget build(BuildContext context) {
    return Obx(() {
      final type = controller.mapMeasureType.value;
      final points = controller.distanceOrAreaMeasurePoints.toList();

      if (type == MapMeasureType.none || points.isEmpty) {
        return const SizedBox.shrink();
      }

      final markers = <Marker>[];
      final polylines = <Polyline>[];

      // ── Vonalak ───────────────────────────────────────────────────
      if (points.length >= 2) {
        // Fővonal
        polylines.add(Polyline(
          points: points,
          color: Colors.deepOrange,
          strokeWidth: 2.5,
          borderColor: Colors.white.withOpacity(0.6),
          borderStrokeWidth: 1.0,
        ));

        // Szakaszhosszak a felezőpontokon
        for (int i = 0; i < points.length - 1; i++) {
          final mid = _midpoint(points[i], points[i + 1]);
          final dist = _haversine(points[i], points[i + 1]);
          markers.add(Marker(
            point: mid,
            width: 80,
            height: 22,
            alignment: Alignment.center,
            child: _LabelBubble(
              text: _fmtDist(dist),
              color: Colors.deepOrange,
            ),
          ));
        }
      }

      // ── Záró szár (terület módban: vissza az első ponthoz) ────────
      if (type == MapMeasureType.area && points.length >= 3) {
        polylines.add(Polyline(
          points: [points.last, points.first],
          color: Colors.deepOrange.withOpacity(0.5),
          strokeWidth: 2.0,
          //isDotted:    true,
        ));
      }

      // ── Összesítő buborék ─────────────────────────────────────────
      if (points.length >= 2) {
        final anchor = type == MapMeasureType.area && points.length >= 3
            ? _centroid(points)
            : points.last;

        final label = type == MapMeasureType.distance
            ? _totalDistLabel(points)
            : _areaLabel(points);

        markers.add(Marker(
          point: anchor,
          width: 140,
          height: 36,
          alignment: type == MapMeasureType.area
              ? Alignment.center
              : Alignment.topCenter,
          child: _LabelBubble(
            text: label,
            color: Colors.indigo,
            large: true,
          ),
        ));
      }

      // ── Mérési pontok ─────────────────────────────────────────────
      for (int i = 0; i < points.length; i++) {
        final isLast = i == points.length - 1;
        final isFirst = i == 0;
        markers.add(Marker(
          point: points[i],
          width: 20,
          height: 20,
          alignment: Alignment.center,
          child: Container(
            decoration: BoxDecoration(
              color: isFirst
                  ? Colors.green
                  : isLast
                      ? Colors.deepOrange
                      : Colors.white,
              shape: BoxShape.circle,
              border: Border.all(color: Colors.deepOrange, width: 2),
              boxShadow: const [
                BoxShadow(color: Colors.black26, blurRadius: 3),
              ],
            ),
          ),
        ));
      }

      return Stack(children: [
        if (polylines.isNotEmpty) PolylineLayer(polylines: polylines),
        if (markers.isNotEmpty) MarkerLayer(markers: markers),
      ]);
    });
  }

  // ── Számítások ────────────────────────────────────────────────────

  static const _distCalc = Distance();

  double _haversine(LatLng a, LatLng b) => _distCalc.as(LengthUnit.Meter, a, b);

  LatLng _midpoint(LatLng a, LatLng b) => LatLng(
        (a.latitude + b.latitude) / 2,
        (a.longitude + b.longitude) / 2,
      );

  LatLng _centroid(List<LatLng> pts) => LatLng(
        pts.map((p) => p.latitude).reduce((a, b) => a + b) / pts.length,
        pts.map((p) => p.longitude).reduce((a, b) => a + b) / pts.length,
      );

  double _totalDist(List<LatLng> pts) {
    double total = 0;
    for (int i = 0; i < pts.length - 1; i++) {
      total += _haversine(pts[i], pts[i + 1]);
    }
    return total;
  }

  /// Gömbháromszög módszer — pontos terület m²-ben
  double _area(List<LatLng> pts) {
    if (pts.length < 3) return 0;
    const r = 6371000.0;
    double area = 0;
    final n = pts.length;
    for (int i = 0; i < n; i++) {
      final j = (i + 1) % n;
      final xi = pts[i].longitude * pi / 180;
      final xj = pts[j].longitude * pi / 180;
      final yi = pts[i].latitude * pi / 180;
      final yj = pts[j].latitude * pi / 180;
      area += (xj - xi) * (2 + sin(yi) + sin(yj));
    }
    return (area.abs() * r * r / 2);
  }

  double _perimeter(List<LatLng> pts) {
    double p = _totalDist(pts);
    if (pts.length >= 3) p += _haversine(pts.last, pts.first);
    return p;
  }

  // ── Formázás ──────────────────────────────────────────────────────

  String _fmtDist(double m) {
    if (m < 1000) return '${m.toStringAsFixed(0)} m';
    return '${(m / 1000).toStringAsFixed(2)} km';
  }

  String _fmtArea(double m2) {
    if (m2 < 10000) return '${m2.toStringAsFixed(0)} m²';
    if (m2 < 1000000) return '${(m2 / 10000).toStringAsFixed(2)} ha';
    return '${(m2 / 1000000).toStringAsFixed(3)} km²';
  }

  String _totalDistLabel(List<LatLng> pts) => '⟷ ${_fmtDist(_totalDist(pts))}';

  String _areaLabel(List<LatLng> pts) {
    final a = _area(pts);
    final p = _perimeter(pts);
    return '${_fmtArea(a)}\n(${_fmtDist(p)})';
  }
}

// ─── Felirat buborék ──────────────────────────────────────────────────────────

class _LabelBubble extends StatelessWidget {
  final String text;
  final Color color;
  final bool large;
  const _LabelBubble({
    required this.text,
    required this.color,
    this.large = false,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.symmetric(
          horizontal: large ? 8 : 5, vertical: large ? 4 : 2),
      decoration: BoxDecoration(
        color: Colors.white.withOpacity(0.93),
        borderRadius: BorderRadius.circular(6),
        border: Border(left: BorderSide(color: color, width: 3)),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withOpacity(0.15),
            blurRadius: 4,
            offset: const Offset(0, 1),
          ),
        ],
      ),
      child: Text(
        text,
        style: TextStyle(
          fontSize: large ? 12 : 10,
          fontWeight: FontWeight.w700,
          color: color,
          height: 1.2,
          fontFeatures: const [FontFeature.tabularFigures()],
        ),
        textAlign: TextAlign.center,
        maxLines: 2,
      ),
    );
  }
}
