import { Injectable } from '@nestjs/common';
import { BaseCustomManager } from 'src/core/modules/domain/usecase/managers/base-custom.manager';
import { ItemEntity } from '../../entities/item.entity';
import { EventTopics } from 'src/core/strings/constants/interface.constants';
import { ItemModel } from '../../../data/models/item.model';
import { In, LessThanOrEqual, MoreThanOrEqual } from 'typeorm';

@Injectable()
export class UpdateItemRatePriceManager extends BaseCustomManager<ItemEntity> {
  protected rates = [];
  get entityTarget(): any {
    return ItemModel;
  }

  get eventTopics(): EventTopics[] {
    return [];
  }

  async validateProcess(): Promise<void> {
    return;
  }

  async beforeProcess(): Promise<void> {
    let query;
    const bundling_items = [];
    const item_ids = this.data.items.map((item) => {
      if (item.item.bundling_items) {
        const bundlings = item.item.bundling_items.map(({ id }) => id);
        bundling_items.push(...bundlings);
      }
      return item.item.id;
    });

    if (this.data.season_period_id) {
      query = {
        item_id: In([...item_ids, ...bundling_items]),
        season_period: {
          id: this.data.season_period_id,
        },
      };
    } else {
      query = {
        item_id: In([...item_ids, ...bundling_items]),
        season_period: {
          start_date: MoreThanOrEqual(this.data.booking_date),
          end_date: LessThanOrEqual(this.data.booking_date),
        },
      };
    }

    this.rates = await this.dataService.getManyByOptions({
      where: query,
    });
    return;
  }

  async process(): Promise<void> {
    this.data.items.map((item) => {
      const current_price = this.rates.find(
        (rate) => rate.item_id == item.item.id,
      );
      item.item.bundling_items = item.item.bundling_items?.map((bundling) => {
        const current_price = this.rates.find(
          (rate) => rate.item_id == bundling.id,
        );

        return {
          ...bundling,
          item_rates: current_price?.price ?? 0,
        };
      });

      Object.assign(item, {
        total_price: current_price?.price ?? item.item.base_price,
      });
    });
    return;
  }

  async afterProcess(): Promise<void> {
    return;
  }

  async getResult() {
    return this.data.items;
  }
}
