import { Component, OnInit } from "@angular/core";
import { formatDate } from '@angular/common';
import { DateAdapter, MAT_DATE_FORMATS, NativeDateAdapter } from "@angular/material/core";

import { JumpTypeResp } from "../../models/jumpType";
import { AircraftResp } from "../../models/aircraft";
import { DropZoneResp } from "../../models/dropzone";
import { GearResp } from "../../models/gear";

import { DateService } from "../../services/date.service";
import { ServiceComm } from "../../services/service-comm.service";
import { DropzoneService } from "../../services/dropzone.service";
import { AircraftService } from "../../services/aircraft.service";
import { JumpService } from "../../services/jump.service";
import { JumpTypeService } from "../../services/jump-type.service";
import { GearService } from "../../services/gear.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 {
  format(date: Date, displayFormat: Object): string {
      return formatDate(date, displayFormat.toString(), "en");
  }
}

@Component({
  selector: "app-new-jump",
  templateUrl: "./new-jump.component.html",
  styleUrls: ["./new-jump.component.css"],
  providers: [
    { provide: DateAdapter, useClass: PickDateAdapter },
    { provide: MAT_DATE_FORMATS, useValue: PICK_FORMATS }
  ]
})
export class NewJumpComponent implements OnInit {
  public beginDate: Date;
  public endDate: Date;
  public exitAltitude: number;
  public deployAltitude: number;
  public countOfJumps: number;
  public selectedDz: DropZoneResp;
  public selectedGear: GearResp;
  public selectedAircraft: AircraftResp;
  public selectedJumpType: JumpTypeResp;
  public withCutaway: boolean;
  public isSpecial: boolean;
  public listOfJumpType: Array<JumpTypeResp>;
  public listOfAircraft: Array<AircraftResp>;
  public listOfFilteredDropZone: Array<DropZoneResp>;
  public listOfGear: Array<GearResp>;
  public comments: string;
  public resetForm: boolean;
  private countDatasLoaded: number;
  private pendingAddRequest: boolean;
  private listOfDropZone: Array<DropZoneResp>;

  constructor(private serviceComm: ServiceComm,
              private serviceJump: JumpService,
              private serviceJumpType: JumpTypeService,
              private serviceAircraft: AircraftService,
              private serviceDropzone: DropzoneService,
              private serviceGear: GearService,
              private dateService: DateService) {}

  ngOnInit() {
    this.serviceComm.UpdatedComponentTitle("Add a new jump");
    this.pendingAddRequest = false;

    this.initForm();

    this.getListOfJumpTypes();
  }

  onFormSubmit() {
    this.pendingAddRequest = true;

    this.serviceJump.AddListOfJump(this.selectedJumpType.id,
                                   this.selectedAircraft.id,
                                   this.selectedDz.id,
                                   this.selectedGear.id,
                                   this.withCutaway === undefined ? false : this.withCutaway,
                                   this.beginDate,
                                   this.endDate,
                                   this.exitAltitude,
                                   this.deployAltitude,
                                   this.countOfJumps,
                                   this.comments,
                                   this.isSpecial === undefined ? false : this.isSpecial);

    setTimeout(() => {
      this.comments = undefined;
      this.withCutaway = false;
      this.isSpecial = false;

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

  public isValidatedForm(): boolean {
    return (this.selectedDz !== undefined &&
            this.selectedDz.id !== undefined &&
            this.selectedGear !== undefined &&
            this.selectedGear.id !== undefined &&
            this.selectedAircraft !== undefined &&
            this.selectedAircraft.id !== undefined &&
            this.selectedJumpType !== undefined &&
            this.selectedJumpType.id !== undefined &&
            this.exitAltitude !== undefined &&
            typeof this.exitAltitude === "number" &&
            this.deployAltitude !== undefined &&
            typeof this.deployAltitude === "number" &&
            this.countOfJumps !== undefined &&
            typeof this.countOfJumps === "number");
  }

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

      this.getListOfAircrafts();
      this.getListOfDropZones();
      this.getListOfGears();
    });
  }

  private getListOfAircrafts() {
    this.serviceAircraft.getListOfAircrafts(true).subscribe((data) => {
      data.sort((a, b) => a.name.localeCompare(b.name));
      this.listOfAircraft = data;
      this.countDatasLoaded++;
    });
  }

  private getListOfDropZones() {
    this.serviceDropzone.getListOfDropZones(true).subscribe((data) => {
      data.sort((a, b) => (b.isFavorite ? 1 : 0) - (a.isFavorite ? 1 : 0) || a.name.localeCompare(b.name));
      this.listOfDropZone = data;
      this.listOfFilteredDropZone = data;
      this.countDatasLoaded++;
    });
  }

  private getListOfGears() {
    this.serviceGear.getListOfGears().subscribe((data) => {
      data.sort((a, b) => b.id - a.id);
      this.listOfGear = data;
      this.countDatasLoaded++;
    });
  }

  private initForm() {
    this.endDate = new Date();
    this.beginDate = this.dateService.AddDays(new Date(), -1);

    this.exitAltitude = 4000;
    this.deployAltitude = 1000;
    this.countOfJumps = 1;

    this.selectedDz = undefined;
    this.selectedGear = undefined;
    this.selectedAircraft = undefined;
    this.selectedJumpType = undefined;

    this.listOfFilteredDropZone = this.listOfDropZone;
    this.comments = undefined;

    this.withCutaway = false;
    this.isSpecial = false;
  }

  public displayFn(data?: JumpTypeResp): string | undefined {
    return data ? data.name : undefined;
  }

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

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

      this.listOfFilteredDropZone = this.listOfDropZone;
      this.listOfFilteredDropZone = this.listOfFilteredDropZone.filter((option) =>
        option.name.toLowerCase().includes(filterValue)
      );
    }
  }

  public onChangeBeginDate(event: any) {
    this.endDate = event;
  }

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

  public resetDz() {
    this.selectedDz = undefined;
    this.onChangeDz('');
  }
}
