import { Injectable } from '@angular/core';
import {
  ListResponseArgsOfPackageDTO2,
  PackageArrivalStatusDTO,
  PackageDetailResponseDTO,
  PackageDTO2,
  QuerySettingsDTO,
  QueryTokenDTO,
  ResponseArgsOfPackageArrivalStatusDTO,
  ResponseArgsOfPackageDetailResponseDTO,
  ResponseArgsOfQuerySettingsDTO,
  WareneingangService,
} from '@generated/swagger/wws-api';
import { Observable, Subject } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import { PackageInspectionEvent, PackageStatusChangedEvent } from './events';

@Injectable({
  providedIn: 'root',
})
export class DomainPackageInspectionService {
  private _events = new Subject<PackageInspectionEvent>();

  events = this._events.asObservable();

  constructor(private _wareneingang: WareneingangService) {}

  getQuerySettingsResponse(): Observable<ResponseArgsOfQuerySettingsDTO> {
    return this._wareneingang.WareneingangQueryPackagesSettings();
  }

  getQuerySettings(): Observable<QuerySettingsDTO> {
    return this.getQuerySettingsResponse().pipe(map((response) => response.result));
  }

  queryPackagesResponse(queryToken: QueryTokenDTO): Observable<ListResponseArgsOfPackageDTO2> {
    return this._wareneingang.WareneingangQueryPackages(queryToken);
  }

  queryPackages(queryToken: QueryTokenDTO): Observable<PackageDTO2[]> {
    return this.queryPackagesResponse(queryToken).pipe(map((response) => response.result));
  }

  getPackageDetailsResponse(id: string): Observable<ResponseArgsOfPackageDetailResponseDTO> {
    return this._wareneingang.WareneingangGetPackageDetails(id);
  }

  getPackageDetails(id: string): Observable<PackageDetailResponseDTO> {
    return this.getPackageDetailsResponse(id).pipe(map((response) => response.result));
  }

  changePackageStatusResponse(pkg: PackageDTO2, modifier: string): Observable<ResponseArgsOfPackageArrivalStatusDTO> {
    return this._wareneingang
      .WareneingangChangePackageStatus({
        packageId: pkg.id,
        payload: {
          id: pkg.id,
          annotation: pkg.annotation,
          area: pkg.area,
          arrivalChecked: pkg.arrivalChecked,
          arrivalStatus: pkg.arrivalStatus,
          deliveryNoteNumber: pkg.deliveryNoteNumber,
          deliveryTarget: pkg.deliveryTarget,
          estimatedDeliveryDate: pkg.estimatedDeliveryDate,
          packageNumber: pkg.packageNumber,
          supplier: pkg.supplier,
          trackingNumber: pkg.trackingNumber,
          scanId: pkg.scanId,
        },
        modifier,
      })
      .pipe(tap((res) => this._events.next(new PackageStatusChangedEvent(pkg.id, res.result))));
  }

  changePackageStatus(pkg: PackageDTO2, modifier: string): Observable<PackageArrivalStatusDTO> {
    return this.changePackageStatusResponse(pkg, modifier).pipe(map((response) => response.result));
  }

  test() {
    return this._wareneingang.WareneingangChangePackageStatus;
  }
}
