import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_map_location_marker/flutter_map_location_marker.dart';
//import 'package:flutter_map_marker_popup/flutter_map_marker_popup.dart';
import 'package:flutter_polyline_points/flutter_polyline_points.dart';
import 'package:get/get.dart';
import 'package:latlong2/latlong.dart';
import 'package:gifunavi/model/destination.dart';
import 'package:gifunavi/pages/destination/destination_controller.dart';
import 'package:gifunavi/pages/index/index_controller.dart';
import 'package:gifunavi/utils/text_util.dart';
import 'package:gifunavi/widgets/base_layer_widget.dart';
import 'package:gifunavi/widgets/bottom_sheet_new.dart';
//import 'package:gifunavi/widgets/bottom_sheets/bottom_sheet_start.dart';
//import 'package:gifunavi/widgets/bottom_sheets/bottom_sheet_goal.dart';
//import 'package:gifunavi/widgets/bottom_sheets/bottom_sheet_normal_point.dart';

// FlutterMapウィジェットを使用して、地図を表示します。
// IndexControllerから目的地のリストを取得し、マーカーとしてマップ上に表示します。
// マーカーがタップされると、BottomSheetウィジェットを表示します。
// 現在地の表示、ルートの表示、ベースレイヤーの表示などの機能を提供します。
// 主なロジック：
// FlutterMapウィジェットを使用して、地図を表示します。
// IndexControllerから目的地のリストを取得し、MarkerLayerを使用してマーカーを表示します。
// getMarkerShapeメソッドを使用して、マーカーの見た目をカスタマイズします。目的地の種類に応じて、異なるマーカーを表示します。
// マーカーがタップされると、festuretoDestinationメソッドを使用してGeoJSONFeatureをDestinationオブジェクトに変換し、showModalBottomSheetを使用してBottomSheetウィジェットを表示します。
// CurrentLocationLayerを使用して、現在地をマップ上に表示します。
// PolylineLayerを使用して、ルートをマップ上に表示します。getPointsメソッドを使用して、ルートの座標を取得します。
// BaseLayerを使用して、マップのベースレイヤーを表示します。
//
class DestinationMapPage extends StatelessWidget {
  DestinationMapPage({super.key});

  final IndexController indexController = Get.find<IndexController>();

  final DestinationController destinationController =
      Get.find<DestinationController>();
  StreamSubscription? subscription;
  //final PopupController _popupLayerController = PopupController();

  List<LatLng>? getPoints() {
    //print("##### --- route point ${indexController.routePoints.length}");
    List<LatLng> pts = [];
    for (PointLatLng p in indexController.routePoints) {
      LatLng l = LatLng(p.latitude, p.longitude);
      pts.add(l);
    }
    return pts;
  }

  // 要検討：マーカーのタップイベントを処理する際に、エラーハンドリングが不十分です。例外が発生した場合の処理を追加することをお勧めします。
  //
  List<Marker>? getMarkers() {
    List<Marker> pts = [];
    //int index = -1;
    for (int i = 0; i < destinationController.destinations.length; i++) {
      Destination d = destinationController.destinations[i];
      //print("^^^^ $d ^^^^");
      Marker m = Marker(
          point: LatLng(d.lat!, d.lon!),
          alignment: Alignment.center,
          child: InkWell(
            onTap: () {
              //print("-- Destination is --- ${d.name} ------");
              if (indexController.currentDestinationFeature.isNotEmpty) {
                indexController.currentDestinationFeature.clear();
              }
              indexController.currentDestinationFeature.add(d);
              //indexController.getAction();

              Widget bottomSheet = BottomSheetNew(destination: d);
              /*
              if (d.cp == -1 || d.cp == 0) {
                bottomSheet = BottomSheetStart(destination: d);
              } else if (d.cp == -2 || d.cp == 0) {
                bottomSheet = BottomSheetGoal(destination: d);
              } else {
                bottomSheet = BottomSheetNormalPoint(destination: d);
              }
               */

              showModalBottomSheet(
                  context: Get.context!,
                  isScrollControlled: true,
                  constraints:
                      BoxConstraints.loose(Size(Get.width, Get.height * 0.85)),
                  builder: ((context) => bottomSheet ),

                      ).whenComplete(() {
                //print("---- set skip gps to false -----");
                destinationController.skipGps = false;
              });
            },
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Container(
                  width: 20,
                  height: 20,
                  decoration: BoxDecoration(
                    color: Colors.red,
                    shape: BoxShape.circle,
                    border: Border.all(
                      color: Colors.white,
                      width: d.checkin_radious != null ? d.checkin_radious! : 1,
                    ),
                  ),
                  child: Center(
                    child: Text(
                      (i + 1).toString(),
                      style: const TextStyle(color: Colors.white),
                    ),
                  ),
                ),
                Container(
                    color: Colors.yellow,
                    child: Text(
                      TextUtils.getDisplayText(d),
                      style: const TextStyle(
                          fontSize: 15.0,
                          fontWeight: FontWeight.bold,
                          overflow: TextOverflow.visible),
                    )),
              ],
            ),
          ));

      pts.add(m);
    }
    return pts;
  }

  @override
  Widget build(BuildContext context) {
    return Obx((() => Stack(
          children: [
            // indexController.is_rog_mapcontroller_loaded.value == false ?
            //   Center(child: CircularProgressIndicator())
            // :
            // Padding(
            //   padding: const EdgeInsets.only(left:8.0),
            //   child: BreadCrumbWidget(mapController:indexController.rogMapController),
            // ),
            Padding(
              padding: const EdgeInsets.only(top: 0.0),
              //child: TravelMap(),
              child: travelMap(),
            ),
          ],
        )));
  }

  // 要検討：MapOptionsのboundsプロパティにハードコードされた座標が使用されています。これを動的に設定できるようにすることを検討してください。
  //
  FlutterMap travelMap() {
    return FlutterMap(
      mapController: indexController.rogMapController,
      options: MapOptions(
        onMapReady: () {
          indexController.isRogMapcontrollerLoaded.value = true;
          subscription = indexController.rogMapController.mapEventStream
              .listen((MapEvent mapEvent) {
            if (mapEvent is MapEventMoveStart) {}
            if (mapEvent is MapEventMoveEnd) {
              //destinationController.is_gps_selected.value = true;
              //indexController.mapController!.move(c.center, c.zoom);
              LatLngBounds bounds = indexController.rogMapController.bounds!;
              indexController.currentBound.clear();
              indexController.currentBound.add(bounds);
              if (indexController.currentUser.isEmpty) {
                indexController.loadLocationsBound(indexController.currentUser[0]["user"]["event_code"]);
              }
            }
          });
        },
        bounds: indexController.currentBound.isNotEmpty
            ? indexController.currentBound[0]
            : LatLngBounds.fromPoints([
                const LatLng(35.03999881162295, 136.40587119778962),
                const LatLng(36.642756778706904, 137.95226720406063)
              ]),
        initialZoom: 1,
        maxZoom: 42,
        interactiveFlags: InteractiveFlag.pinchZoom | InteractiveFlag.drag,
      ),
      children: [
        const BaseLayer(),
        Obx(
          () => indexController.routePointLenght > 0
              ? PolylineLayer(
                  polylines: [
                    Polyline(
                        points: getPoints()!,
                        strokeWidth: 6.0,
                        color: Colors.indigo),
                  ],
                )
              : Container(),
        ),
        CurrentLocationLayer(),
        MarkerLayer(markers: getMarkers()!),
      ],
    );
  }
}
