import { AfterViewInit, Component, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output, QueryList, Renderer2, ViewChildren } from '@angular/core';
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
import { Store } from '@ngrx/store';
import { DialogContentBase, DialogRef } from '@progress/kendo-angular-dialog';
import { Observable, of, Subscription } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';
import { AuthService } from 'src/app/auth/services/auth.service';
import { CalculatePriceColor } from 'src/app/models/calculate-price-color.model';
import { ColorsTintometrico } from 'src/app/models/colors-tintometrico.model';
import { SaleProduct, Stock } from 'src/app/models/sale-product.model';
import { ProductService } from 'src/app/services/product.service';
import { ShoppingService } from 'src/app/services/shopping.service';
import { TintometricoService } from 'src/app/services/tintometrico.service';
import { AddItemAction } from '../../store/actions/shopping.action';
import { SaleState } from '../../store/models/sale-state.model';
import { ShoppingItem } from '../../store/models/shopping-item';

@Component({
  selector: 'app-tintometrico-modal',
  templateUrl: './tintometrico-modal.component.html',
  styleUrls: ['./tintometrico-modal.component.scss',
  '../product-card/product-card.component.scss']
})

export class TintometricoModalComponent extends DialogContentBase implements OnInit, OnDestroy, AfterViewInit {
  @Input() product: SaleProduct;
  @Input() shoppingItem: ShoppingItem;
  @Output() public submitForm: EventEmitter<SaleProduct> = new EventEmitter();
  subscriptionStock: Subscription;
  updatePrice = false;
  form: FormGroup;
  quantityOk = true;
  stockValid = true;
  listPrice: number;
  salePrice: number;
  loading$: Observable<boolean>;
  error$: Observable<Error>;
  stock$: Observable<Stock[]>;
  colors$: Observable<ColorsTintometrico[]>;
  loadPrice = false;
  error: Error = null;
  showDescription = false;
  textShowMore = 'Ver mais';
  public data: any = {
    deliveryType: null,
    store: null,
    stockStore: null,
    quantity: 1
  };

  public dataDelivery = [{ type: 'RI', description: 'Retira imediata' },
  { type: 'EN', description: 'Entrega' },
  { type: 'RP', description: 'Retira posterior' },
  { type: 'EF', description: 'Entrega futura' },
  ];

  /* Variaveis para mensagem */
  showInformation = false;
  titleInformation = 'Pedido de venda';
  messageInformation = '';
  informationDescription = '';

  /* edit Price */
  editPrice = false;
  @ViewChildren('inputPrice') inputPrice: QueryList<ElementRef>;

  returnShowInformation() {
    this.showInformation = false;
  }
  /* FIM - Variaveis para mensagem */


  constructor(
    public dialog: DialogRef,
    private fb: FormBuilder,
    private shoppingService: ShoppingService,
    private productService: ProductService,
    private tintometricoService: TintometricoService,
    private store: Store<SaleState>,
    private readonly authService: AuthService,
  ) {
    super(dialog);
  }

  ngOnDestroy(): void {
    if (this.subscriptionStock) {
      this.subscriptionStock.unsubscribe();
    }
  }

  ngOnInit(): void {
    this.form = this.fb.group({
      quantity: new FormControl(this.shoppingItem != null ? this.shoppingItem.quantity : this.product.mutiple.toFixed(2), []),
      salePrice: new FormControl(this.shoppingItem != null ? this.shoppingItem.price : this.product.salePrice, []),
      store: new FormControl(this.shoppingItem != null ? this.shoppingItem.stockStore : this.authService.getStore(), []),
      deliveryType: new FormControl(this.shoppingItem != null ? this.shoppingItem.deliveryType : '', []),
      price: new FormControl(this.shoppingItem != null ? this.shoppingItem.price : this.product.salePrice, []),
      description: new FormControl(this.shoppingItem != null ? this.shoppingItem.auxDescription : '', []),
      addUpQuantity: new FormControl(this.shoppingItem != null ? this.shoppingItem.percentUpQuantity > 0 : false, []),
      originalQuantity: new FormControl(this.shoppingItem != null ? this.shoppingItem.upQuantity : 0, []),
    });
    this.listPrice = (this.shoppingItem != null ? this.shoppingItem.listPrice : this.product.listPrice);
    this.salePrice = (this.shoppingItem != null ? this.shoppingItem.price : this.product.salePrice);
    this.form.valueChanges.subscribe((_) => {
      const oldValue = this.form.get('quantity').value;
      this.quantityOk = Number.parseFloat(oldValue) <= this.product.stock;
    });
    this.loading$ = this.store.select(store => store.shopping.loading);
    this.error$ = this.store.select(store => store.shopping.error);
    this.error$.subscribe((error) => {
      this.error = error;
    });
    this.stock$ = this.productService.getStocks(this.authService.getStore(), this.product.idProduct);
    console.log(`LETRA: ${this.product.letter} - LINHA: ${this.product.line}`);
    this.colors$ = this.tintometricoService.getColors(this.product.letter, this.product.line);
  }

  ngAfterViewInit() {
    this.setFocus(); // If the button is already present...
    this.inputPrice.changes.subscribe(() => {
      this.setFocus();
    });
  }

  setFocus() {
    if (this.inputPrice.length > 0) {
      this.inputPrice.first.nativeElement.focus();
      this.inputPrice.first.nativeElement.select();
    }
  }

  addQuantity(product: SaleProduct) {
    const oldValue = this.form.get('quantity').value;
    let addQuantity = 1;
    if (product.mutiple !== 1) {
      addQuantity = product.mutiple;
    }
    let newValue = (Number.parseFloat(oldValue) + addQuantity);
    if (newValue > product.stock) {
      newValue = oldValue;
    }
    this.form.patchValue({ quantity: newValue });
  }

  minusQuantity(product: SaleProduct) {
    const oldValue = this.form.get('quantity').value;
    let addQuantity = 1;
    if (product.mutiple !== 1) {
      addQuantity = product.mutiple;
    }
    let newValue = (Number.parseFloat(oldValue) - addQuantity);
    if (newValue < 0 || newValue < product.mutiple) {
      newValue = product.mutiple;
    }
    this.form.patchValue({ quantity: newValue });
  }

  addProductCart(product: any) {
    // this.returnProduct.emit({ ...this.product, quantity: this.formQuantity.get('quantity').value });
  }

  public onConfirmation() {
    console.log('botao acionado');
    this.dialog.close();
  }

  onDialogClose() {
    this.dialog.close();
  }

  async addProductCard(product: any) {
    const idCart = this.shoppingService.getCart();
    const quantity = this.form.get('quantity').value;
    const quantitySale = Math.ceil(quantity / product.mutiple) * product.mutiple;
    const descriptionAux = this.form.get('description').value;
    const deliveryType = this.form.get('deliveryType').value;
    const store = this.form.get('store').value;
    let price = this.product.listPrice; // Number.parseFloat(this.form.get('price').value);
    //  if (product.base === 'S') {
    if (this.product.salePromotion > 0){
      price = this.product.salePromotion;
    }
    const newPrice = Number.parseFloat(this.form.get('price').value);
    console.log(`Preço de tabela: ${price} - Novo Preço: ${newPrice} - Promocional: ${this.product.offPercent}`);
    if (newPrice < price ) {
      this.messageInformation = 'Preço de venda inválido!';
      this.informationDescription = 'Preço informado não pode ser inferior ao preço de tabela!';
      this.showInformation = true;
      return;
    }
    price = newPrice;
    // }

    if (deliveryType === null || deliveryType === '' || deliveryType === undefined) {
      this.messageInformation = 'Não foi informado o tipo de entrega!';
      this.informationDescription = 'Para incluir o item selecione um tipo de entrega para o produto!';
      this.showInformation = true;
      return;
    }

    this.subscriptionStock = this.productService
      .validateStock(product.idProduct, deliveryType, store, quantitySale)
      .pipe(
        map((stockValid) => {
          if (stockValid) {
            try {
              this.error = null;
              const id = (this.shoppingItem != null) ? this.shoppingItem.id : null;
              const sellerId = (this.shoppingItem != null) ? this.shoppingItem.seller : this.authService.getSeller();
              const discount = (this.shoppingItem != null) ? this.shoppingItem.discount : null;
              const discountValue = (this.shoppingItem != null) ? this.shoppingItem.discountValue : null;
              const userDiscount = (this.shoppingItem != null) ? this.shoppingItem.userDiscount : null;
              this.store.dispatch(new AddItemAction({
                id, idCart, invoiceStore: this.authService.getStore(),
                idProduct: product.idProduct, description: product.title, image: product.images[0], productType: product.productType,
                quantity: quantitySale, price, deliveryType,
                stockStore: store, seller: sellerId, percentUpQuantity: 0, upQuantity: 0,
                discount, discountValue, ean: product.ean, promotion: (product.offPercent > 0) ? product.salePrice : 0,
                listPrice: price, userDiscount, mutiple: product.mutiple,
                auxDescription: descriptionAux, smallDescription: product.smallDescription, brand: product.brand,
                base: product.base, letter: product.letter, line: product.line, color: product.color, can: product.can,
              }));

              this.loading$.subscribe((inProcess) => {
                console.log(inProcess);
                if (this.error) {
                  this.dialog.close({ success: false, message: this.error.message });
                  console.log('Erro ocorrido: ' + JSON.stringify(this.error));
                }
                if (!inProcess && this.error == null) {
                  console.log('Produto incluido com sucesso!');
                  this.dialog.close({ success: true, message: 'Produto incluído com sucesso!' });
                }
              });
            } catch (e) {
              console.log(e);
            }
          } else {
            // mostrar mensagem de falta de estoque
            this.messageInformation = 'Produto sem estoque disponível!';
            this.informationDescription = 'Verifique a disponibilidade do produto em outras filiais de estoque.';
            this.showInformation = true;
          }
        })
      ).subscribe();
  }

  isShowDescription() {
    this.showDescription = !this.showDescription;
    this.textShowMore = (this.showDescription) ? 'Ver menos' : 'Ver mais';
  }

  editingPrice() {
    this.editPrice = !this.editPrice;
  }

  confirmPrice() {
    const newPrice = Number.parseFloat(this.form.get('price').value);
    if (newPrice < this.product.listPrice) {
      this.form.patchValue({ price: (this.shoppingItem != null ? this.shoppingItem.price : this.product.salePrice) });
      this.messageInformation = 'Preço menor que o preço de tabela!';
      this.informationDescription = 'Preço informado é menor que o preço de tabela, em caso de desconto utilize a função de desconto por item ou pedido.';
      this.showInformation = true;
      return;
    }
    this.salePrice = newPrice;
    this.editPrice = !this.editPrice;
    this.updatePrice = true;
  }

  addQuantityM2() {
    const isAddPercentQuantity = !(this.form.get('addUpQuantity').value as boolean);
    if ( isAddPercentQuantity ) {
      const quantityProduct = Number.parseFloat(this.form.get('quantity').value);
      const quantity = Number.parseFloat(( quantityProduct * 0.1 ).toFixed(3));
      let newQuantity = quantityProduct + quantity;
      if ( this.product.mutiple > 1 ) {
        newQuantity = Number.parseFloat(( newQuantity / this.product.mutiple ).toFixed()) * this.product.mutiple;
        if ( newQuantity < (quantityProduct + quantity)) {
          newQuantity += this.product.mutiple;
        }
      }
      this.form.patchValue({
        quantity: newQuantity.toFixed(2),
        originalQuantity: quantityProduct.toFixed(2),
        addUpQuantity: ( newQuantity - quantityProduct ),
      });
    } else {

      const quantityProduct = Number.parseFloat(this.form.get('quantity').value);
      const quantity = Number.parseFloat(( quantityProduct / 1.1 ).toFixed(3));
      let newQuantity = quantity;
      if ( this.product.mutiple > 1 ) {
        newQuantity = Number.parseInt(( newQuantity / this.product.mutiple).toFixed(3), 10) * this.product.mutiple;
      }
      console.log(newQuantity);
      this.form.patchValue({
        quantity: newQuantity.toFixed(2),
        originalQuantity: newQuantity.toFixed(2),
        addUpQuantity: 0,
      });

    }

  }

  calcPriceColor(colorSelected: any) {
    console.log(colorSelected);
    const priceColor = new CalculatePriceColor();
    priceColor.productId = this.product.idProduct;
    priceColor.can = this.product.can;
    priceColor.letter = this.product.letter;
    priceColor.line = this.product.line;
    priceColor.price = 0;
    priceColor.storeId = this.form.get('store').value;
    priceColor.color = colorSelected.colorName;
    this.loadPrice = true;
    this.tintometricoService.calculatePrice(priceColor)
      .pipe(
        tap((price) => {
          console.log(price);
        //  this.product.salePrice = price.price;
          this.salePrice = price.price;
          this.form.patchValue({
            price: price.price,
            description: colorSelected.colorName,
          });
          this.loadPrice = false;
        }),
        catchError(error => {
          // TODO Mensagem de erro
          this.loadPrice = false;
          console.log(error);
          return of(error);
        })
      )
      .subscribe();
  }

}
