import { Config, Init, Inject, Provide } from '@midwayjs/decorator';
import { BaseService, CoolCommException } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Equal, In, Repository } from 'typeorm';
import { KnowDataInfoEntity } from '../../entity/data/info';
import { KnowStore } from '../../store';
import { retryWithAsync } from '@midwayjs/core';

/**
 * 知识信息
 */
@Provide()
export class KnowDataInfoService extends BaseService {
  @InjectEntityModel(KnowDataInfoEntity)
  knowDataInfoEntity: Repository<KnowDataInfoEntity>;

  @Inject()
  knowStore: KnowStore;

  @Config('module.know.prefix')
  prefix: string;

  @Config('module.know.chroma')
  chromaConfig;

  @Init()
  async init() {
    await super.init();
    this.setEntity(this.knowDataInfoEntity);
  }

  /**
   * 删除
   * @param ids
   */
  async delete(ids: number[]) {
    const info = await this.knowDataInfoEntity.findOneBy({ id: ids[0] });
    const store = await this.knowStore.get(info.typeId);
    await store.remove(`${this.prefix}${info.typeId}`, ids);
    await super.delete(ids);
  }

  /**
   * 新增或修改
   * @param param
   * @param type
   */
  async addOrUpdate(param: any | any[], type?: 'add' | 'update') {
    await super.addOrUpdate(param, type);
    if (type == 'add') {
      // 判断param 是数组还是对象
      if (Array.isArray(param)) {
        param.forEach(item => {
          this.retrySaveToStore(item.typeId, item);
        });
      } else {
        if (param.enable == 1) {
          this.retrySaveToStore(param.typeId, param);
        }
      }
    } else {
      const info = await this.knowDataInfoEntity.findOneBy({ id: param.id });
      const store = await this.knowStore.get(info.typeId);
      const data = {
        ...info,
        ...param,
      };
      if (data.enable == 0) {
        await store.remove(`${this.prefix}${info.typeId}`, [data.id]);
        await this.knowDataInfoEntity.update(data.id, {
          status: 0,
        });
      } else {
        this.retrySaveToStore(info.typeId, data);
      }
    }
  }

  /**
   * 重试保存到存储
   * @param typeId
   * @param param
   */
  async retrySaveToStore(typeId: number, param: any) {
    const invokeNew = retryWithAsync(
      this.saveToStore.bind(this),
      this.chromaConfig.retry,
      {
        retryInterval: this.chromaConfig.retryInterval,
      }
    );
    try {
      await invokeNew(typeId, param);
    } catch (e) {
      console.error('retrySaveToStore error', e);
    }
  }

  /**
   * 保持到存储
   * @param typeId
   * @param param
   */
  async saveToStore(typeId: number, param: any) {
    const store = await this.knowStore.get(typeId);
    await store.upsert(`${this.prefix}${typeId}`, [param]);
    await this.knowDataInfoEntity.update(
      { id: Equal(param.id) },
      {
        status: 1,
      }
    );
  }
}
