import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
import '../core/app_colors.dart';
import '../models/route_model.dart';
import '../services/route_simulator_service.dart';

List<LatLng> _smooth(List<LatLng> pts) {
  if (pts.length < 2) return pts;
  final res = <LatLng>[];
  for (int i = 0; i < pts.length - 1; i++) {
    final p0 = pts[i > 0 ? i - 1 : i];
    final p1 = pts[i];
    final p2 = pts[i + 1];
    final p3 = pts[i + 2 < pts.length ? i + 2 : i + 1];
    res.add(p1);
    for (int j = 1; j <= 8; j++) {
      final t = j / 9.0;
      res.add(LatLng(_cr(p0.latitude,p1.latitude,p2.latitude,p3.latitude,t),
                     _cr(p0.longitude,p1.longitude,p2.longitude,p3.longitude,t)));
    }
  }
  res.add(pts.last);
  return res;
}

double _cr(double a,double b,double c,double d,double t) => 0.5*(
  (2*b)+(-a+c)*t+(2*a-5*b+4*c-d)*t*t+(-a+3*b-3*c+d)*t*t*t);

// Calcular bearing entre dos puntos
double _bearing(LatLng from, LatLng to) {
  final lat1 = from.latitude * math.pi / 180;
  final lat2 = to.latitude * math.pi / 180;
  final dLng = (to.longitude - from.longitude) * math.pi / 180;
  final y = math.sin(dLng) * math.cos(lat2);
  final x = math.cos(lat1)*math.sin(lat2) - math.sin(lat1)*math.cos(lat2)*math.cos(dLng);
  return (math.atan2(y, x) * 180 / math.pi + 360) % 360;
}

// ── Mapa ciudadano ────────────────────────────────────────────────────────
class RouteMapWidget extends StatelessWidget {
  final RouteModel route;
  final RouteSimulatorService simulator;
  final bool showFullRoute;
  final double height;
  const RouteMapWidget({super.key, required this.route, required this.simulator,
      this.showFullRoute = false, this.height = 300});

  @override
  Widget build(BuildContext context) {
    final posIdx = simulator.getPositionIndex(route.routeId);
    final cur = posIdx < route.positions.length
        ? route.positions[posIdx].latLng : route.positions.last.latLng;
    final gps = simulator.isGpsActive(route.routeId);
    final all = _smooth(route.polylinePoints);
    final done = posIdx > 0
        ? _smooth(route.positions.take(posIdx+1).map((p)=>p.latLng).toList())
        : <LatLng>[];

    // Calcular bearing hacia siguiente punto
    double bear = 0;
    if (posIdx < route.positions.length - 1) {
      bear = _bearing(cur, route.positions[posIdx+1].latLng);
    }

    return ClipRRect(
      borderRadius: BorderRadius.circular(12),
      child: SizedBox(height: height,
        child: FlutterMap(
          options: MapOptions(
            initialCenter: cur, initialZoom: 14.5,
            initialRotation: -bear, // Rotar mapa según dirección del camión
          ),
          children: [
            TileLayer(urlTemplate:'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
                userAgentPackageName:'com.example.celaya_limpia'),
            // Ruta completa (gris punteada)
            PolylineLayer(polylines:[
              Polyline(points:all, color:Colors.grey.shade400, strokeWidth:4,
                  borderColor:Colors.white54, borderStrokeWidth:1),
            ]),
            // Tramo recorrido (guinda)
            if (done.isNotEmpty) PolylineLayer(polylines:[
              Polyline(points:done, color:AppColors.guindaPrimary, strokeWidth:5,
                  borderColor:AppColors.guindaDark, borderStrokeWidth:1),
            ]),
            MarkerLayer(markers:[
              // Camión con orientación
              Marker(point:cur, width:56, height:56,
                child:Transform.rotate(
                  angle: bear * math.pi / 180,
                  child:Container(
                    decoration:BoxDecoration(
                      color:gps?AppColors.guindaPrimary:Colors.grey,
                      shape:BoxShape.circle,
                      border:Border.all(color:Colors.white,width:2.5),
                      boxShadow:[BoxShadow(color:Colors.black38,blurRadius:6)]),
                    child:Icon(gps?Icons.navigation:Icons.gps_off,
                        color:Colors.white,size:26)))),
              // Origen
              Marker(point:route.positions.first.latLng, width:24, height:24,
                child:Container(decoration:BoxDecoration(color:AppColors.verdeExito,
                    shape:BoxShape.circle,border:Border.all(color:Colors.white,width:2)),
                  child:const Icon(Icons.circle,color:Colors.white,size:8))),
              // Destino
              Marker(point:route.positions.last.latLng, width:28, height:28,
                child:Container(decoration:BoxDecoration(color:AppColors.rojoError,
                    shape:BoxShape.circle,border:Border.all(color:Colors.white,width:2)),
                  child:const Icon(Icons.flag,color:Colors.white,size:14))),
            ]),
          ])));
  }
}

// ── Mapa Admin (todas las rutas) ──────────────────────────────────────────
class AdminMapWidget extends StatefulWidget {
  final List<RouteModel> routes;
  final RouteSimulatorService simulator;
  const AdminMapWidget({super.key, required this.routes, required this.simulator});
  @override State<AdminMapWidget> createState() => _AdminMapWidgetState();
}

class _AdminMapWidgetState extends State<AdminMapWidget> {
  String? _sel;
  static const _colors = [
    Colors.blue,Colors.green,Colors.orange,Colors.purple,Colors.teal,
    Colors.red,Colors.indigo,Colors.brown,Colors.cyan,Colors.pink,
    Colors.amber,Colors.lime,Colors.deepOrange,Colors.lightBlue,Colors.deepPurple,
  ];

  @override
  Widget build(BuildContext context) {
    return Column(children:[
      Expanded(child: FlutterMap(
        options: const MapOptions(initialCenter:LatLng(20.5211,-100.8196), initialZoom:12),
        children:[
          TileLayer(urlTemplate:'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
              userAgentPackageName:'com.example.celaya_limpia'),
          PolylineLayer(polylines: widget.routes.asMap().entries.map((e){
            final c = _colors[e.key%_colors.length];
            final isS = _sel==null||_sel==e.value.routeId;
            return Polyline(points:_smooth(e.value.polylinePoints),
              color:c.withOpacity(isS?0.85:0.2), strokeWidth:isS?4:1.5,
              borderColor:Colors.white.withOpacity(isS?0.4:0), borderStrokeWidth:1);
          }).toList()),
          MarkerLayer(markers: widget.routes.asMap().entries.map((e){
            final r = e.value;
            final idx = widget.simulator.getPositionIndex(r.routeId);
            final pos = idx < r.positions.length ? r.positions[idx].latLng : r.positions.last.latLng;
            final c = _colors[e.key%_colors.length];
            final gps = widget.simulator.isGpsActive(r.routeId);
            double bear = 0;
            if (idx < r.positions.length - 1) bear = _bearing(pos, r.positions[idx+1].latLng);
            return Marker(point:pos, width:44, height:44,
              child:GestureDetector(
                onTap:()=>setState(()=>_sel=_sel==r.routeId?null:r.routeId),
                child:Transform.rotate(angle: bear*math.pi/180,
                  child:Container(decoration:BoxDecoration(
                      color:gps?c:Colors.grey, shape:BoxShape.circle,
                      border:Border.all(color:Colors.white,width:2),
                      boxShadow:[BoxShadow(color:Colors.black26,blurRadius:4)]),
                    child:Center(child:Text(r.truckId.toString().substring(1),
                      style:const TextStyle(color:Colors.white,fontSize:11,fontWeight:FontWeight.bold)))))));
          }).toList()),
        ])),
      if (_sel!=null) Container(
        padding:const EdgeInsets.symmetric(horizontal:16,vertical:10),
        color:AppColors.guindaPrimary,
        child:Row(children:[
          const Icon(Icons.local_shipping,color:Colors.white,size:16),
          const SizedBox(width:8),
          Expanded(child:Text(widget.routes.firstWhere((r)=>r.routeId==_sel).name,
              style:const TextStyle(color:Colors.white,fontWeight:FontWeight.bold,fontSize:13))),
          Text('Pos ${widget.simulator.getPositionIndex(_sel!)}/7',
              style:const TextStyle(color:AppColors.dorado,fontSize:12)),
        ])),
    ]);
  }
}

// ── Mapa conductor (con bearing) ──────────────────────────────────────────
class DriverRouteMap extends StatelessWidget {
  final RouteModel route;
  final RouteSimulatorService simulator;
  const DriverRouteMap({super.key, required this.route, required this.simulator});

  @override
  Widget build(BuildContext context) {
    final idx  = simulator.getPositionIndex(route.routeId);
    final gps  = simulator.isGpsActive(route.routeId);
    final positions = route.positions;
    final cur  = idx < positions.length ? positions[idx].latLng : positions.last.latLng;
    double bear = 0;
    if (idx < positions.length - 1) bear = _bearing(cur, positions[idx+1].latLng);

    final done = idx > 0
        ? _smooth(positions.take(idx+1).map((p)=>p.latLng).toList())
        : <LatLng>[];
    final pending = _smooth(positions.skip(idx).map((p)=>p.latLng).toList());

    return FlutterMap(
      options: MapOptions(initialCenter:cur, initialZoom:15, initialRotation:-bear),
      children:[
        TileLayer(urlTemplate:'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
            userAgentPackageName:'com.example.celaya_limpia'),
        PolylineLayer(polylines:[
          Polyline(points:pending, color:Colors.grey.shade400, strokeWidth:5,
              borderColor:Colors.white54, borderStrokeWidth:1),
          if (done.isNotEmpty)
            Polyline(points:done, color:AppColors.moradoConductor, strokeWidth:6,
                borderColor:AppColors.moradoConductor.withOpacity(0.4), borderStrokeWidth:2),
        ]),
        MarkerLayer(markers:[
          // Waypoints pendientes
          ...positions.skip(idx+1).take(4).toList().asMap().entries.map((e)=>
            Marker(point:e.value.latLng, width:22, height:22,
              child:Container(decoration:BoxDecoration(color:Colors.amber,shape:BoxShape.circle,
                  border:Border.all(color:Colors.white,width:1.5)),
                child:Center(child:Text('${idx+2+e.key}',
                    style:const TextStyle(color:Colors.white,fontSize:9,fontWeight:FontWeight.bold)))))),
          // Camión orientado
          Marker(point:cur, width:56, height:56,
            child:Transform.rotate(angle:bear*math.pi/180,
              child:Container(decoration:BoxDecoration(
                  color:gps?AppColors.moradoConductor:Colors.grey, shape:BoxShape.circle,
                  border:Border.all(color:Colors.white,width:2.5),
                  boxShadow:[BoxShadow(color:Colors.black38,blurRadius:8)]),
                child:Icon(gps?Icons.navigation:Icons.gps_off,color:Colors.white,size:28)))),
        ]),
      ]);
  }
}
