import { Config, Init, Inject, Provide } from '@midwayjs/decorator';
import { BaseService } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Equal, In, Repository } from 'typeorm';
import { KnowDataTypeEntity } from '../../entity/data/type';
import { KnowConfigEntity } from '../../entity/config';
import { KnowConfigService } from '../config';
import { EmbeddModel } from '../../embed';
import { KnowStore } from '../../store';
import { KnowDataInfoEntity } from '../../entity/data/info';
import { KnowDataInfoService } from './info';

/**
 * 知识类型
 */
@Provide()
export class KnowDataTypeService extends BaseService {
  @InjectEntityModel(KnowDataTypeEntity)
  knowDataTypeEntity: Repository<KnowDataTypeEntity>;

  @InjectEntityModel(KnowDataInfoEntity)
  knowDataInfoEntity: Repository<KnowDataInfoEntity>;

  @InjectEntityModel(KnowConfigEntity)
  knowConfigEntity: Repository<KnowConfigEntity>;

  @Inject()
  knowDataInfoService: KnowDataInfoService;

  @Inject()
  knowConfigService: KnowConfigService;

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

  @Inject()
  knowStore: KnowStore;

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

  /**
   * 重建
   * @param typeId
   */
  async rebuild(typeId: number) {
    await this.knowDataInfoEntity.update({ typeId }, { status: 0 });
    const store = await this.knowStore.get(typeId);
    // 先删除
    await store.collection(`${this.prefix}${typeId}`, 'delete');
    // 再创建
    await store.collection(`${this.prefix}${typeId}`, 'create');
    // 获得所有数据
    const list = await this.knowDataInfoEntity.findBy({
      typeId: Equal(typeId),
      enable: 1,
    });
    // 保存到知识库
    list.forEach(item => {
      this.knowDataInfoService.retrySaveToStore(typeId, item);
    });
  }

  /**
   * 新增或修改
   * @param param
   * @param type
   */
  async addOrUpdate(param: any, type?: 'add' | 'update') {
    await super.addOrUpdate(param, type);
    if (param.enable == 0) {
      return;
    }
    // 先删除
    const store = await this.knowStore.get(param.id);
    await store.collection(`${this.prefix}${param.id}`, 'delete');
    // 再创建
    await store.collection(`${this.prefix}${param.id}`, 'create');
  }

  /**
   * 删除
   * @param ids
   */
  async delete(ids: number[]) {
    for (const id of ids) {
      const store = await this.knowStore.get(id);
      await store.collection(`${this.prefix}${id}`, 'delete');
    }
    await super.delete(ids);
    // 删除子数据
    await this.knowDataInfoEntity.delete({ id: In(ids) });
  }

  /**
   * 获得所有可用的知识库列表
   */
  async getKnows() {
    const list = await this.knowDataTypeEntity.findBy({
      enable: 1,
    });
    return list.map(item => {
      return {
        id: item.id,
        name: item.name,
        icon: item.icon,
        description: item.description,
      };
    });
  }

  /**
   * 获得知识信息
   * @param knowIds
   */
  async getKnow(knowId: number) {
    const result = await this.knowDataTypeEntity.findOneBy({
      id: Equal(knowId),
    });
    return result;
  }

  /**
   * 获得知识库对应的向量化模型
   * @param knowId
   * @returns
   */
  async getEmbedding(knowId: number) {
    const know = await this.getKnow(knowId);
    const embedConfigId = know.embedConfigId;
    const config = await this.knowConfigService.info(embedConfigId);
    const embedding = new EmbeddModel[config.type]({
      ...config.options.comm,
      ...know.embedOptions,
    });
    return embedding;
  }
}
