import { Component, OnInit, ViewChild } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { DataBindingDirective, FilterableSettings, GridDataResult } from '@progress/kendo-angular-grid';
import { AggregateDescriptor, groupBy, GroupDescriptor, process } from "@progress/kendo-data-query";
import { PageChangeEvent } from '@progress/kendo-angular-pager';
import { Observable, of } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';
import { AuthService } from 'src/app/auth/services/auth.service';
import { CreatePaymentPartner } from 'src/app/models/create-payment-partner.model';
import { Partners } from 'src/app/models/partners.model';
import { PaymentPartner } from 'src/app/models/payment-partner.model';
import { PartnerService } from 'src/app/services/partner.service';

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

  formFilter: FormGroup;
  type: FormControl;
  partners$: Observable<Partners[]>;
  selectedPartner: Partners;
  public value: Date = new Date();
  @ViewChild(DataBindingDirective) dataBinding: DataBindingDirective;

  titleMessage = 'Confirmar';
  messageConfirmation = 'Confirma processamento?';
  textButtonConfirmation = 'OK';
  textButtonCancel = 'Cancelar';
  openedConfirmationPayment = false;
  loading = false;
  messageLoading = 'Aguarde, consultando vendas dos parceiros...';

  openedInformation = false;
  titleInformation = 'Pagamento de parceiros';
  messageInformation = '';

  public gridView: any; // GridDataResult;
  public paymentsPartner: PaymentPartner[] = [];
  public mySelection: number[] = [];
  public pageSize = 30;
  public skip = 0;
  public filterMode: FilterableSettings = "row";

  public myAggregates: AggregateDescriptor[] = [
    { field: 'saleValue', aggregate: 'sum' },
    { field: 'devolValue', aggregate: 'sum' },
    { field: 'commissionValue', aggregate: 'sum' },
    { field: 'previusBalance', aggregate: 'sum' },
    { field: 'paidValue', aggregate: 'sum' },
    { field: 'creditValue', aggregate: 'sum' },
    { field: 'balance', aggregate: 'sum' },
  ];

  public group: GroupDescriptor[] = [
    { field: "type", aggregates: this.myAggregates },
  ];

  constructor(
    private readonly partnerService: PartnerService,
    private readonly authService: AuthService,
  ) { }

  ngOnInit(): void {
    this.partners$ = this.partnerService.getPartnerByQuery('T', null, null);
    this.formFilter = new FormGroup({
      type: new FormControl(),
      dateMov: new FormControl(),
    });
  }

  public selectPartner(partner: any) {
    console.log(partner);
    this.selectedPartner = null;
    if (partner) {
      this.selectedPartner = partner;
    }
  }

  public pageChange(event: PageChangeEvent): void {
    this.skip = event.skip;
    this.loadItems();
  }

  private loadItems(): void {
    // this.gridView = {
    //   data: this.paymentsPartner.slice(this.skip, this.skip + this.pageSize),
    //   total: this.paymentsPartner.length,
    // };

    this.gridView = groupBy(process(this.paymentsPartner, {}).data, this.group);
    this.dataBinding.skip = 0;
    this.mySelection = [];

  }

  public onGroupChange(group: GroupDescriptor[]): void {
    // set aggregates to the returned GroupDescriptor
    group.map((group) => (group.aggregates = this.myAggregates));

    this.group = group;
    this.loadItems();
  }

  public search() {

    let partnerId = -1;
    if (this.selectedPartner !== null && this.selectedPartner !== undefined) {
      partnerId = this.selectedPartner.id;
    }
    const dateMov = this.formFilter.get('dateMov').value as Date;
    const month = ('00' + (dateMov.getMonth() + 1)).slice(-2);
    const year = dateMov.getFullYear();
    const type = this.formFilter.get('type').value;
    let intType = 99;
    switch (type) {
      case 'M':
        intType = 1;
        break;
      case 'P':
        intType = 2;
        break;
      case 'B':
        intType = 3;
        break;
      default:
        intType = 99;
        break;
    }
    console.log(type);
    this.messageLoading = 'Aguarde, consultando vendas dos parceiros...';
    this.loading = true;
    this.partnerService.getPayment(partnerId, intType, month, year.toString()).pipe(
      map(data => {
        this.paymentsPartner = data;
        console.log(data);
        this.loadItems();
        this.loading = false;
      }),
      catchError(error => {
        this.loading = false;
        this.messageInformation = error.message;
        this.openedInformation = true;
        return of();
      })
    ).subscribe();

  }

  async showConfirmationPayment() {
    this.titleMessage = 'Gerar pagamentos parceiros';
    this.messageConfirmation = `Confirma a geração dos pagamentos?`;
    this.textButtonConfirmation = 'Confirma';
    this.openedConfirmationPayment = true;
  }

  createPayment(result: any) {

    console.log(result);

    this.openedConfirmationPayment = false;

    const payments: CreatePaymentPartner[] = [];

    const dateMov = this.formFilter.get('dateMov').value as Date;
    const month = ('00' + (dateMov.getMonth() + 1)).slice(-2);
    const year = dateMov.getFullYear();

    this.mySelection.forEach(partnerId => {
      const payment = new CreatePaymentPartner();
      payment.dueDate = new Date(year, Number.parseInt(month), 10);
      payment.month = month;
      payment.partnerId = partnerId;
      payment.userId = this.authService.getUser();
      payment.year = year.toString();
      payments.push(payment);
    });
    console.log(JSON.stringify(payments));
    this.messageLoading = 'Aguarde, processando pagamentos dos parceiros selecionados...';
    this.loading = true;
    this.partnerService.createPayment(payments).pipe(
      tap(() => {
        this.loading = false;
        this.search();
      }),
      catchError(error => {
        this.loading = false;
        this.messageInformation = error.message;
        this.openedInformation = true;
        return of();
      })
    )
      .subscribe();

  }

  closeInformation(result: any) {
    this.openedInformation = false;
  }

}
