import { CommonModule } from "@angular/common";
import {
  Component,
  Input,
  SimpleChanges,
  AfterViewInit,
  OnDestroy,
} from "@angular/core";
import { LeafletModule } from "@asymmetrik/ngx-leaflet";
import {
  NgbAlertModule,
  NgbCollapseModule,
  NgbDropdownModule,
  NgbModal,
  NgbModule,
} from "@ng-bootstrap/ng-bootstrap";
import {
  latLng,
  tileLayer,
  Map,
  Polyline,
  LatLngExpression,
  FeatureGroup,
  DivIcon,
} from "leaflet";
import * as L from "leaflet";
import "leaflet.markercluster";
import { SubDistricService } from "src/app/cores/api-services/map/sub-district.service";
import { ReportSegmens } from "src/app/cores/api-services/map/report-segmens.service";
import { LaporanService } from "src/app/cores/api-services/laporan/laporan.service";
import { HelpersService } from "src/app/cores/services/helpers.service";
import { LoadingService } from "src/app/cores/services/loading.service";
import { DetailPerbaikanService } from "src/app/cores/api-services/perbaikan/detail-perbaikan.service";
import * as dayjs from "dayjs";

interface Kerusakan {
  status: string;
  jumlah: number;
}

@Component({
  selector: "app-map",
  standalone: true,
  imports: [
    CommonModule,
    LeafletModule,
    NgbDropdownModule,
    NgbAlertModule,
    NgbCollapseModule,
    NgbModule,
  ],
  templateUrl: "./map.component.html",
  styleUrls: ["./map.component.scss"],
})
export class MapComponent implements AfterViewInit {
  isExpand = true;
  @Input() polylineData: any = L.layerGroup();
  @Input() perbaikanSegmen: any;

  @Input() showOption: boolean = true;
  @Input() showStatus: boolean = true;

  @Input() allowDragging: boolean = true;

  @Input() cnterLatLng: any = { lat: -7.869576, lng: 112.5309706 };

  scheduleLayer: FeatureGroup = new FeatureGroup();

  polylineLayer: FeatureGroup = new FeatureGroup();
  polygonLayer: FeatureGroup = new FeatureGroup();
  pointLayer: FeatureGroup = new FeatureGroup();

  selectedData: any[] = [];
  selectedOption: string = "DSS";

  map: Map | undefined;

  zoom: number = 14;
  lat: number = -7.8699381;
  lng: number = 112.5285772;
  dayjs = dayjs;

  public mapOptions = {
    layers: [
      tileLayer(
        "http://mt0.google.com/vt/lyrs=m&hl=en&x={x}&y={y}&z={z}&s=Ga",
        {
          maxZoom: 22,
          minZoom: 11,
        }
      ),
    ],
    scrollWheelZoom: false,
    zoom: this.zoom,
    dragging: this.allowDragging,
    doubleClickZoom: false,
    touchZoom: false,
    tap: false,
    center: latLng(this.lat, this.lng),
  };

  constructor(
    public helpers: HelpersService,
    public loading: LoadingService,
    public api: LaporanService,
    public modal: NgbModal,
    private reportSegmens: ReportSegmens,
    private subDistrict: SubDistricService,
    private perbaikan: DetailPerbaikanService
  ) {}

  initMap(map: Map) {
    if (!this.map) this.map = map;
    this.map.zoomControl.setPosition("bottomright");
  }

  ngAfterViewInit(): void {
    window.dispatchEvent(new Event("resize"));
  }

  ngOnChanges(changes: SimpleChanges): void {
    if (changes["cnterLatLng"]) {
    }
    if (changes["allowDragging"]) {
      this.mapOptions.dragging = this.allowDragging;
    }
  }

  ngOnInit(): void {
    if (this.polylineData.segmen == null && this.perbaikanSegmen == null) {
      this.getSubDistrict();
      this.getReportSegmens();
    } else if (this.perbaikanSegmen != null) {
      this.getReportSegmensBySchedule();
    } else {
      this.getReportSegmentById();
    }
    this.condition();
  }

  isCollapsed: boolean = false;
  toggleCollapse() {
    if (!this.isCollapsed) {
      this.getStatusDss();
    }
    this.isCollapsed = !this.isCollapsed;
  }

  toggleFullscreen() {
    const mapElement = document.getElementById("map");

    if (mapElement) {
      if (!document.fullscreenElement) {
        if (mapElement.requestFullscreen) {
          mapElement.requestFullscreen();
        }
      } else {
        if (document.exitFullscreen) {
          document.exitFullscreen();
        }
      }
    }
  }

  onOptionChange(selectedValue: any) {
    this.selectedOption = selectedValue;

    if (this.map) {
      this.map.removeLayer(this.pointLayer);
      this.map.removeLayer(this.polygonLayer);
      this.map.removeLayer(this.polylineLayer);
    }

    this.selectedData = [];

    if (selectedValue === "DSS") {
      if (this.map) {
        this.map.closePopup();
      }
    } else if (selectedValue === "Titik Laporan") {
      this.getStatusTitik();
      this.getStatusSegmenByReport();
    }

    if (this.map) {
      if (selectedValue === "DSS") {
        this.polygonLayer.addTo(this.map);
        this.polylineLayer.addTo(this.map);
      } else if (selectedValue === "point") {
        this.pointLayer.addTo(this.map);
      }
    }
  }

  createCustomIcon(imageUrl: string, width: number, height: number): DivIcon {
    return new DivIcon({
      className: "custom-icon",
      html: `<img src="${imageUrl}" width="${width}" height="${height}">`,
      iconSize: [width, height],
      iconAnchor: [width / 2, height],
    });
  }

  addMarkers(status: string): L.Icon<L.IconOptions> | DivIcon {
    const iconUrl = this.getIconByStatus(status);

    const iconOptions: L.IconOptions = {
      iconUrl: iconUrl,
      iconSize: [32, 32],
    };

    return L.icon(iconOptions);
  }

  getIconByStatus(status: string): string {
    switch (status) {
      case "PROG":
        return "assets/images/icon/marker-dalam_proses.png";
      case "FOLUP":
        return "assets/images/icon/marker-tindak_lanjut.png";
      case "DONE":
        return "assets/images/icon/marker-selesai.png";
      case "RPR":
        return "assets/images/icon/marker-perbaikan.png";
      case "FIXED":
        return "assets/images/icon/marker-selesai-perbaikan.png";
      default:
        return "assets/images/icon/marker-default.png";
    }
  }

  getColorByStatusTitikLaporan(status_id: string): string {
    const colorMap: { [key: string]: string } = {
      "Dalam Proses": "#586AF5",
      "Tindak Lanjut": "#FFAB00",
      "Selesai Perbaikan": "#663000",
      Perbaikan: "#F35625",
      Selesai: "#24D07A",
    };

    return colorMap[status_id] || "transparent";
  }

  getStatusDss() {
    const colorMap: { [key: string]: string } = {
      "Berlubang Parah": "#215A99",
      "Berlubang Sedang": "#2B79CC",
      "Berlubang Ringan": "#87C0FF",
      "Terkelupas Parah": "#18795F",
      "Terkelupas Sedang": "#1CA762",
      "Terkelupas Ringan": "#4FDA95",
      "Retak Parah": "#992A44",
      "Retak Sedang": "#FF4671",
      "Retak Ringan": "#FF90AA",
      "Bergelombang Parah": "#322564",
      "Bergelombang Sedang": "#644BC8",
      "Bergelombang Ringan": "#977EFB",
      "PermukaanKasar Berat": "#CCCC00",
      "PermukaanKasar Sedang": "#FFFF00",
      "PermukaanKasar Ringan": "#FFFF66",
    };
    const colors: string[] = Object.values(colorMap);

    this.statusDss = Object.keys(colorMap).map((status, index) => ({
      status,
      jumlah: 0,
      color: colors[index],
    }));
  }

  getStatusTitik() {
    const statusMap: { [key: string]: string } = {
      "Dalam Proses": "#586AF5",
      "Tindak Lanjut": "#FFAB00",
      "Selesai Perbaikan": "#663000",
      Perbaikan: "#F35625",
      Selesai: "#24D07A",
    };

    const colors: string[] = Object.values(statusMap);

    this.statusTitikLaporan = Object.keys(statusMap).map((status, index) => ({
      status,
      jumlah: 0,
      color: colors[index],
    }));
  }

  getColorByStatusDss(status: string, userLevel?: string): string {
    const userStatus = `${status} ${userLevel}`;
    const colorMap: { [key: string]: string } = {
      "- -": "#EC8F5E",
      "Berlubang Parah": "#215A99",
      "Berlubang Sedang": "#2B79CC",
      "Berlubang Ringan": "#87C0FF",
      "Terkelupas Parah": "#18795F",
      "Terkelupas Sedang": "#1CA762",
      "Terkelupas Ringan": "#4FDA95",
      "Retak Parah": "#992A44",
      "Retak Sedang": "#FF4671",
      "Retak Ringan": "#FF90AA",
      "Bergelombang Parah": "#322564",
      "Bergelombang Sedang": "#644BC8",
      "Bergelombang Ringan": "#977EFB",
      "PermukaanKasar Berat": "#CCCC00",
      "PermukaanKasar Sedang": "#FFFF00",
      "PermukaanKasar Ringan": "#FFFF66",
    };

    return colorMap[userStatus] || colorMap[status];
  }

  condition(): boolean {
    if (this.polylineLayer.getLayers().length === 0) {
      return true;
    } else {
      return false;
    }
  }

  statusDss: Kerusakan[] = [];
  statusTitikLaporan: Kerusakan[] = [];

  sortCustomDss() {
    this.statusTitikLaporan.sort((a, b) => {
      const urutanDss = [
        "Dalam Proses",
        "Ditindak Lanjuti",
        "Perbaikan",
        "Selesai",
      ];
      return urutanDss.indexOf(a.status) - urutanDss.indexOf(b.status);
    });
  }

  sortByCustomOrder() {
    this.statusDss.sort((a, b) => {
      const urutanStatus = [
        "Berlubang Parah",
        "Berlubang Sedang",
        "Berlubang Ringan",
        "Terkelupas Parah",
        "Terkelupas Sedang",
        "Terkelupas Ringan",
        "Retak Parah",
        "Retak Sedang",
        "Retak Ringan",
        "Bergelombang Parah",
        "Bergelombang Sedang",
        "Bergelombang Ringan",
        "NULL",
      ];
      return urutanStatus.indexOf(a.status) - urutanStatus.indexOf(b.status);
    });
  }

  embedReportSegments = {
    embed: "segmen,analytic_data",
  };

  embedReportSegmentsPerbaikan = {
    embed: "user.user,user.segmens.segmen,user.status_report",
  };

  embedReportSchedule = {
    embed: "user.user,user.segmens.segmen,user.status_report",
  };

  getReportSegmensBySchedule(): void {
    this.mapOptions.zoom = 18;
    this.mapOptions.dragging = false;

    this.perbaikan.getById(this.perbaikanSegmen).subscribe((response) => {
      const data = response.data.report.segmens;

      for (const segmen of data) {
        const geojson = JSON.parse(segmen.segmen.geojson);
        const coordinates = geojson.coordinates;

        const coordById = coordinates[0];

        this.lat = coordById[1];
        this.lng = coordById[0];

        const latLngCoordinates: LatLngExpression[] = coordinates.map(
          (coord: [number, number]) => ({
            lat: coord[1],
            lng: coord[0],
          })
        );

        const status_level = segmen.user_level;
        const status_type = segmen.user_type;
        const polyline = new Polyline(latLngCoordinates, {
          // color: this.getColorByStatusDss(status_type, status_level),
          color: "#586AF5",
          weight: 8,
        });

        polyline.on("mouseover", function () {
          (".leaflet-mouse-marker");
        });
        this.scheduleLayer.addLayer(polyline);
      }

      if (this.map) {
        this.map?.panTo(latLng(this.lat, this.lng));
        this.scheduleLayer.addTo(this.map);
      }
    });
  }

  // Show Segmen ID By Report, EndPoint:Report-Segmen/ID
  // Menampilkan satu Segmen By ID -> Page: Data-Laporan
  getReportSegmentById(): void {
    this.loading.isLoading();
    this.mapOptions.zoom = 19;
    this.mapOptions.dragging = false;
    this.reportSegmens.getById(this.polylineData.id).subscribe({
      next: ({}) => {
        const geojson = JSON.parse(this.polylineData.segmen.geojson);
        const coordinates = geojson.coordinates;

        const coordById = coordinates[0];

        this.lat = coordById[1];
        this.lng = coordById[0];

        const latLngCoordinates: LatLngExpression[] = coordinates.map(
          (coord: [number, number]) => ({
            lat: coord[1],
            lng: coord[0],
          })
        );

        const status_level = this.polylineData.user_level;
        const status_type = this.polylineData.user_type;

        const polyline = new Polyline(latLngCoordinates, {
          color: this.getColorByStatusDss(status_type, status_level),
          weight: 8,
        });

        console.log(status_type, status_level);

        if (this.map) {
          this.polylineLayer.addTo(this.map);
          this.map.setZoom(this.mapOptions.zoom);
        }

        this.map?.panTo(latLng(this.lat, this.lng));
        this.polylineLayer.addLayer(polyline);
      },
      error: () => {},
    });
  }

  // Show Segmen By Report Segments, EndPoint:Report-Segmens
  // Menampilkan seluruh segmen
  getReportSegmens(): void {
    this.loading.isLoading();
    this.reportSegmens.getAll(this.embedReportSegments).subscribe(
      (response) => {
        const data = response.data;

        if (data && data.length > 0) {
          this.polylineLayer.clearLayers();

          for (const feature of data) {
            const geojson = JSON.parse(feature.segmen.geojson);

            const coordinates = geojson.coordinates;

            const featureCoordinates: LatLngExpression[] = coordinates.map(
              (coord: [number, number]) => ({
                lat: coord[1],
                lng: coord[0],
              })
            );

            const status_level = feature.user_level;
            const status_type = feature.user_type;

            const polyline = new Polyline(featureCoordinates, {
              color: this.getColorByStatusDss(status_type, status_level),
              weight: 5,
            });

            this.polylineLayer.addLayer(polyline);
          }

          if (this.map) {
            this.polylineLayer.addTo(this.map);
          }
        }
      },
      (error) => {}
    );
  }

  // ngOnDestroy(): void {
  //   this.getStatusSegmenByReport();
  // }

  embedReportList = {
    embed:
      "segmens.segmen,segmens.analytic_data,segmens.photos,status_report,user",
  };
  // Show Segmen By Status Laporan, EndPoint:Report-List
  // Menampilkan titik segmen laporan berdasarkan laporan
  getStatusSegmenByReport(): void {
    this.api.getAll(this.embedReportList).subscribe((response) => {
      const data = response.data;

      if (data && data[0]?.segmens && data[0]?.segmens.length > 0) {
        this.pointLayer.clearLayers();

        for (const segmenData of data) {
          const segmens = segmenData.segmens;
          for (const segmen of segmens) {
            const geojson = JSON.parse(segmen?.segmen?.geojson);
            const coordinates = geojson.coordinates;

            const latLngCoordinates: LatLngExpression[] = coordinates.map(
              (coord: [number, number]) => ({
                lat: coord[1],
                lng: coord[0],
              })
            );

            const hasil = segmen.user_type + " " + segmen.user_level;

            const status_id = segmenData.status_id;

            if (status_id !== "RJT") {
              const customIcon = L.icon({
                iconUrl: this.getIconByStatus(status_id),
                iconSize: [32, 32],
                iconAnchor: [16, 32],
              });

              const marker = L.marker(latLngCoordinates[0], {
                icon: customIcon,
              }).addTo(this.pointLayer);

              this.pointLayer.setStyle({ className: "mask" });

              marker.addTo(this.pointLayer);
              marker.on("click", (e) => {
                for (const photo of segmen.photos) {
                  if (this.map) {
                    L.popup({
                      className: "custom-popup",
                    })
                      .setLatLng(e.latlng)
                      .setContent(
                        `
                <div>
                  <div>
                    <div class="d-flex justify-content-between align-items-center text-wrap" style:"display: flex">
                      <p class="text-uppercase fs-6 fw-bold mb-2"
                        style="font-size: 14px; color: ${
                          segmenData.status_report.id === "PROG"
                            ? "#586AF5"
                            : segmenData.status_report.id === "RPR"
                            ? "#F35625"
                            : segmenData.status_report.id === "FIXED"
                            ? "#663000"
                            : segmenData.status_report.id === "FOLUP"
                            ? "#FFAB00"
                            : segmenData.status_report.id === "DONE"
                            ? "#24D07A"
                            : "black"
                        };">
                        ${segmenData.status_report.name}
                      </p>
                      <p class="fs-6 mb-2" style="text-align: right;">
                        No.Tiket ${segmenData.no_ticket}
                      </p>
                    </div>

                    <div class="d-flex mb-2 align-items-center">
                      <img 
                        class="location-image" 
                        src="${photo.abs_path}"
                        style="width: 94px; height: 94px; border-radius: 8px;">
                      <div class="ms-3">
                        <div class="d-flex mb-1">
                          <i class="bi bi-person me-2" style="color: #586af5"></i>
                          Nama ${segmenData.user.fullname}
                        </div>
                        <div class="d-flex mb-1">
                          <i class="bi bi-geo-alt me-2" style="color: #586af5"></i>
                          ${segmen.segmen.name}
                        </div>
                        <div class="d-flex mb-1">
                          <i class="bi bi-calendar2 me-2" style="color: #586af5"></i>
                          ${dayjs(segmenData.created_at).format("DD-MM-YYYY")}
                        </div>
                      </div>
                    </div>

                    <div class="d-flex mb-2">
                      <Label class="d-flex align-self-center me-3">Keterangan :</Label>
                      <small class="btn btn-custom" 
                        style="color: white; background-color: ${
                          hasil === "Berlubang Parah"
                            ? "#215A99"
                            : hasil === "Berlubang Sedang"
                            ? "#2B79CC"
                            : hasil === "Berlubang Ringan"
                            ? "#87C0FF"
                            : hasil === "Terkelupas Parah"
                            ? "#18795F"
                            : hasil === "Terkelupas Sedang"
                            ? "#1CA762"
                            : hasil === "Terkelupas Ringan"
                            ? "#4FDA95"
                            : hasil === "Retak Parah"
                            ? "#992A44"
                            : hasil === "Retak Sedang"
                            ? "#FF4671"
                            : hasil === "Retak Ringan"
                            ? "#FF90AA"
                            : hasil === "Bergelombang Parah"
                            ? "#322564"
                            : hasil === "Bergelombang Sedang"
                            ? "#644BC8"
                            : hasil === "Bergelombang Ringan"
                            ? "#977EFB"
                            : "black"
                        };"
                      >
                        ${
                          segmen.user_type === "-" && segmen.user_level === "-"
                            ? `Belum Diketahui`
                            : `${segmen.user_type}${segmen.user_level}`
                        }
                      </small>
                    </div>

                    <p 
                      class="description text-justify mb-0"
                      style="font-size: 14px; letter-spacing: 0.15px; text-align: justify">
                      ${segmenData.note}
                    </p>
                  </div>
                </div>
                `
                      )
                      .openOn(this.map);
                  }
                }
              });
            }
            this.getColorByStatusTitikLaporan(segmenData.status_report.name);
          }
        }
        this.getStatusTitik();
        if (this.map) {
          this.pointLayer.addTo(this.map);
        }
      }
    });
  }

  // Show Polygon, EndPoint:sub-district
  getSubDistrict(): void {
    this.subDistrict.getAll().subscribe(
      (response) => {
        const data = response.data;

        if (data && data.length > 0) {
          this.polygonLayer.clearLayers();

          for (const item of data) {
            const geojson = JSON.parse(item.geojson);

            const polygon = L.geoJSON(geojson, {
              style: {
                fillColor: "green",
                weight: 2,
                color: "white",
              },
            });

            polygon.on("click", (e) => {
              const layer = e.target;
              const name = item.name;

              const popup = L.popup().setContent(name);

              layer.bindPopup(popup).openPopup();
            });

            polygon.addTo(this.polygonLayer);
          }
          if (this.map) {
            this.polygonLayer.addTo(this.map);
          }
        }
      },
      (error) => {}
    );
  }
}
