import { EventSubscriberModel } from '@midwayjs/typeorm';
import { EntitySubscriberInterface, InsertEvent, UpdateEvent, RemoveEvent } from 'typeorm';
import Axios from 'axios';
import { Config } from '@midwayjs/core';
import { get, toLower } from 'lodash';

enum Methods {
  CREATE = 'CREATE',
  UPDATE = 'UPDATE',
  DELETE = 'DELETE',
}

/**
 * 数据库监听类
 * 在这里通过对指定表的过滤,将数据变化通过http请求发送至es服务
 * 让es服务去处理数据的同步问题
 */
@EventSubscriberModel()
export class DbSubscriber implements EntitySubscriberInterface {
  @Config('modulesConfig.es')
  esServiceHttpPrefix: any;
  /**
   * 添加前触发
   */
  beforeInsert(event: InsertEvent<any>) {
    console.log('BEFORE ENTITY INSERTED: ', event.entity);
    // console.log(this.ctx.request);
    // console.log(event.metadata.givenTableName);
  }

  /**
   * 修改前触发
   */
  beforeUpdate(event: UpdateEvent<any>) {
    console.log('BEFORE ENTITY UPDATED: ', event.entity);
  }

  /**
   * 删除前触发
   */
  beforeRemove(event: RemoveEvent<any>) {
    console.log(`BEFORE ENTITY WITH ID ${event.entityId} REMOVED: `, event.entity);
  }

  /**
   * 添加后触发
   */
  afterInsert(event: InsertEvent<any>) {
    console.log('AFTER ENTITY INSERTED: ', event.entity);
    const tableName = get(event, 'metadata.givenTableName');
    const data = event.entity;
    const m = Methods.CREATE;
    this.toSync(tableName, data, m);
  }

  /**
   * 修改后触发
   */
  afterUpdate(event: UpdateEvent<any>) {
    console.log('AFTER ENTITY UPDATED: ', event.entity);
    const tableName = get(event, 'metadata.givenTableName');
    const data = event.entity;
    const m = Methods.UPDATE;
    this.toSync(tableName, data, m);
  }

  /**
   * 删除后触发
   */
  afterRemove(event: RemoveEvent<any>) {
    console.log(`AFTER ENTITY WITH ID ${event.entityId} REMOVED: `, event.entity);
    const tableName = get(event, 'metadata.givenTableName');
    const data = event.entity;
    const m = Methods.DELETE;
    this.toSync(tableName, data, m);
  }

  /**
   * 查询后触发
   */
  async afterLoad(entity: any) {
    // const url = 'http://127.0.0.1:9700';
    // const axios = Axios.get(url);
    // console.log(axios);
    // console.log('AFTER ENTITY LOADED: ', entity);
  }

  async toSync(tableName: string, data: any, method: Methods) {
    const url = `${this.esServiceHttpPrefix}/sync`;
    tableName = toLower(tableName);
    const body = { index: tableName, data, method };
    try {
      await Axios.post(url, body, { responseType: 'json' });
    } catch (error) {
      console.log(error)
    }
  }
}
