import { ChangeDetectorRef, Component, NgZone, OnDestroy, OnInit } from '@angular/core';
import { DetailsComponentBase } from '@objects-view/details-component-base';
import { IServiceModel } from '@fleio-api/billing/model/service.model';
import { ConfigService } from '@shared/config/config.service';
import { Sort } from '@angular/material/sort';
import { PaginatorService } from '@shared/ui-api/paginator.service';
import { ObjectListController } from '@objects-view/object-list-controller';
import { ObjectController } from '@objects-view/object-controller';
import { OrderingHelper } from '@shared/ui-api/helpers/ordering-helper';
import { map } from 'rxjs/operators';
import { ServiceCyclesApiService } from '@fleio-api/billing/service-cycles/service-cycles-api.service';
import { Subscription } from 'rxjs';
import { ServicesApiService } from '@fleio-api/billing/services/service-api.service';
import { NotificationService } from '@shared/ui-api/notification.service';
import { ServiceCycleEditTrackerService } from '../../../service-cycles/service-cycle-edit-tracker.service';
import { IYesNoDialogResult } from '@shared/ui-api/interfaces/yes-no-dialog-result';
import { ServiceCycleListUIService } from '../../../service-cycles/service-cycle-list-ui.service';
import { IObjectListController } from '@objects-view/interfaces/object-list-controller';
import { IServiceCycleModel, ServiceCycleStates } from '@fleio-api/billing/service-cycles/models/service-cycle-model';

@Component({
  selector: 'app-service-details-cycles',
  templateUrl: './service-details-cycles.component.html',
  styleUrls: ['./service-details-cycles.component.scss']
})
export class ServiceDetailsCyclesComponent extends DetailsComponentBase<IServiceModel> implements OnInit, OnDestroy {
  objectListController: IObjectListController;
  currentPageSize = this.paginator.defaultPageSize;
  sort = {active: 'id', direction: 'desc'} as Sort;
  private serviceCycleEditSubscription: Subscription = null;

  constructor(
    private serviceCycleEditTrackerService: ServiceCycleEditTrackerService,
    public paginator: PaginatorService,
    private serviceCyclesApi: ServiceCyclesApiService,
    private servicesApi: ServicesApiService,
    private notificationService: NotificationService,
    private serviceCycleListUIService: ServiceCycleListUIService,
    public config: ConfigService,
    ngZone: NgZone,
    changeDetectorRef: ChangeDetectorRef,
  ) {
    super(ngZone, changeDetectorRef, config);
  }

  protected tabActivated() {
    super.tabActivated();
    this.loadServiceCycles();
  }

  ngOnDestroy() {
    super.ngOnDestroy();
    if (this.serviceCycleEditSubscription) {
      this.serviceCycleEditSubscription.unsubscribe();
      this.serviceCycleEditSubscription = null;
    }
  }

  ngOnInit() {
    super.ngOnInit();
    this.serviceCycleEditSubscription = this.serviceCycleEditTrackerService.observableServiceCycleEdit.subscribe(
      () => {
      this.loadServiceCycles();
    });
  }

  increasePageSize() {
    this.currentPageSize += this.paginator.defaultPageSize;
    this.loadServiceCycles();
  }

  sortFn(data: Sort) {
    this.sort = data;
    this.loadServiceCycles();
  }

  loadServiceCycles() {
    this.objectListController = null;
    this.changeDetectorRef.detectChanges();
    this.objectListController = new ObjectListController<ObjectController>(
      this.serviceCyclesApi.list({
        service_id: this.object.id,
        page_size: this.currentPageSize,
        ordering: OrderingHelper.toStr(this.sort),
      }).pipe(map(data => data)),
      this.serviceCycleListUIService,
    );
  }

  addNewCycle() {
    this.notificationService.confirmDialog(
      {
        title: $localize`Create new service cycle`,
        message: $localize`Are you sure you want to create a new cycle for current service?`,
      }
    ).subscribe((dialogResult: IYesNoDialogResult) => {
      if (dialogResult?.button === 'yes') {
        this.servicesApi.newCycle(this.object.id).subscribe(response => {
          this.notificationService.showMessage(response.detail);
          this.loadServiceCycles();
        });
      }
    });
  }

  showSettleButton() {
    return (this.object.status == 'terminated') && this.objectListController?.objects.some(
      (o : IServiceCycleModel) => [ServiceCycleStates.InProgress, ServiceCycleStates.Unpaid].includes(o.state),
    )
  }

  settleAllCycles() {
    this.notificationService.confirmDialog(
      {
        title: $localize`Settle all cycles`,
        message: $localize`Are you sure you want to settle all cycles for current service?`,
        secondaryMessage: $localize`All "in progress" or "unpaid" cycles will be invoiced or paid from client credit based on client configuration settings. Note that for postpaid services only cycles ended before current time will be settled.`
      }
    ).subscribe((dialogResult: IYesNoDialogResult) => {
      if (dialogResult?.button === 'yes') {
        this.servicesApi.settleAllCycles(this.object.id).subscribe(response => {
          this.notificationService.showMessage(response.detail);
          this.loadServiceCycles();
        });
      }
    });

  }
}

