import { action, computed, extendObservable, observable } from 'mobx';
import moment from 'moment';
import sortBy from 'lodash.sortby';

export default class AirlinesDomestic {

  @observable lists = [];
  @observable isLoading = false;
  @observable isLoadingSearch = false;
  @observable isReturn = 0;
  @observable serviceCharge = 0;
  @observable queries = {
    fromcity: 'CGK',
    tocity: 'SUB',
    departuredate: moment().add(1,'day').format("DD-MMM-YYYY"),
    arrivaldate: "",
    listairlines: "GA",
    cabin: '',
    adult: 1,
    child: 0,
    infant: 0,
    cheapestclass: false,
    results: {
      departure: [],
      returning: []
    }
  };
  @observable sortBy = 'price_low_to_high';
  @observable stopFilter = 'any';

  @action
  setSortBy(sortBy) {
    this.sortBy = sortBy;
  }
  @action
  setStopFilter(filter) {
    this.stopFilter = filter;
  }

  @computed
  get departureLists() {
    let result = [];
    if(this.sortBy === 'price_low_to_high') {
      result =  sortBy(this.queries.results.departure.slice(), (it => it.price_range_start));
    } else if (this.sortBy === 'price_high_to_low') {
      result =  sortBy(this.queries.results.departure.slice(), (it => it.price_range_start)).reverse();
    } else if (this.sortBy === 'duration') {

      result =  sortBy(this.queries.results.departure.slice(), (it => {
        return parseInt(it.durationhour) * 60 + parseInt(it.durationminute);
      }));

    } else if (this.sortBy === 'departure_time') {
      result =  sortBy(this.queries.results.departure.slice(), (it => {
        let [hour,minute] = it.departtime.split(':');
        return parseInt(hour) * 60 + parseInt(minute);
      }));
    }

    if(this.stopFilter === 'no_stop') {
      result = result.filter(it => it.no_of_flight === 1);
    } else if (this.stopFilter === 'one_or_less') {
      result = result.filter(it => it.no_of_flight <= 2);
    } else if (this.stopFilter === 'two_or_less') {
      result = result.filter(it => it.no_of_flight <= 3);
    }
    result = result.filter(it => it.price_range_start !== 0);

    if(this.priceMaxFilter !== 0) {
      result = result.filter(it => it.price_range_start <= this.priceMaxFilter);
    }

    result = result.filter(it => {
      let returning = false;
      this.selectedAirlinesFilter.forEach(airlineName => {
        if(it.airline.includes(airlineName)) {
          returning = true;
        }
      });
      return returning;
    });

    return result;
  }

  @computed
  get priceMin() {
    if(this.queries.results.departure.slice().length === 0) {
      return 0;
    }
    return Math.min(...this.queries.results.departure.slice().map(it => it.price_range_start));
  }
  @computed
  get priceMax() {
    if(this.queries.results.departure.slice().length === 0) {
      return 0;
    }
    return Math.max(...this.queries.results.departure.slice().map(it => it.price_range_start));
  }

  @observable priceMaxFilter = 0;

  @action
  setPriceMaxFilter(value) {
    this.priceMaxFilter = value;
  }

  @computed
  get airlineFilterList() {
    return this.queries.results.departure.slice().map(it => it.airline.split(',')[0]).filter((value, index, self) => {
      return self.indexOf(value) === index;
    });
  }

  @observable selectedAirlinesFilter = [];

  @action
  setSelectedAirlinesFilter(airlines) {
    this.selectedAirlinesFilter = airlines;
  }

  @computed
  get isSelectedAirlinesFilterIndeterminate() {
    if(this.selectedAirlinesFilter.length === 0) {
      return false;
    }
    if(this.selectedAirlinesFilter.length === this.airlineFilterList.length) {
      return false;
    }
    return true;
  }

  @computed
  get isAllSelectedAirlinesChecked() {
    return this.selectedAirlinesFilter.length === this.airlineFilterList.length;
  }


  @observable flightCodeClasses = [];

  @observable selectedAirline = 'GA';

  // @observable selectedDepartureFlight = {
  //   airline: "",
  //   airlinecode: "",
  //   arrivaldate: "",
  //   arrivetime: "",
  //   departdate: "",
  //   departtime: "",
  //   flightno: "",
  //   flights: [],
  //   fromcity: "",
  //   tocity: ""
  // };

  // @observable selectedDepartureFlight = {
  //   'flightno': 'QG 815',
  //   'airline': 'Citilink',
  //   'no_of_flight': 1,
  //   'airlinecode': 'QG',
  //   'departdate': '09-Dec-2017',
  //   'arrivaldate': '09-Dec-2017',
  //   'fromcity': 'CGK',
  //   'tocity': 'SUB',
  //   'fromcity_airport': 'Soekarno Hatta',
  //   'tocity_airport': 'Juanda',
  //   'fromcity_long': 'Surabaya',
  //   'tocity_long': 'Surabaya',
  //   'departtime': '04:10',
  //   'arrivetime': '05:40',
  //   'durationhour': 1,
  //   'durationminute': 30,
  //   'flights': [
  //     {
  //       'flightno': 'QG 815',
  //       'airline': 'Citilink',
  //       'airlinecode': 'QG',
  //       'departdate': '09-Dec-2017',
  //       'arrivaldate': '09-Dec-2017',
  //       'fromcity': 'CGK',
  //       'tocity': 'SUB',
  //       'fromcity_airport': 'Soekarno Hatta',
  //       'tocity_airport': 'Juanda',
  //       'fromcity_long': 'Jakarta',
  //       'tocity_long': 'Surabaya',
  //       'departtime': '04:10',
  //       'arrivetime': '05:40',
  //       'durationhour': 1,
  //       'durationminute': 30,
  //       selected_class: 'K',
  //       'classes': [
  //         {
  //           'code': 'K',
  //           'availcode': 5,
  //           'fare': 781000,
  //           'currency': 'IDR',
  //           'pairid': '',
  //           'baggagekilos': 15,
  //           'cabin': 'ECONOMY',
  //         },
  //         {
  //           'code': 'H',
  //           'availcode': 5,
  //           'fare': 841500,
  //           'currency': 'IDR',
  //           'pairid': '',
  //           'baggagekilos': 15,
  //           'cabin': 'ECONOMY',
  //         },
  //         {
  //           'code': 'G',
  //           'availcode': 5,
  //           'fare': 902000,
  //           'currency': 'IDR',
  //           'pairid': '',
  //           'baggagekilos': 15,
  //           'cabin': 'ECONOMY',
  //         },
  //         {
  //           'code': 'F',
  //           'availcode': 5,
  //           'fare': 974600,
  //           'currency': 'IDR',
  //           'pairid': '',
  //           'baggagekilos': 15,
  //           'cabin': 'ECONOMY',
  //         },
  //         {
  //           'code': 'E',
  //           'availcode': 5,
  //           'fare': 1059300,
  //           'currency': 'IDR',
  //           'pairid': '',
  //           'baggagekilos': 15,
  //           'cabin': 'ECONOMY',
  //         },
  //         {
  //           'code': 'D',
  //           'availcode': 5,
  //           'fare': 1119800,
  //           'currency': 'IDR',
  //           'pairid': '',
  //           'baggagekilos': 15,
  //           'cabin': 'ECONOMY',
  //         },
  //         {
  //           'code': 'B',
  //           'availcode': 5,
  //           'fare': 1162150,
  //           'currency': 'IDR',
  //           'pairid': '',
  //           'baggagekilos': 15,
  //           'cabin': 'ECONOMY',
  //         },
  //         {
  //           'code': 'A',
  //           'availcode': 5,
  //           'fare': 1336500,
  //           'currency': 'IDR',
  //           'pairid': '',
  //           'baggagekilos': 15,
  //           'cabin': 'ECONOMY',
  //         }],
  //     }],
  //   'price_range_start': 781000,
  //   'price_range_end': 1336500,
  // };

  @observable selectedDepartureFlight = {
    'flightno': '',
    'airline': '',
    'no_of_flight': '',
    'airlinecode': '',
    'departdate': '',
    'arrivaldate': '',
    'fromcity': '',
    'tocity': '',
    'fromcity_airport': '',
    'tocity_airport': '',
    'fromcity_long': '',
    'tocity_long': '',
    'departtime': '',
    'arrivetime': '',
    'durationhour': 0,
    'durationminute': 0,
    'flights': [],
    'price_range_start': 0,
    'price_range_end': 0,
  };
  @observable selectedReturningFlight = {
    'flightno': '',
    'airline': '',
    'no_of_flight': '',
    'airlinecode': '',
    'departdate': '',
    'arrivaldate': '',
    'fromcity': '',
    'tocity': '',
    'fromcity_airport': '',
    'tocity_airport': '',
    'fromcity_long': '',
    'tocity_long': '',
    'departtime': '',
    'arrivetime': '',
    'durationhour': 0,
    'durationminute': 0,
    'flights': [],
    'price_range_start': 0,
    'price_range_end': 0,
  };

  @observable passengerData = [{
    key: 'adult_0',
    index: 0,
    type: 'adult',
    data: {
      'id': 'c5065ae1-c313-41c0-9c90-e44d749d56f9',
      'agent_id': '54e9a8c4-d0c9-4403-ad64-aef00a4cc889',
      'name': 'Hasta Ragil',
      'date_of_birth': '1997-12-02T17:00:00.000Z',
      'gender': 'Man',
      'address': '1969892',
      'occupation': '1969892',
      'passport_number': '123',
      'created_at': '2017-12-03T18:05:03.400Z',
      'updated_at': '2017-12-03T18:05:03.401Z',
      'deleted_at': null,
      'email': 'hasta.ragil@gmail.com',
      'birth_place': '1969892',
      'phone': '1969892',
      'handphone': '1969892',
      'martial_status': 'Married',
      'id_tax_number': '123',
      'id_type': 'Resident ID Card',
      'id_number': '322',
      'id_photo': '/api/v1/upload/e7190139-3a1e-4a76-8ba8-09935ac94614.png',
      'passport_photo': '/api/v1/upload/9d0ab0c9-53f5-4815-8913-b98a155e3ccb.png',
      'search_text': 'Hasta Ragil - 322',
    },
  }];

  @observable picInfo = {
    'id': 'c5065ae1-c313-41c0-9c90-e44d749d56f9',
    'agent_id': '54e9a8c4-d0c9-4403-ad64-aef00a4cc889',
    'name': 'Hasta Ragil',
    'date_of_birth': '1997-12-02T17:00:00.000Z',
    'gender': 'Man',
    'address': '1969892',
    'occupation': '1969892',
    'passport_number': '123',
    'created_at': '2017-12-03T18:05:03.400Z',
    'updated_at': '2017-12-03T18:05:03.401Z',
    'deleted_at': null,
    'email': 'hasta.ragil@gmail.com',
    'birth_place': '1969892',
    'phone': '1969892',
    'handphone': '1969892',
    'martial_status': 'Married',
    'id_tax_number': '123',
    'id_type': 'Resident ID Card',
    'id_number': '322',
    'id_photo': '/api/v1/upload/e7190139-3a1e-4a76-8ba8-09935ac94614.png',
    'passport_photo': '/api/v1/upload/9d0ab0c9-53f5-4815-8913-b98a155e3ccb.png',
    'search_text': 'Hasta Ragil - 322',
  };

  constructor(context) {
    this.http = context.http;
    this.context = context;
  }

  @action
  setServiceCharge(value) {
    this.serviceCharge = value;
  }

  @action
  setPicInfo(info) {
    this.picInfo = info;
  }

  @action
  setSelectedAirline(item) {
    this.selectedAirline = item;
  }

  @action
  setDepartureAirport(item) {
    this.queries.fromcity = item;
  }

  @action
  setArrivalAirport(item) {
    this.queries.tocity = item;
  }

  @action
  setDepartureDate(item) {
    this.queries.departuredate = item;
  }

  @action
  setArrivalDate(item) {
    this.queries.arrivaldate = item;
  }

  @action
  setCabin(item) {
    this.queries.cabin = item;
  }

  @action
  setAdult(item) {
    this.queries.adult = item;
  }

  @action
  setChild(item) {
    this.queries.child = item;
  }

  @action
  setInfant(item) {
    this.queries.infant = item;
  }

  @action
  setSelectedClassForFlightCode(flightCode, selectedClass, departureOrReturning = 'departure') {
    if(departureOrReturning === 'departure') {
      let flightIndex = this.selectedDepartureFlight.flights.findIndex(it => it.flightno === flightCode);
      this.selectedDepartureFlight.flights[flightIndex].selected_class = selectedClass;
      this.selectedDepartureFlight.flights = this.selectedDepartureFlight.flights.map(it => it);
    } else {
      let flightIndex = this.selectedReturningFlight.flights.findIndex(it => it.flightno === flightCode);
      this.selectedReturningFlight.flights[flightIndex].selected_class = selectedClass;
      this.selectedReturningFlight.flights = this.selectedReturningFlight.flights.map(it => it);
    }
  }

  @computed
  get totalPassenger() {
    return (+this.queries.adult) + (+this.queries.child) + (+this.queries.infant);
  }

  @action
  getAllAirlines() {
    this.isLoading = true;
    return this.http.get(`master/airlines`).then(res => {
      this.lists = res;
      this.isLoading = false;
    });
  }

  @action
  setReturn() {
    this.isReturn = 1;
  }

  @action
  setOneway() {
    this.isReturn = 0;
  }

  @action
  searchAirlines() {
    let passenger = [];
    for (let x = 0; x < this.queries.adult; x++) {
      passenger.push({
        key: 'adult_' + x,
        index: x,
        type: 'adult',
        data: {}
      });
    }
    for (let x = 0; x < this.queries.child; x++) {
      passenger.push({
        key: 'child_' + x,
        index: x,
        type: 'child',
        data: {}
      });
    }
    for (let x = 0; x < this.queries.infant; x++) {
      passenger.push({
        key: 'infant_' + x,
        index: x,
        type: 'infant',
        data: {}
      });
    }

    this.passengerData = passenger;
    // console.log(this.passengerData, 'this.passengerData');


    this.isLoadingSearch = true;
    let fromCity = (this.queries.fromcity) ? `fromcity=${this.queries.fromcity}` : "";
    let toCity = (this.queries.tocity) ? `&tocity=${this.queries.tocity}` : "";
    let departDate = (this.queries.departuredate) ? `&departdate=${this.queries.departuredate}` : "";
    let returnDate = (this.queries.arrivaldate) ? `&returndate=${this.queries.arrivaldate}` : "";
    let airlines = (this.selectedAirline) ? `&listairline=${this.selectedAirline}` : "";
    let adult = (this.queries.adult) ? `&adult=${this.queries.adult}` : "";
    let child = (this.queries.child) ? `&child=${this.queries.child}` : "";
    let infant = (this.queries.infant) ? `&infant=${this.queries.infant}` : "";
    let uri = `vendor/airlines/search_new?${fromCity}${toCity}${departDate}${returnDate}${airlines}${adult}${child}${infant}`;
    // console.log(uri, "uri");

    this.queries.results = {
      departure: []
    };
    return this.http.get(uri).then(res => {
      // console.log(this.queries, res, "results");
      this.queries.results = res;
      this.priceMaxFilter = this.priceMax;
      this.selectedAirlinesFilter = this.airlineFilterList.slice();
      this.isLoadingSearch = false;
    });
  }

  @action
  setDepartureItem(item) {
    // console.log(JSON.stringify(item));
    item.flights = item.flights.map(flight => {
      let lowestClass = flight.classes.reduce((currentLowest, current) => {
        if(currentLowest.fare > current.fare) {
          return current;
        }
        return currentLowest;
      }, {fare: Infinity});

      flight.selected_class = lowestClass.code;
      return flight;
    });

    this.selectedDepartureFlight = item;
  }

  @action
  setReturningItem(item) {
    // console.log(JSON.stringify(item));
    item.flights = item.flights.map(flight => {
      let lowestClass = flight.classes.reduce((currentLowest, current) => {
        if(currentLowest.fare > current.fare) {
          return current;
        }
        return currentLowest;
      }, {fare: Infinity});

      flight.selected_class = lowestClass.code;
      return flight;
    });

    this.selectedReturningFlight = item;
  }

  @action
  setPassengerData(type, index, data) {
    let passengerIndex = this.passengerData.findIndex(it => it.key === `${type}_${index}`);
    if(passengerIndex === -1) {
      this.passengerData.push({
        type: type,
        key: type + '_' + index,
        index: index,
        data: data
      });
    } else {
      this.passengerData[passengerIndex].data = data;
    }
  }

  @computed
  get totalForAdult() {
    let totalPerAdult = this.selectedDepartureFlight.flights.map(flight => {
      if(!flight.selected_class) {
        return 0;
      }

      return flight.classes.find(classes => classes.code === flight.selected_class).fare;
    }).reduce((total, curr) => total + curr, 0);

    let totalPerAdultReturning = this.selectedReturningFlight.flights.map(flight => {
      if(!flight.selected_class) {
        return 0;
      }

      return flight.classes.find(classes => classes.code === flight.selected_class).fare;
    }).reduce((total, curr) => total + curr, 0);
    return this.queries.adult * (totalPerAdult + totalPerAdultReturning);
  }
  @computed
  get totalForChild() {
    let totalPerAdult = this.selectedDepartureFlight.flights.map(flight => {
      if(!flight.selected_class) {
        return 0;
      }

      return flight.classes.find(classes => classes.code === flight.selected_class).fare;
    }).reduce((total, curr) => total + curr, 0);

    let totalPerAdultReturning = this.selectedReturningFlight.flights.map(flight => {
      if(!flight.selected_class) {
        return 0;
      }

      return flight.classes.find(classes => classes.code === flight.selected_class).fare;
    }).reduce((total, curr) => total + curr, 0);
    return this.queries.child * (totalPerAdult + totalPerAdultReturning);
  }
  @computed
  get totalForInfant() {
    let totalPerAdult = this.selectedDepartureFlight.flights.map(flight => {
      if(!flight.selected_class) {
        return 0;
      }

      return flight.classes.find(classes => classes.code === flight.selected_class).fare;
    }).reduce((total, curr) => total + curr, 0);

    let totalPerAdultReturning = this.selectedReturningFlight.flights.map(flight => {
      if(!flight.selected_class) {
        return 0;
      }

      return flight.classes.find(classes => classes.code === flight.selected_class).fare;
    }).reduce((total, curr) => total + curr, 0);
    return this.queries.infant * (totalPerAdult + totalPerAdultReturning);
  }

  @computed
  get totalForAll() {
    return this.totalForChild + this.totalForAdult + this.totalForInfant;
  }

  @computed
  get totalForAllWithServiceCharge() {
    return this.totalForAll + this.serviceCharge;
  }

  @action
  book() {
    let departureFlights = {
      airlinecode: this.selectedDepartureFlight.airlinecode,
      tripdate: this.selectedDepartureFlight.tripdate,
      departdate: this.selectedDepartureFlight.departdate,
      flights: this.selectedDepartureFlight.flights.map(flight => {
        return ({
          flightno: flight.flightno,
          classcode: flight.selected_class,
          fromcity: flight.fromcity,
          tocity: flight.tocity,
          departdate: flight.departdate,
          departtime: flight.departtime,
          arrivetime: flight.arrivetime
        })
      })
    };
    
    let returningFlight = {
    };

    if(this.isReturn) {
      returningFlight = {
        airlinecode: this.selectedReturningFlight.airlinecode,
        tripdate: this.selectedReturningFlight.tripdate,
        departdate: this.selectedReturningFlight.departdate,
        flights: this.selectedReturningFlight.flights.map(flight => {
          return ({
            flightno: flight.flightno,
            classcode: flight.selected_class,
            fromcity: flight.fromcity,
            tocity: flight.tocity,
            departdate: flight.departdate,
            departtime: flight.departtime,
            arrivetime: flight.arrivetime
          })
        })
      }
    }

    let paxes = this.passengerData.map(passenger => {
      let splitted = passenger.data.name.split(' ');
      let firstname = '';
      let lastname = '';
      if(splitted.length <= 1) {
        firstname = splitted[0];
        lastname = splitted[1];
      } else {
        lastname = splitted.pop();
        firstname = splitted.join(' ');
      }
      return {
        title: 'MR',
        customer_id: passenger,
        firstname: firstname,
        lastname: lastname,
        type: passenger.type.toUpperCase(),
        id_number: passenger.data.id_number
      }
    });

    let pic = this.picInfo;

    this.context.globalUI.openLoading();
    
    let postData = {
      departure: departureFlights,
      pax: paxes,
      pic,
      request_data: {
        selectedDepartureFlight: this.selectedDepartureFlight,
        selectedReturningFlight: this.selectedReturningFlight
      }
    };

    if(this.isReturn){
      postData.returning = returningFlight;
    }

    return this.http.post('vendor/airlines/book', postData).then((data) => {
      this.context.globalUI.closeLoading();
      return data;
    });
  }
}
