import { Location } from '@angular/common';

import { MatSelectionList, MatSelectionListChange } from '@angular/material';

import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';

import { Directive, Input, NgModule } from '@angular/core';

import { CreateKnokStepService, CreateKnokStepServiceData } from '../wizardstep.service';

import { Observable } from 'rxjs/Observable';

import { Subscription } from 'rxjs/Subscription';

import { startWith } from 'rxjs/operators/startWith';

import { map } from 'rxjs/operators/map';

import { slideToLeft, StepBaseComponent } from '../wizard.basestep.component';
// import { StepOneModel } from './wizardstepone.model';

import { FormControl, FormGroup, Validators } from '@angular/forms';

import { CurrencyService, ExchangeService, ICurrencies, ICurrency, ICurrencyPair, IExchange, IExchanges, IKnok } from '../../../shared';

import 'web-animations-js';

abstract class Evt extends EventTarget {
  abstract get value(): string;
}

@Component({
  selector: 'knk-step-one',
  templateUrl: './wizardstepone.component.html',
  styleUrls: ['./wizardstepone.component.scss'],
  providers: [
    {provide: CreateKnokStepService, useExisting: StepOneComponent} // forwardRef(() => StepOneComponent)
  ],
  animations: [slideToLeft()]
})
export class StepOneComponent extends StepBaseComponent implements OnInit, OnDestroy {
  @Input('knok') knok: IKnok;
  @ViewChild(MatSelectionList) exchangesCtrl: MatSelectionList;
  exchanges: IExchange[];
  avaliableExchanges: Array<{ name: string, value: number, disabled: boolean }> = [];
  exchangeChange: Subscription;
  currencies: ICurrency[];
  isEdit: boolean = false;

  currencyCtrl: FormControl;
  tradingPairsCtrl: FormControl;
  exchangeCtrl: FormControl;

  tradingPairs: Array<{ value: string, name: string }>;

  currency: string = null;
  nonBaseCurrency: string = null;
  tradingPair: string = null;
  exchangeId: number;
  displayPair: string;
  displayExchange: string;
  displayCurrency: string;
  precision: number = 2;
  recent: Array<{ item: { asset: string, pair: string, time: Date, id: number } }> = [];

  constructor(private currencyService: CurrencyService,
              private exchangeService: ExchangeService) {
    super(); // new StepOneModel());
    // const model: StepOneModel = this.stepModel as StepOneModel;
    this.currStepName = ['Currency Pair'];
  }

  loadRecentKnok(evt: { asset: string, pair: string, time: Date, id: number }): void {
    this.currencyCtrl.setValue(evt.asset);
    const pair: string = evt.pair.replace('/', '|');
    this.tradingPairsCtrl.setValue(pair);
    let traidingPair: string[] = pair.split('|');
    if (traidingPair && traidingPair.length === 2) {
      this.knok.currency1 = traidingPair[0];
      this.knok.currency2 = traidingPair[1];
      this.currencyService.getCurrencies(null).subscribe(
        (val: ICurrencies): void => {
          let selectedCurrency: ICurrency[] = val.items.filter(f => f.code === traidingPair[1]);
          if (selectedCurrency) {
            this.precision = selectedCurrency[0].decimals;
          }
        }
      );
      this.fillExchanges(traidingPair);
    }

    this.knok.entryPriceFrom = 1.11;
    this.knok.entryPriceTo = 1.31;
    this.knok.exitPriceFrom = 1.4;
    this.knok.exitPriceTo = 1.5;
    this.knok.stopLoss = 1;
    this.knok.duration = 2;
  }

  ngOnInit(): void {
    super.ngOnInit();

    this.currencyCtrl = new FormControl('', {validators: Validators.required});
    this.currencyCtrl.valueChanges.subscribe(x => {
      // model
      this.currency = x;
      let selectedCurrency: ICurrency[];
      if (Array.isArray(this.currencies)) {
        selectedCurrency = this.currencies.filter((value: ICurrency) => x === value.longName);
      }
      if (selectedCurrency && selectedCurrency.length > 0) {
        // model.displayCurrency = selectedCurrency[0].currencyName.toUpperCase();
        this.fillTradingPairs();
        this.knok.currency1 = null;
        this.knok.currency2 = null;
        this.fillExchanges(null);
        this.isEdit = true;
      }
    });
    this.stepForm.addControl('currency', this.currencyCtrl);

    this.tradingPairsCtrl = new FormControl('', {validators: Validators.required});
    this.tradingPairsCtrl.valueChanges.subscribe(x => {
      // model
      this.tradingPair = x;
      let traidingPair: string[] = x.split('|');
      if (traidingPair && traidingPair.length === 2) {
        this.knok.currency1 = traidingPair[0];
        this.knok.currency2 = traidingPair[1];
        this.nonBaseCurrency = traidingPair[1];
        // let selectedExchange: IExchange[] = this.exchanges.filter((value: IExchange) => value.exchangeId === model.exchangeId);
        // if (selectedExchange.length > 0) {
        //     let selectedExchangePair: ICurrencyPair[] = selectedExchange[0].currencyPairs.filter((value: ICurrencyPair) =>
        //         value.currency1 === traidingPair[0] && value.currency2 === traidingPair[1]);
        //     if (selectedExchangePair.length > 0) {
        //         model.displayCurrency = selectedExchangePair[0].currency;
        //     }
        // }
      }
    });
    this.stepForm.addControl('tradingPairs', this.tradingPairsCtrl);

    this.exchangeCtrl = new FormControl('', {validators: Validators.required});
    this.exchangeCtrl.valueChanges.subscribe((x: number[]) => {
      this.knok.exchangeId = x && x.length > 0 ? x[0] : null;
      if (Array.isArray(this.exchanges)) {
        let selectedExchange: IExchange[] = this.exchanges.filter((value: IExchange) => this.knok.exchangeId && value.exchangeId === this.knok.exchangeId);
        if (selectedExchange && selectedExchange.length > 0) {
          // model
          this.displayExchange = selectedExchange[0].exchangeName.toUpperCase();
          let selectedExchangePair: ICurrencyPair[] = selectedExchange[0].currencyPairs.filter((value: ICurrencyPair) =>
            value.currency1 === this.knok.currency1 && value.currency2 === this.knok.currency2);
          if (selectedExchangePair.length > 0) {
            // model
            this.displayCurrency = selectedExchangePair[0].currency;
            // model
            this.displayPair = selectedExchangePair[0].displayName; // model.tradingPair ? model.tradingPair.replace('|', ' / ') : '';
          }
        }
      }
    });
    this.stepForm.addControl('exchange', this.exchangeCtrl);

    this.stepModel = this.knok;
    this.exchangeChange = this.exchangesCtrl.selectionChange.subscribe((s: MatSelectionListChange) => {
      if (this.exchangesCtrl) {
        this.exchangesCtrl.deselectAll();
        s.option.selected = true;
      }
    });

    this.currencyService.getCurrencies(null).subscribe((currencies: ICurrencies) => {
      // if (currencies) {
      //     this.currencies = currencies.items;
      // } else {
      //     console.log('Currencies is not found');
      // }
      this.currencies = [];
      // this.exchangeService.Exchanges.subscribe((exchanges: IExchanges) => {
      //   if (exchanges) {
      //     exchanges.items.forEach((exchange: IExchange) => {
      //       exchange.currencyPairs.forEach((pair: ICurrencyPair) => {
      //         let selectedCurrency: ICurrency[] = currencies.items.filter((currency: ICurrency) => currency.code === pair.currency1);
      //         if (selectedCurrency.length > 0) {
      //           if (!this.currencies.find(val => val.code === selectedCurrency[0].code)) {
      //             this.currencies.push(selectedCurrency[0]);
      //             this.currencies.sort(
      //               (a: ICurrency, b: ICurrency) => {
      //                 if (a.longName < b.longName) {
      //                   return -1;
      //                 } else if (a.longName > b.longName) {
      //                   return 1;
      //                 } else {
      //                   return 0;
      //                 }
      //               }
      //             );
      //           }
      //         }
      //       });
      //     });
      //     this.exchanges = exchanges.items;
      //     this.fillExchanges(null);
      //   } else {
      //     console.log('Exchanges code is not found');
      //   }
      // });
    });

    this.recent.push({item: {asset: 'Bitcoin Cash', pair: 'BCH/BTC', time: new Date(), id: 1}});
    this.recent.push({item: {asset: 'Bitcoin Cash', pair: 'LTC/BTC', time: new Date(), id: 2}});
    this.recent.push({item: {asset: 'Bitcoin Cash', pair: 'CDT/LTC', time: new Date('1/10/2018'), id: 3}});
  }

  ngOnDestroy(): void {
    if (this.exchangeChange && typeof this.exchangeChange.unsubscribe === 'function') {
      this.exchangeChange.unsubscribe();
    }
  }

  changePair(event: Event): void {
    let evt: Evt = event.target as Evt;
    if (evt.value !== '') {
      const pair: string[] = evt.value.split('|');
      this.currencyService.getCurrencies(null).subscribe(
        (val: ICurrencies): void => {
          let selectedCurrency: ICurrency[] = val.items.filter(f => f.code === pair[1]);
          if (selectedCurrency) {
            // (this.stepModel as StepOneModel)
            this.precision = selectedCurrency[0].decimals;
          }
        }
      );
      this.fillExchanges(pair);
    }
  }

  isSelected(value: { name: string, value: number, disabled: boolean }): boolean {
    // const model: StepOneModel = (this.stepModel as StepOneModel);
    if (value && this.stepForm.controls.exchange && (!this.knok.exchangeId && !value.disabled)) {
      setTimeout(() => {
        this.stepForm.controls.exchange.setValue([value.value]);
      }, 10);
      return true;
    } else {
      return (this.knok.exchangeId && this.knok.exchangeId === value.value);
    }
  }

  isPairSelected(value: string): boolean {
    return value === this.tradingPair;
  }

  private fillTradingPairs(): void {
    let pairs: Array<{ value: string, name: string }> = [{value: '', name: '- select -'}];
    if (Array.isArray(this.currencies)) {
      const baseCurrency: ICurrency[] = this.currencies.filter((val: ICurrency) => val.longName === this.currencyCtrl.value);
      if (Array.isArray(this.exchanges)) {
        this.exchanges.forEach((exchange: IExchange) => {
          exchange.currencyPairs.forEach((pair: ICurrencyPair) => {
            if (baseCurrency[0].code === pair.currency1) {
              let item: { value: string, name: string } = {value: pair.currency1 + '|' + pair.currency2, name: pair.displayName};
              if (!pairs.find(val => val.value === item.value)) {
                pairs.push(item);
              }
            }
          });
        });
      }
      // const baseCurrency: ICurrency[] = this.currencies.filter((val: ICurrency) => val.longName === this.currencyCtrl.value);
      // if (baseCurrency && baseCurrency.length > 0) {
      //     const baseValue: ICurrency = baseCurrency[0];
      //     this.currencies.forEach((val: ICurrency): void => {
      //         if (val.code !== baseValue.code) {
      //             pairs.push({value: baseValue.code + '|' + val.code, name: baseValue.currencyName + ' / ' + val.currencyName});
      //         }
      //     });
      // }
    }
    this.tradingPairs = pairs.sort(
      (a, b) => {
        if (a.name < b.name) {
          return -1;
        } else if (a.name > b.name) {
          return 1;
        } else {
          return 0;
        }
      }
    );
  }

  private fillExchanges(pair: string[]): void {
    this.avaliableExchanges = [];
    if (Array.isArray(this.exchanges)) {
      this.exchanges.forEach((val: IExchange) => {
        this.avaliableExchanges.push({
          name: val.exchangeName, value: val.exchangeId,
          disabled: !pair || pair.length < 2 || val.currencyPairs.filter((exchangePair: ICurrencyPair) => exchangePair.currency1 === pair[0] && exchangePair.currency2 === pair[1]).length === 0
        });
      });
    }

    if (this.avaliableExchanges.length > 0 && !this.avaliableExchanges[0].disabled) {
      this.exchangeCtrl.setValue([this.avaliableExchanges[0].value]);
    } else {
      this.exchangeCtrl.setValue([]);
    }
  }
}
