import { Component, ChangeDetectionStrategy, Input, TemplateRef, OnInit } from '@angular/core';
import { HistoryStateFacade } from '@shelf-store/history';
import { DetailsFacade } from '@shelf-store/details';
import { OrderDetailsCardInput } from '../../../components/order-details-card';
import { OrderItemListItemDTO, OrderItemProcessingStatusValue } from '@swagger/oms';
import { Observable } from 'rxjs';
import { map, filter, shareReplay, take } from 'rxjs/operators';

@Component({
  selector: 'app-shelf-history-header',
  templateUrl: 'history-header.component.html',
  styleUrls: ['./history-header.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ShelfHistoryHeaderComponent implements OnInit {
  @Input() orderId: any;
  @Input() compartmentCode: string;
  @Input() orderItemId: number;
  @Input() orderItemSubsetId: number;
  @Input() headerTemplate: TemplateRef<any>;

  details$: Observable<OrderDetailsCardInput & { orderId: number }>;

  orderItems$: Observable<OrderItemListItemDTO[]>;

  constructor(private detailsFacade: DetailsFacade, private historyStateFacade: HistoryStateFacade) {}

  ngOnInit() {
    if (this.compartmentCode) {
      this.orderItems$ = this.detailsFacade.getOrderItemsByCompartmentCode$(this.compartmentCode);
    } else if (this.orderId) {
      this.orderItems$ = this.detailsFacade.getOrderItemsByOrderNumber$(this.orderId);
    }

    this.details$ = this.orderItems$.pipe(
      map((items) => {
        if (items.length > 0) {
          const item = items[0];
          return {
            firstName: item.firstName,
            lastName: item.lastName,
            customerNumber: item.buyerNumber,
            estimatedShippingDate: item.estimatedShippingDate ? new Date(item.estimatedShippingDate) : undefined,
            orderDate: new Date(item.orderDate),
            orderNumber: item.orderNumber,
            processingStatus: item.processingStatus,
            processingStatusDate: new Date(item.processingStatusDate),
            orderChannel: item.clientChannel,
            compartmentCode: item.compartmentCode,
            compartmentInfo: item.compartmentInfo,
            pickupDeadline: new Date(item.pickUpDeadline),
            orderId: item.orderId,
          } as OrderDetailsCardInput & { orderId: number };
        }
        return undefined;
      }),
      filter((details) => !!details),
      shareReplay()
    );
  }

  updateHistory() {
    this.historyStateFacade.reloadHistory(this.orderItemSubsetId);
  }

  async updateEstimatedShippingDate(date: Date) {
    const orderId = await this.getOrderId();

    await this.detailsFacade.setEstimatedShippingDate({
      items: [
        {
          orderItemSubsetId: this.orderItemSubsetId,
          orderItemId: this.orderItemId,
          orderId: orderId,
        },
      ],
      estimatedShippingDate: date,
    });

    this.updateHistory();
  }

  async changePickUpDate(date: Date) {
    const orderId = await this.getOrderId();

    await this.detailsFacade.setPickUpDeadline({
      items: [
        {
          orderItemSubsetId: this.orderItemSubsetId,
          orderItemId: this.orderItemId,
          orderId: orderId,
        },
      ],
      pickUpDeadline: date,
    });

    this.updateHistory();
  }

  async changeProcessingStatus(processingStatus: OrderItemProcessingStatusValue) {
    const orderId = await this.getOrderId();

    await this.detailsFacade.changeStatus([
      {
        orderItemSubsetId: this.orderItemSubsetId,
        orderItemId: this.orderItemId,
        orderId,
        data: {
          processingStatus,
        },
      },
    ]);

    this.updateHistory();
  }

  private async getOrderId() {
    return this.details$
      .pipe(
        map((details) => details.orderId),
        take(1)
      )
      .toPromise();
  }
}
