import { ShoppingItem } from './../store/models/shopping-item';
import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { Store } from '@ngrx/store';
import { DialogCloseResult, DialogRef, DialogService, WindowCloseResult,
         WindowRef, WindowService, WindowState } from '@progress/kendo-angular-dialog';
import { AutoCompleteComponent } from '@progress/kendo-angular-dropdowns';
import { SelectableSettings, SelectionEvent } from '@progress/kendo-angular-grid';
import { minusSmIcon } from '@progress/kendo-svg-icons';
import { Observable } from 'rxjs';
import { debounceTime, distinctUntilChanged, filter, map, switchMap } from 'rxjs/operators';
import { Billing } from 'src/app/models/billing.model';
import { Customer } from 'src/app/models/customer.model';
import { PaymentPlan } from 'src/app/models/payment-plan.model';
import { ResultApi } from 'src/app/models/result-api.model';
import { CustomerService } from 'src/app/services/customer.service';
import { LookupService } from 'src/app/services/lookup.service';
import { ShoppingService } from 'src/app/services/shopping.service';
import { DiscountItemComponent } from '../components/discount-item/discount-item.component';
import { DiscountOrderComponent } from '../components/discount-order/discount-order.component';
import { DeleteItemAction, LoadShoppingItemsAction } from '../store/actions/shopping.action';
import { SaleState } from '../store/models/sale-state.model';
import { SelectCustomerComponent } from '../components/select-customer/select-customer.component';
import { CustomerSaleState } from '../store/reducers/customer-sale.reducer';
import { LoadCustomerAction } from '../store/actions/customer-sale.action';
import { CustomerState } from '../store/models/customer-state.model';
import { DeliveryAddressComponent } from '../components/delivery-address/delivery-address.component';
import { CustomerAddress } from 'src/app/models/customer-address.model';
import { AuthService } from 'src/app/auth/services/auth.service';
import { OrderService } from 'src/app/services/order.service';
import { CartModel } from 'src/app/models/cart.model';
import { CartItensModel } from 'src/app/models/cart-itens.model';
import { SelectEvent } from '@progress/kendo-angular-layout';
import { Router } from '@angular/router';
import { PreOrderService } from 'src/app/services/pre-order.service';

@Component({
  selector: 'app-cart',
  templateUrl: './cart.component.html',
  styleUrls: ['./cart.component.scss',
    './cart.component.css']
})
export class CartComponent implements OnInit {

  shopping$: Observable<ShoppingItem[]>;
  loading$: Observable<boolean>;
  error$: Observable<Error>;
  paymentPlan$: Observable<PaymentPlan[]>;
  billing$: Observable<Billing[]>;
  totalCart$: Observable<number>;
  customerSale$: Observable<Customer>;
  errorCustomer$: Observable<Error>;
  customerAddress: CustomerAddress;
  saleBilling: Billing = null;
  salePaymentPlan: PaymentPlan = null;

  public form1: FormGroup;
  public formCustomer: FormGroup;
  public formAddress: FormGroup;
  public formNotation: FormGroup;
  public queryField = new FormControl();
  customers: Customer[] = [];
  saleCustomer: Customer = null;
  public openedCustomer = false;
  public selectableSettigns: SelectableSettings = {
    checkboxOnly: false
  };
  public icons = { discount: minusSmIcon };
  public themeColorDiscount = 'error';
  openFormDiscount = false;
  private dialog;
  public loadingIcon = '';

  public windowState: WindowState = 'maximized';
  public openedPrintPreOrder = false;

  public openClosePrintPreOrder(isOpened: boolean): void {
    this.openedPrintPreOrder = isOpened;
  }


  constructor(
    private store: Store<SaleState>,
    private storeCustomer: Store<CustomerState>,
    private customerService: CustomerService,
    private shoppingService: ShoppingService,
    private lookupService: LookupService,
    private authService: AuthService,
    private orderService: OrderService,
    private preOrderService: PreOrderService,
    private formBuilder: FormBuilder,
    private windowService: WindowService,
    private dialogService: DialogService,
    private router: Router) {
    this.form1 = this.formBuilder.group({
      customer: new FormControl('', [Validators.required, Validators.minLength(3)]),
      addressCustomer: new FormControl('', []),
      numberCustomer: new FormControl('', []),
      neighbordCustomer: new FormControl('', []),
      cityCustomer: new FormControl('', []),
      stateCustomer: new FormControl('', []),
      zipCodeCustomer: new FormControl('', []),
      cellPhoneCustomer: new FormControl('', []),
      phoneCustomer: new FormControl('', []),
    });
    this.formCustomer = this.formBuilder.group({
      name: new FormControl('', []),
      document: new FormControl('', []),
      street: new FormControl('', []),
      number: new FormControl('', []),
      complement: new FormControl('', []),
      neighbordCustomer: new FormControl('', []),
      city: new FormControl('', []),
      state: new FormControl('', []),
      zipCode: new FormControl('', []),
    });

    this.formAddress = this.formBuilder.group({
      street: new FormControl('', []),
      number: new FormControl('', []),
      complement: new FormControl('', []),
      neighbordCustomer: new FormControl('', []),
      city: new FormControl('', []),
      state: new FormControl('', []),
      zipCode: new FormControl('', []),
      observacaoEntrega1: new FormControl('', []),
      observacaoEntrega2: new FormControl('', []),
      observacaoEntrega3: new FormControl('', []),
    });

    this.formNotation = this.formBuilder.group({
      observacao1: new FormControl('', []),
      observacao2: new FormControl('', []),
      observacao3: new FormControl('', []),
    });
  }

  ngOnInit(): void {
    this.shopping$ = this.store.select(store => store.shopping.list);
    this.loading$ = this.store.select(store => store.shopping.loading);
    this.error$ = this.store.select(store => store.shopping.error);
    this.totalCart$ = this.store.select(store => store.shopping.total);

    this.customerSale$ = this.storeCustomer.select(storeCustomer => storeCustomer.customerSale.item);
    this.errorCustomer$ = this.storeCustomer.select(storeCustomer => storeCustomer.customerSale.error);

    this.store.dispatch(new LoadShoppingItemsAction(this.shoppingService.getCart())); // '906488c9-249f-4253-b5e7-25033d597229'));
    this.storeCustomer.dispatch(new LoadCustomerAction());

    this.customerSale$.pipe(map(data => {
      this.saleCustomer = data;
      this.formCustomer.patchValue({
        name: data.name,
        document: data.cpfCnpj,
        street: data.address,
        number: data.addressNumber,
        complement: data.complement,
        neighborhood: data.neighborhood,
        city: data.city,
        state: data.state,
        zipCode: data.zipCode,
      });
      this.paymentPlan$ = this.lookupService.getPaymentPlan();
      this.billing$ = this.lookupService.getBilling(data.customerId);
    })).subscribe();
    this.getCustomerAddress();


    this.queryField.valueChanges
      .pipe(
        map(value => value.trim()),
        filter(value => value.length > 3 || value === ''),
        debounceTime(300),
        distinctUntilChanged(),
        switchMap(async (value) => {
          this.customers = await this.searchCustomer(value);
        })
      ).subscribe();
  }

  getCustomerAddress() {
    const dataAddress = localStorage.getItem('address');
    if (dataAddress != null) {
      this.customerAddress = JSON.parse(dataAddress);
      this.formAddress.patchValue({
        street: this.customerAddress.street,
        number: this.customerAddress.numberAddress,
        complement: this.customerAddress.complement,
        neighborhood: this.customerAddress.neighbourhood,
        city: this.customerAddress.city,
        state: this.customerAddress.state,
        zipCode: this.customerAddress.zipCode,
      });
    }
  }

  setBilling(selectBilling: Billing) {
    this.saleBilling = selectBilling;
  }

  setPaymentoPlan(selectPaymentPlan: PaymentPlan) {
    console.log(selectPaymentPlan);
    localStorage.setItem('paymentPlan', JSON.stringify(selectPaymentPlan));
    this.salePaymentPlan = selectPaymentPlan;
  }

  validadeBilling(itemArgs: { dataItem: any; index: number }) {
    const stringPaymentPlan = localStorage.getItem('paymentPlan');
    if (stringPaymentPlan == null) {
      return true;
    }
    const paymentPlan: PaymentPlan = JSON.parse(stringPaymentPlan);

    return itemArgs.dataItem.prazomaximovenda < paymentPlan.numdias;
  }


  public openWindowDiscount() {
    this.openFormDiscount = true;
    const window: WindowRef = this.windowService.open({
      title: 'Aplicar desconto para o pedido',
      content: DiscountOrderComponent,
      width: 450,
    });
    const discountForm = window.content.instance;
    this.totalCart$.subscribe(value => {
      discountForm.orderValue = value;
      discountForm.percent = 5;
    });

    window.result.subscribe((result) => {
      if (result instanceof WindowCloseResult) {
        console.log('Window was closed!');
        this.openFormDiscount = false;
      }
    });

    window.content.instance.submitForm.subscribe((formData) => {
      // handle form data
      console.log(formData);
      window.close();
    });

  }

  public editHandler({ sender, rowIndex, dataItem }) {
    console.log(dataItem);
  }

  public openDiscountItem({ sender, rowIndex, dataItem }) {
    this.openFormDiscount = true;
    const windowRef: WindowRef = this.windowService.open({
      title: 'Aplicar desconto para o item',
      content: DiscountItemComponent,
      width: 700,

    });
    const discountForm = windowRef.content.instance;
    discountForm.shoppingItem = dataItem;

    windowRef.result.subscribe((result) => {
      if (result instanceof WindowCloseResult) {
        console.log('Window was closed!');
      }
    });

    windowRef.content.instance.submitForm.subscribe((formData) => {
      // handle form data
      windowRef.close();
      console.log('Tela de desconto fechada.');
      //  this.store.dispatch(new LoadShoppingAction(this.shoppingService.getCart()));
    });

  }

  public openSelectCustomer() {

    this.openFormDiscount = true;
    const dialog: DialogRef = this.dialogService.open({
      title: 'Selecione o cliente para pedido',
      content: SelectCustomerComponent,
      width: 900,
      height: 600,

    });
    const dialogCustomer = dialog.content.instance;
    // discountForm.shoppingItem = dataItem;

    dialog.result.subscribe((result) => {
      if (result instanceof WindowCloseResult) {
        console.log('Window was closed!');
        window.close();
      }
    });

    dialog.content.instance.dialogCustomer.subscribe(() => {
      // handle form data
      const customer = (dialog.content.instance as SelectCustomerComponent).customer;
      console.log(customer);
      dialogCustomer.close();
    });

  }

  public openDeliveryAddress() {

    const window: WindowRef = this.windowService.open({
      title: 'Selecione o endereço de entrega',
      content: DeliveryAddressComponent,
      width: 1200,
      height: 600,

    });

    /*  window.result.subscribe((result) => {
        if (result instanceof WindowCloseResult) {
          console.log('Window was closed!');
          window.close();
        }
      }); */

    window.content.instance.submitForm.subscribe((formData) => {
      this.getCustomerAddress();
      window.close();
    });

  }

  async getItens() {
    const itensCart: CartItensModel[] = [];
    this.shopping$.subscribe(data => {
      console.log(data);
      data.forEach((itemShopping) => {
        const item: CartItensModel = {
          idProduct: itemShopping.idProduct, idStock: itemShopping.stockStore,
          deliveryMethod: itemShopping.deliveryType, quantity: itemShopping.quantity, listPrice: itemShopping.price,
          salePrice: itemShopping.price, ean: itemShopping.ean, descriptionAux: itemShopping.auxDescription,
        };
        itensCart.push(item);
      });
    }
    );

    return itensCart;
  }

  async createOrder() {
    console.log('criando cart');
    let idAddress = 0;
    const dataAddress = localStorage.getItem('address');
    if (dataAddress != null) {
      this.customerAddress = JSON.parse(dataAddress);
      idAddress = this.customerAddress.idAddress;
    }

    if (!this.saleCustomer) {
      console.log('sem cliente informado.');
      return;
    }
    console.log('Consultando itens');
    const itensCart = await this.getItens();
    console.log(itensCart);
    console.log('criando carrinho');
    console.log(this.form1);
    const cart: CartModel = {
      id: this.shoppingService.getCart(),
      userId: this.authService.getUser(),
      saleStore: this.authService.getStore(),
      idCustomer: this.saleCustomer.customerId,
      idPaymentPlan: this.salePaymentPlan.codplpag,
      idBilling: this.saleBilling.codcob,
      idSeller: this.authService.getSeller(),
      idProfessional: 0,
      shippingValue: 0,
      shippingDate: null,
      scheduleDelivery: this.formNotation.get('scheduleDelivery').value,
      shippingPriority: '',
      idAddress,
      notation1: this.formNotation.get('observacao1').value,
      notation2: this.formNotation.get('observacao2').value,
      notation3: this.formNotation.get('observacao3').value,
      deliveryNote1: this.formAddress.get('observacaoEntrega1').value,
      deliveryNote2: this.formAddress.get('observacaoEntrega1').value,
      deliveryNote3: this.formAddress.get('observacaoEntrega1').value,
      itens: itensCart,
      preCustomerDocument: null,
      preCustomerName: null,
      preCustomerPhone: null,
      carrierId: null,
    };

    console.log(cart);

    const result$ = this.orderService.create(cart);
    result$.pipe(
      map(result => {
        if (result.success) {
          this.showInformation(result.data.idOrder);
        }
      }),
    ).subscribe();

  }

  public close() {
    this.openedCustomer = false;
  }

  onSaveDiscount() {
    this.openFormDiscount = !this.openFormDiscount;
  }

  onSelectionChangeCustomer(args: SelectionEvent) {
    const selCustomer = args.selectedRows[0].dataItem as Customer;
    this.shoppingService.setCustomerSale(selCustomer);
    this.saleCustomer = selCustomer;
    this.close();
  }

  async searchCustomer(name: string) {
    try {
      this.customerService.getCustomer(name)
        .subscribe((res: Customer[]) => {
          this.customers = res;
        });
    } catch (e) {
      return null;
    }

  }

  isCustomerSelect() {
    console.log(this.saleCustomer);
    return this.saleCustomer != null && this.saleCustomer.customerId > 3;
  }

  public showConfirmation({ sender, rowIndex, dataItem }) {
    const dialog: DialogRef = this.dialogService.open({
      title: 'Confirmação',
      content: `Confirma a exclusão do produto?`,
      actions: [{ text: 'Não', primary: true }, { text: 'Sim' }],
      minWidth: 350,
      minHeight: 150,
    });
    console.log('Item para exclusao:' + JSON.stringify(dataItem));
    dialog.result.subscribe((result) => {
      if (result instanceof DialogCloseResult) {
        console.log('close');
        this.closeConfirmation();
      } else {
        console.log('action', result);
        if (result.text === 'Sim') {
          console.log('Item:' + dataItem.id);
          this.store.dispatch(new DeleteItemAction(dataItem.id));

        }
        this.closeConfirmation();
      }
    });
  }

  public closeConfirmation() {
    if (this.dialog) {
      this.dialog.close();
    }
  }

  public get isLoading(): boolean {
    return this.loadingIcon !== '';
  }

  public custom() {
    this.loadingIcon = 'loading';

    // Mock async action
    window.setTimeout(() => {
      this.loadingIcon = '';
      this.close();
    }, 3000);
  }

  public onTabSelect(e: SelectEvent) {
    console.log(e);
  }

  deleteAddressDelivery() {
    this.customerAddress = null;
    localStorage.removeItem('address');
  }

  public showInformation(idOrder: number) {
    const dialog: DialogRef = this.dialogService.open({
      title: 'Pedido gerado com sucesso!',
      content: `Número: ${idOrder}`,
      actions: [{ text: 'Ok', primary: true }],
      preventAction: (ev) => {
        return ev instanceof DialogCloseResult;
      },
    });

    dialog.result.subscribe((result) => {
      this.closeSale();
      if (result instanceof DialogCloseResult) {
        return;
      }
    });
  }

  public closeSale() {
    console.log('Fechamento venda.');
    localStorage.removeItem('cart');
    localStorage.removeItem('customer');
    localStorage.removeItem('preCustomer');
    localStorage.removeItem('paymentPlan');
    localStorage.removeItem('billing');
    localStorage.removeItem('address');
    localStorage.removeItem('invoiceStore');
    localStorage.removeItem('partner');
    localStorage.removeItem('shoppingItem');
    localStorage.removeItem('dataDelivery');
    localStorage.removeItem('taxDelivery');
    localStorage.removeItem('authorizationTax');
    localStorage.removeItem('authorizationPartner');
    this.router.navigate(['/appbar']);
  }

  async createPreOrder() {
    let idAddress = 0;
    const dataAddress = localStorage.getItem('address');
    if (dataAddress != null) {
      this.customerAddress = JSON.parse(dataAddress);
      idAddress = this.customerAddress.idAddress;
    }

    if (!this.saleCustomer) {
      console.log('sem cliente informado.');
      return;
    }
    console.log('Consultando itens');
    const itensCart = await this.getItens();
    console.log(itensCart);
    console.log('criando carrinho');
    console.log(this.form1);
    const cart: CartModel = {
      id: this.shoppingService.getCart(),
      userId: this.authService.getUser(),
      saleStore: this.authService.getStore(),
      idCustomer: this.saleCustomer.customerId,
      idPaymentPlan: this.salePaymentPlan.codplpag,
      idBilling: this.saleBilling.codcob,
      idSeller: this.authService.getSeller(),
      idProfessional: 0,
      shippingDate: null,
      scheduleDelivery: this.formNotation.get('scheduleDelivery').value,
      shippingValue: 0,
      carrierId: 0,
      shippingPriority: '',
      idAddress,
      notation1: this.formNotation.get('observacao1').value,
      notation2: this.formNotation.get('observacao2').value,
      notation3: this.formNotation.get('observacao3').value,
      deliveryNote1: this.formAddress.get('observacaoEntrega1').value,
      deliveryNote2: this.formAddress.get('observacaoEntrega1').value,
      deliveryNote3: this.formAddress.get('observacaoEntrega1').value,
      itens: itensCart,
      preCustomerDocument: null,
      preCustomerName: null,
      preCustomerPhone: null,

    };

    console.log(cart);

    const result$ = this.preOrderService.create(cart);
    result$.pipe(
      map(result => {
        if (result.success) {
          this.showInformation(result.data.idOrder);
          this.openedPrintPreOrder = true;
        }
      }),
    ).subscribe();

  }


}
