import { Provide } from '@midwayjs/core';
import { InjectDataSource, InjectEntityModel } from '@midwayjs/typeorm';
import { DataSource, In, Repository } from 'typeorm';
import { Menus } from '../../entity/system/menus.entity';
import { get, isNull, isNumber, isUndefined } from 'lodash';
import { User } from '../../entity/system/user.entity';
import { Admin } from '../../entity/system/admin.entity';
import { Achievement } from '../../entity/platform/achievement.entity';
import { Demand } from '../../entity/platform/demand.entity';
import { Design } from '../../entity/platform/design.entity';
import { Footplate } from '../../entity/platform/footplate.entity';
import { Journal } from '../../entity/platform/journal.entity';
import { Match } from '../../entity/platform/match.entity';
import { News } from '../../entity/platform/news.entity';
import { Notes } from '../../entity/platform/notes.entity';
import { Project } from '../../entity/platform/project.entity';
import { Sector } from '../../entity/platform/sector.entity';
import { Supply } from '../../entity/platform/supply.entity';
import { Support } from '../../entity/platform/support.entity';
import { UserMenus } from '../../entity/system/userMenus.entity';
import { Role } from '../../entity/system/role.entity';
import { Expert } from '../../entity/users/expert.entity';
import { Company } from '../../entity/users/company.entity';

@Provide()
export class DataDealService {
  @InjectEntityModel(Menus)
  Menus: Repository<Menus>;
  @InjectEntityModel(User)
  User: Repository<User>;
  @InjectEntityModel(Admin)
  Admin: Repository<Admin>;
  @InjectEntityModel(Achievement)
  Achievement: Repository<Achievement>;
  @InjectEntityModel(Demand)
  Demand: Repository<Demand>;
  @InjectEntityModel(Design)
  Design: Repository<Design>;
  @InjectEntityModel(Footplate)
  Footplate: Repository<Footplate>;
  @InjectEntityModel(Journal)
  Journal: Repository<Journal>;
  @InjectEntityModel(Match)
  Match: Repository<Match>;
  @InjectEntityModel(News)
  News: Repository<News>;
  @InjectEntityModel(Notes)
  Notes: Repository<Notes>;
  @InjectEntityModel(Project)
  Project: Repository<Project>;
  @InjectEntityModel(Sector)
  Sector: Repository<Sector>;
  @InjectEntityModel(Supply)
  Supply: Repository<Supply>;
  @InjectEntityModel(Support)
  Support: Repository<Support>;

  @InjectEntityModel(UserMenus)
  UserMenus: Repository<UserMenus>;
  @InjectEntityModel(Expert)
  Expert: Repository<Expert>;
  @InjectEntityModel(Company)
  Company: Repository<Company>;
  @InjectEntityModel(Role)
  Role: Repository<Role>;

  @InjectDataSource('default')
  defaultDataSource: DataSource;
  /**修正导入的数据,主要是内容变成object的数据,把richText取出来拼一起 */
  async correctImportData() {
    const config = [
      { model: this.Achievement, entity: Achievement, fields: ['field', 'name', 'brief', 'source', 'person', 'tel'] },
      { model: this.Company, entity: Company, fields: ['name', 'products', 'type', 'person'] },
      { model: this.Demand, entity: Demand, fields: ['field', 'company', 'brief', 'contacts', 'year', 'industry', 'company', 'tec_name', 'company_brief', 'question', 'month', 'tel'] },
      { model: this.Expert, entity: Expert, fields: ['industry_type', 'industry', 'work_type', 'name', 'work', 'title'] },
      { model: this.Match, entity: Match, fields: ['name', 'address'] },
      { model: this.Project, entity: Project, fields: ['name', 'brief', 'main', 'progress', 'track_unit', 'source'] },
      { model: this.Supply, entity: Supply, fields: ['industry', 'field', 'name', 'brief', 'source'] },
    ];
    const limit = 50;
    for (const c of config) {
      const { model, fields, entity } = c;
      let skip = 0;
      let isEmpty = false;
      while (!isEmpty) {
        const list = await model.find({ skip, take: limit });
        if (list.length <= 0) {
          isEmpty = true;
          break;
        }
        for (const i of list) {
          let needUpdate = false;
          const updateObj = {};
          for (const f of fields) {
            const fd = get(i, f);
            if (!fd) continue;
            try {
              if (isNumber(fd)) {
                continue;
              } else if (fd.includes('richText')) {
                // 处理值,然后修改 修改标记 过滤完所有字段后,进行修改
                try {
                  const obj = JSON.parse(fd);
                  const str = obj.richText.reduce((p, n) => `${p}${n.text}`, '');
                  updateObj[f] = str;
                  needUpdate = true;
                } catch (error) {
                  console.log('update field check', model.metadata.name, `id:${i.id}`);
                }
              }
              if (needUpdate) {
                await model.createQueryBuilder().update(entity).set(updateObj).where('id =:id', { id: i.id }).execute();
              }
            } catch (error) {
              console.log('field data check', model.metadata.name, `id:${i.id}`, f);
              console.log(i);
            }
          }
        }
        skip = skip + limit;
      }
    }
  }

  count = 0;

  isNoValue(val) {
    return isNull(val) || isUndefined(val);
  }

  async JsonbAddDefault() {
    // const menusRes = await this.menusModel.createQueryBuilder().where()
    const modelList = ['Menus', 'User', 'Admin', 'Achievement', 'Demand', 'Design', 'Footplate', 'Journal', 'Match', 'News', 'Notes', 'Project', 'Sector', 'Supply', 'Support'];
    // const modelList = ['Design'];
    for (const mn of modelList) {
      const model = get(this, mn);
      if (!model) continue;
      await this.getModelJsonbConfig(model);
    }
    console.log(this.count);
  }
  async getModelJsonbConfig(model) {
    const columns = model.metadata.columns;
    const defaultDataObject = {};
    const props = [];
    for (const c of columns) {
      if (get(c, 'type') !== 'jsonb') continue;
      const propertyName = get(c, 'propertyName');
      const defaultVal = get(c, 'default');
      defaultDataObject[propertyName] = defaultVal;
      props.push(propertyName);
    }
    // console.group(get(model, 'name'));
    // console.log(defaultDataObject);
    // console.log(props);
    if (props.length <= 0) return;
    const builder = model.createQueryBuilder();
    for (let i = 0; i < props.length; i++) {
      const prop = props[i];
      if (i === 0) {
        builder.where(`"${prop}" Is NULL`);
      } else {
        builder.orWhere(`"${prop}" Is NULL`);
      }
    }
    const list = await builder.getMany();
    for (const i of list) {
      const updateData = {};
      for (const p of props) {
        const val = get(i, p);
        if (this.isNoValue(val)) updateData[p] = defaultDataObject[p];
      }
      await model.update(i.id, updateData);
      this.count = this.count + 1;
    }
    // console.groupEnd();
  }
}
