import { ChangeDetectorRef, Component, NgZone, OnInit } from '@angular/core';
import { DetailsComponentBase } from '@objects-view/details-component-base';
import { IClientModel } from '@fleio-api/client-user/model/client.model';
import { ConfigService } from '@shared/config/config.service';
import { IInvoiceModel } from '@fleio-api/billing/model/invoice.model';
import { InvoicesApiService } from '@fleio-api/billing/invoices/invoices-api.service';
import { FleioId } from '@fleio-api/base-model/base-fleio-object.model';
import { MatDialog } from '@angular/material/dialog';
import {
  InvoicesMergeDialogComponent
} from '../../../../billing/invoices/dialogs/invoices-merge-dialog/invoices-merge-dialog.component';
import { LineDirection, LineType } from '@shared/ui/objects-view/status-line/status-line.component';
import { LineColorPipe } from '@shared/ui/objects-view/status-line/line-color.pipe';
import { IObjectStatus, StatusType, StatusValue } from '@objects-view/interfaces/object-status';

@Component({
  selector: 'app-client-details-invoices',
  templateUrl: './client-details-invoices.component.html',
  styleUrls: ['./client-details-invoices.component.scss']
})
export class ClientDetailsInvoicesComponent extends DetailsComponentBase<IClientModel> implements OnInit {
  invoices: IInvoiceModel[];
  displayedColumns: string[] = ['id', 'status', 'issue_date', 'total'];
  selectedInvoices = {};
  hasInvoicesToMerge = false;
  nothingToMergeTxt = $localize`Select at least two invoices to merge`;

  protected readonly LineType = LineType;
  protected readonly LineDirection = LineDirection;
  private lineColorPipe: LineColorPipe;

  constructor(
    private matDialog: MatDialog,
    private invoicesApi: InvoicesApiService,
    public config: ConfigService,
    ngZone: NgZone,
    changeDetectorRef: ChangeDetectorRef,
  ) {
    super(ngZone, changeDetectorRef, config);
    this.lineColorPipe = new LineColorPipe();
  }

  ngOnInit() {
    super.ngOnInit();
  }

  getInvoiceStatus(invoice: IInvoiceModel): IObjectStatus {
    let status: IObjectStatus = null;
    switch (invoice.status) {
      case 'paid':
        status = {type: StatusType.Defined, value: StatusValue.Paid};
        break;
      case 'canceled':
        status = {type: StatusType.Defined, value: StatusValue.Canceled};
        break;
      case 'refunded':
        status = {type: StatusType.Defined, value: StatusValue.Refunded};
        break;
      case 'unpaid':
        if (new Date(invoice.due_date).getTime() < new Date().getTime()) {
          status = {type: StatusType.Defined, value: StatusValue.Overdue};
        } else {
          status = {type: StatusType.Defined, value: StatusValue.Unpaid};
        }
        break;
    }
    return status;
  }

  changeInvoiceSelection(invoiceId: FleioId) {
    this.selectedInvoices[invoiceId] = !this.selectedInvoices[invoiceId];
    let selectedCount = 0;
    for (const id in this.selectedInvoices) {
      if (this.selectedInvoices.hasOwnProperty(id)) {
        if (this.selectedInvoices[id] === true) {
          selectedCount += 1;
          if (selectedCount > 1) {
            this.hasInvoicesToMerge = true;
            break;
          } else {
            this.hasInvoicesToMerge = false;
          }
        }
      }
    }
  }

  mergeInvoices() {
    return this.matDialog.open(
      InvoicesMergeDialogComponent, {
        data: {selectedInvoices: this.selectedInvoices},
        autoFocus: false,
      }).afterClosed().subscribe(value => {
        if (value === true) {
          this.refreshData(true);
        }
    });
  }

  protected refreshData(resetSelectedInv?: boolean) {
    if (this.object) {
      this.invoicesApi.list({
        client: this.object.id,
        page_size: 20,
        ordering: '-issue_date',
      }).subscribe(invoices => {
        this.invoices = invoices.objects;
        this.invoices.forEach(invoice => {
          let invoiceStatus = this.getInvoiceStatus(invoice);
          (invoice as any).appLineColor = this.lineColorPipe.transform(invoiceStatus.value);
          (invoice as any).appLineType = invoiceStatus.type === StatusType.Changing ? LineType.Progress : LineType.Solid;
        });
        if (resetSelectedInv) {
          // it means we need to reset selected invoices for merging
          this.selectedInvoices = {};
          this.hasInvoicesToMerge = false;
        }
      });
    }
  }
}
