import { CommonModule } from "@angular/common";
import { Component, ViewChild, Input } from "@angular/core";
import {
  NgbAccordionModule,
  NgbModal,
  NgbToastModule,
} from "@ng-bootstrap/ng-bootstrap";
import { AuthService } from "src/app/cores/services/auth.service";
import { KerusakanComponent } from "../../pages/laporan/modal/kerusakan/kerusakan.component";
import { MapComponent } from "../map/map.component";
import { LightboxComponent } from "../lightbox/lightbox.component";
import { Observable, Subject, takeUntil } from "rxjs";
import { ReportSegmens } from "src/app/cores/api-services/map/report-segmens.service";
import { HelpersService } from "src/app/cores/services/helpers.service";
import { HttpClient } from "@angular/common/http";
import { FormsModule } from "@angular/forms";
import { LoadingService } from "src/app/cores/services/loading.service";
import { PredictRoad } from "src/app/cores/interfaces/master";
import { MachineSegmenService } from "src/app/cores/api-services/machine-learning/machine-segmen.service";

export interface FilePreviewModel {
  uploadResponse?: any;
  file: File | Blob;
  fileName: string;
}

@Component({
  selector: "app-segment",
  standalone: true,
  imports: [
    NgbAccordionModule,
    CommonModule,
    MapComponent,
    LightboxComponent,
    FormsModule,
    NgbToastModule,
  ],
  templateUrl: "./segment.component.html",
  styleUrls: ["./segment.component.scss"],
})
export class SegmentComponent {
  @ViewChild("map") Map!: MapComponent;
  @Input() segmentData: any;
  @Input() index: any;
  @Input() statusLaporan: any;

  show = false;
  showRecommend: boolean = false;
  isLoading: boolean = false;
  coordinates: [][] = [];
  base64Image: any;

  accordionData = {};

  segmenType: any;
  segmenLevel: any;

  dataUpdateSubs$ = new Subject<void>();

  selectType = "";
  selectLevel = "";

  constructor(
    public loading: LoadingService,
    public http: HttpClient,
    private auth: AuthService,
    private machine: MachineSegmenService,
    private api: ReportSegmens,
    public helpers: HelpersService,
    public modal: NgbModal
  ) {}

  laterRecomend() {
    this.show = false;
  }

  abs_pathUrl: string = "";
  base64String!: string;
  imageUrl: any;

  ngOnInit(): void {
    this.segmenType = this.segmentData.user_type;
    this.segmenLevel = this.segmentData.user_level;

    if (this.segmenType === "-" && this.segmenLevel === "-") {
      this.show = true;
    }

    if (this.segmentData && this.segmentData.photos) {
      let absPaths = this.segmentData.photos.map(
        (photo: any) => photo.abs_path
      );
      this.abs_pathUrl = absPaths[0];
    }

    const geojson = JSON.parse(this.segmentData.segmen.geojson);
    this.coordinates = geojson.coordinates;
  }

  onType(data: any): void {
    const modalRef = this.modal.open(KerusakanComponent);
    modalRef.componentInstance.data = data;

    modalRef.result.then(
      (result) => {
        if (result) {
          this.api
            .update(data, result)
            .pipe(takeUntil(this.dataUpdateSubs$))
            .subscribe({
              next: () => {
                this.helpers.toast("success", "Data berhasil diubah");
                this.api
                  .getById(this.segmentData.id)
                  .pipe()
                  .subscribe({
                    next: ({ data }) => {
                      this.segmenLevel = data.user_level;
                      this.segmenType = data.user_type;
                    },
                  });
              },
              error: () => {
                this.helpers.toast("error", "Data gagal diubah");
              },
            });
        }
      },
      (reason) => {}
    );
  }

  fetchImageAndDisplay() {
    let imageUrl = this.abs_pathUrl;

    imageUrl = imageUrl.replace(/^https?:\/\/[^\/]+/, "");

    this.getBase64ImageFromURL(imageUrl).subscribe(
      (base64data: string) => {
        const mimeType = this.getMimeTypeFromUrl(imageUrl);
        this.base64Image = `data:${mimeType};base64,${base64data}`;
        const file = this.base64ToFile(
          base64data,
          mimeType,
          `image.${mimeType.split("/")[1]}`
        );
        this.sendImageToEndpoint(file);
      },
      (error) => {
        console.error("Error fetching image:", error);
      }
    );
  }

  base64ToFile(base64: string, mimeType: string, fileName: string): File {
    const byteString = atob(base64);
    const ab = new ArrayBuffer(byteString.length);
    const ia = new Uint8Array(ab);
    for (let i = 0; i < byteString.length; i++) {
      ia[i] = byteString.charCodeAt(i);
    }
    const blob = new Blob([ab], { type: mimeType });
    return new File([blob], fileName, {
      type: mimeType,
      lastModified: Date.now(),
    });
  }

  getMimeTypeFromUrl(url: string): string {
    const extension = url.split(".").pop()?.toLowerCase();
    return extension === "png" ? "image/png" : "image/jpeg";
  }

  getBase64ImageFromURL(url: string): Observable<string> {
    return new Observable<string>((observer) => {
      const img = new Image();
      img.crossOrigin = "Anonymous";
      img.src = url;

      img.onload = () => {
        const canvas = document.createElement("canvas");
        canvas.width = img.width;
        canvas.height = img.height;
        const ctx = canvas.getContext("2d");

        if (ctx) {
          ctx.drawImage(img, 0, 0);
          const mimeType = this.getMimeTypeFromUrl(url);
          const dataURL = canvas
            .toDataURL(mimeType)
            .replace(/^data:image\/(png|jpeg);base64,/, "");
          observer.next(dataURL);
          observer.complete();
        } else {
          observer.error("Unable to get 2D context");
        }
      };

      img.onerror = (err) => observer.error(err);
    });
  }

  predict_road: string = "";
  type_predict: string = "";
  level_predict: string = "";

  onFileSelected(event: any) {
    const file: File = event.target.files[0]; // Mengambil file yang dipilih dari input
    if (file) {
      this.sendImageToEndpoint(file); // Mengirim file ke fungsi sendImageToEndpoint
    }
  }

  sendImageToEndpoint(image: Blob) {
    this.isLoading = true;
    this.showRecommend = false;
    const api = "https://api-model.roadreport.id//predict-road";

    const form = new FormData();
    form.append("image", image);

    this.http.post<PredictRoad>(api, form).subscribe(
      (res) => {
        this.predict_road = res.predicted_label;

        const splitWords = this.predict_road.split(" ");
        if (splitWords.length === 2) {
          this.type_predict = splitWords[0];
          this.level_predict = splitWords[1];
        }

        this.isLoading = false;
        this.showRecommend = true;
      },

      (error) => {}
    );
  }

  changeDetailBasedOnRecommendation() {
    if (this.segmentData && this.segmentData.photos) {
      let absPaths = this.segmentData.photos.map(
        (photo: any) => photo.abs_path
      );
    }

    this.api
      .update(this.segmentData.id, {
        user_type: this.type_predict,
        user_level: this.level_predict,
      })

      .pipe(takeUntil(this.dataUpdateSubs$))
      .subscribe({
        next: () => {
          this.api
            .getById(this.segmentData.id)
            .pipe()
            .subscribe({
              next: ({ data }) => {
                this.segmenLevel = data.user_level;
                this.segmenType = data.user_type;
              },
            });
          this.helpers.toast("success", "Data berhasil diubah");
        },
        error: () => {
          this.helpers.toast("error", "Data gagal diubah");
        },
      });
  }

  onDetail(data: any): void {
    const modalRef = this.modal.open(LightboxComponent);
    modalRef.componentInstance.data = data;
  }

  isPNGL(): boolean {
    const decodedToken = this.auth.getLoggedUser();
    if (decodedToken) {
      const userRole = decodedToken.role.code;

      return userRole === "SADM";
    } else {
      return false;
    }
  }

  parsing(text: any) {
    const coordinates = JSON.parse(text);
    return coordinates.reverse().join(", ");
  }
}
