import { Component, OnInit } from "@angular/core";
import { RouterLink, RouterModule } from "@angular/router";
import { formatDate } from "@angular/common";
import {
  DateAdapter,
  MAT_DATE_FORMATS,
  NativeDateAdapter,
} from "@angular/material/core";
import { TranslateModule, TranslateService } from "@ngx-translate/core";
import { CommonModule } from "@angular/common";
import { MatIconModule } from "@angular/material/icon";
import { MatOptionModule } from "@angular/material/core";
import { MatAutocompleteModule } from "@angular/material/autocomplete";
import { MatFormFieldModule } from "@angular/material/form-field";
import { MatDatepickerModule } from "@angular/material/datepicker";
import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
import { MatInputModule } from "@angular/material/input";
import { MatButtonModule } from "@angular/material/button";

import { TunnelResp } from "../../models/tunnel";

import { JumpTypeResp } from "../../models/jumpType";
import { TunnelService } from "../../services/tunnel.service";
import { ServiceComm } from "../../services/service-comm.service";
import { TunnelFlightService } from "../../services/tunnel-flight.service";
import { JumpTypeService } from "../../services/jump-type.service";
import { DateService } from "../../services/date.service";

export const PICK_FORMATS = {
  parse: { dateInput: "yy MM dd" },
  display: {
    dateInput: "yyyy-MM-dd",
    monthYearLabel: "yyyy MMM",
    dateA11yLabel: "yyyy MM dd",
    monthYearA11yLabel: "yyyy MMMM",
  },
};
class PickDateAdapter extends NativeDateAdapter {
  override format(date: Date, displayFormat: Object): string {
    return formatDate(date, displayFormat.toString(), "en");
  }
}

@Component({
  selector: "app-new-tunnel-flight",
  templateUrl: "./new-tunnel-flight.component.html",
  styleUrls: ["./new-tunnel-flight.component.css"],
  providers: [
    { provide: DateAdapter, useClass: PickDateAdapter },
    { provide: MAT_DATE_FORMATS, useValue: PICK_FORMATS },
  ],
  imports: [
    TranslateModule,
    CommonModule,
    RouterModule,
    RouterLink,
    FormsModule,
    MatFormFieldModule,
    ReactiveFormsModule,
    MatAutocompleteModule,
    MatInputModule,
    MatButtonModule,
    MatIconModule,
    MatFormFieldModule,
    MatOptionModule,
    MatDatepickerModule,
    MatProgressSpinnerModule,
  ],
})
export class NewTunnelFlightComponent implements OnInit {
  public flightDate: Date;
  public minutesOfFlight: number;
  public selectedTunnel: TunnelResp;
  public selectedJumpType: JumpTypeResp;
  public listOfTunnel: Array<TunnelResp>;
  public listOfFilteredTunnel: Array<TunnelResp>;
  public resetForm: boolean;
  public comments: string;
  private countDatasLoaded: number;
  private pendingAddRequest: boolean;
  public listOfJumpType: Array<JumpTypeResp>;
  public maxDate: Date;

  constructor(
    private serviceComm: ServiceComm,
    private serviceTunnel: TunnelService,
    private serviceTunnelFlight: TunnelFlightService,
    private serviceJumpType: JumpTypeService,
    private translateService: TranslateService,
    private dateService: DateService
  ) {}

  ngOnInit() {
    this.serviceComm.forceTranslateTitle.subscribe((data) => {
      if (data === true) {
        this.updateTitle();
      }
    });
    this.updateTitle();

    this.maxDate = this.dateService.addDays(new Date(), 1);
    this.countDatasLoaded = 0;
    this.pendingAddRequest = false;
    this.initForm();
    this.getListOfTunnels();
    this.getListOfJumpTypes();
  }

  public onFormSubmit() {
    this.pendingAddRequest = true;

    this.serviceTunnelFlight
      .addFlight(
        this.selectedTunnel.id,
        this.selectedJumpType.id,
        this.flightDate,
        this.minutesOfFlight,
        this.comments
      )
      .subscribe(() => {
        this.comments = undefined;

        if (this.resetForm === true) {
          this.initForm();
        }
        this.pendingAddRequest = false;
      });
  }

  public isValidatedForm(): boolean {
    return (
      this.selectedTunnel !== undefined &&
      this.selectedTunnel.id !== undefined &&
      this.minutesOfFlight !== undefined &&
      typeof this.minutesOfFlight === "number"
    );
  }

  private getListOfTunnels() {
    this.serviceTunnel.getListOfTunnels().subscribe((data) => {
      data.sort((a, b) => a.name.localeCompare(b.name));
      this.listOfTunnel = data;
      this.listOfFilteredTunnel = data;
      this.countDatasLoaded++;
    });
  }

  private getListOfJumpTypes() {
    this.serviceJumpType.getListOfJumpTypesForTunnel().subscribe((data) => {
      data.sort((a, b) => a.name.localeCompare(b.name));
      this.listOfJumpType = data;
      this.countDatasLoaded++;
    });
  }

  public notLoadingToDisplay(): boolean {
    return !(this.pendingAddRequest || this.countDatasLoaded !== 2);
  }

  private updateTitle() {
    this.translateService.get("NewTunnelFlight_Title").subscribe((data) => {
      this.serviceComm.updatedComponentTitle(data);
    });
  }

  private initForm() {
    this.flightDate = new Date();
    this.flightDate.setHours(0, 0, 0, 0);

    this.minutesOfFlight = 1;
    this.selectedTunnel = undefined;
    this.comments = undefined;
  }

  public resetTunnel() {
    this.selectedTunnel = undefined;
    this.onChangeTunnel("");
  }

  public onChangeTunnel(event: any) {
    let filterValue: string;

    if (event.id === undefined) {
      filterValue = event.toLowerCase();

      this.listOfFilteredTunnel = this.listOfTunnel;
      this.listOfFilteredTunnel = this.listOfFilteredTunnel.filter((option) =>
        option.name.toLowerCase().includes(filterValue)
      );
    }
  }

  public displayNameFn(data?: any): string | undefined {
    return data ? data.name : undefined;
  }
}
