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, isUndefined, omit } 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';

@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(Role)
  Role: Repository<Role>;

  @InjectDataSource('default')
  defaultDataSource: DataSource;

  /**初始化用户目录,先去数据库把表清空,顺便重置下id索引 */
  async initUserMenus() {
    await this.UserMenus.query('TRUNCATE TABLE "public"."userMenus" RESTART IDENTITY RESTRICT;');
    await this.defaultDataSource.query(`SELECT setval('"userMenus_id_seq"', (SELECT max(id) FROM "userMenus"));`);
    const datas = [
      {
        order_num: 0,
        name: '基础信息',
        route_name: 'center_basic',
        i18n_code: 'menus.center_basic',
        path: '/center/basic',
        component: '/center/basic',
        type: '1',
        config: [],
        is_default: '0',
        is_use: '0',
        icon: 'User',
      },
      {
        order_num: 1,
        name: '认证入驻',
        route_name: 'center_attestation',
        i18n_code: 'menus.center_attestation',
        path: '/center/attestation',
        component: '/center/attestation',
        type: '1',
        config: [],
        is_default: '0',
        is_use: '0',
        icon: 'Finished',
      },
      {
        order_num: 2,
        name: '通知管理',
        route_name: 'center_notice',
        i18n_code: 'menus.center_notice',
        path: '/center/notice',
        component: '/center/notice',
        type: '1',
        config: [],
        is_default: '0',
        is_use: '0',
        icon: 'Notebook',
      },
      {
        order_num: 3,
        name: '行业动态',
        route_name: 'center_news2',
        i18n_code: 'menus.center_news2',
        path: '/center/news2',
        component: '/center/news2',
        type: '1',
        config: [],
        is_default: '0',
        is_use: '0',
        icon: 'Message',
      },
      {
        order_num: 4,
        name: '需求管理',
        route_name: 'center_demand',
        i18n_code: 'menus.center_demand',
        path: '/center/demand',
        component: '/center/demand',
        type: '1',
        config: [],
        is_default: '0',
        is_use: '0',
        icon: 'DataBoard',
      },
      {
        order_num: 5,
        name: '供给管理',
        route_name: 'center_supply',
        i18n_code: 'menus.center_supply',
        path: '/center/supply',
        component: '/center/supply',
        type: '1',
        config: [],
        is_default: '0',
        is_use: '0',
        icon: 'Notification',
      },
      {
        order_num: 6,
        name: '成果管理',
        route_name: 'center_achievement',
        i18n_code: 'menus.center_achievement',
        path: '/center/achievement',
        component: '/center/achievement',
        type: '1',
        config: [],
        is_default: '0',
        is_use: '0',
        icon: 'Medal',
      },
      {
        order_num: 7,
        name: '项目管理',
        route_name: 'center_project',
        i18n_code: 'menus.center_project',
        path: '/center/project',
        component: '/center/project',
        type: '1',
        config: [],
        is_default: '0',
        is_use: '0',
        icon: 'Trophy',
      },
      {
        order_num: 8,
        name: '中试管理',
        route_name: 'center_footplate',
        i18n_code: 'menus.center_footplate',
        path: '/center/footplate',
        component: '/center/footplate',
        type: '1',
        config: [],
        is_default: '0',
        is_use: '0',
        icon: 'TakeawayBox',
      },
      {
        order_num: 9,
        name: '服务管理',
        route_name: 'center_service',
        i18n_code: 'menus.center_service',
        path: '/center/service',
        component: '/center/service',
        type: '1',
        config: [],
        is_default: '0',
        is_use: '0',
        icon: 'TakeawayBox',
      },
      {
        order_num: 10,
        name: '赛事管理',
        route_name: 'center_match',
        i18n_code: 'menus.center_match',
        path: '/center/match',
        component: '/center/match',
        type: '1',
        config: [],
        is_default: '0',
        is_use: '0',
        icon: 'CollectionTag',
      },
      {
        order_num: 11,
        name: '活动管理',
        route_name: 'center_sign',
        i18n_code: 'menus.center_sign',
        path: '/center/sign',
        component: '/center/sign',
        type: '1',
        config: [],
        is_default: '0',
        is_use: '0',
        icon: 'Suitcase',
      },
      {
        order_num: 12,
        name: '产研行研',
        route_name: 'center_journal',
        i18n_code: 'menus.center_journal',
        path: '/center/journal',
        component: '/center/journal',
        type: '1',
        config: [],
        is_default: '0',
        is_use: '0',
        icon: 'Reading',
      },
      {
        order_num: 998,
        name: '我的收藏',
        route_name: 'center_collection',
        i18n_code: 'menus.center_collection',
        path: '/center/collection',
        component: '/center/collection',
        type: '1',
        config: [],
        is_default: '0',
        is_use: '0',
        icon: 'Collection',
      },
      {
        order_num: 999,
        name: '修改密码',
        route_name: 'center_password',
        i18n_code: 'menus.center_password',
        path: '/center/password',
        component: '/center/password',
        type: '1',
        config: [],
        is_default: '0',
        is_use: '0',
        icon: 'Lock',
      },
    ];
    await this.UserMenus.insert(datas);
  }

  async initRoleMenus() {
    /**
     * 初始化角色的菜单
     * 共有: 基础信息,认证信息,行业动态,
     */
    const common = ['center_basic', 'center_attestation', 'center_notice', 'center_collection', 'center_password', 'center_sign'];
    // 只用通用菜单的角色
    const justCommonRole = ['User', 'Association', 'Investment', 'State'];
    await this.Role.update({ code: In(justCommonRole) }, { menu: common });
    // 第一类菜单
    const menus1 = [...common, 'center_news2', 'center_demand', 'center_supply', 'center_achievement', 'center_project', 'center_footplate', 'center_service'];
    // 第一类菜单用户: 用户,科研机构,孵化基地,企业,高校
    const roleUseMenus1 = ['Expert', 'Unit', 'Incubator', 'Company', 'YX'];
    await this.Role.update({ code: In(roleUseMenus1) }, { menu: menus1 });
    // 创业大赛用户: 需要去掉报名管理,加入赛事管理
    const MatchRole = common.filter(f => f != 'center_sign');
    MatchRole.push('center_match');
    await this.Role.update({ code: In(['Competition']) }, { menu: MatchRole });
  }

  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();
  }
}
