import { Controller, Context } from 'egg';
import _, { omitBy } from 'lodash';
import { v1 as uuidv1 } from 'uuid';
import { PageHistory } from '../model/pageHistory';
export default class EditorController extends Controller {

  public async login(ctx: Context) {
    await ctx.renderClient('login.js', {});
  }

  public async home(ctx: Context) {
    const apollo = ctx.app.config.apollo || {};
    await ctx.renderClient('editor.js', { apollo });
  }

  public async save(ctx: Context) {
    const pageInfo = ctx.request.body;
    try {
      const result = await ctx.model.PageInfo.create({ ...pageInfo, uuid: uuidv1().replace(/-/g, ''), tenantId: ctx.headers['qg-tenant-id']});
      const { uuid, id } = result.dataValues;
      await ctx.model.PageHistory.create({ ...pageInfo, uuid, pageId: id, tenantId: ctx.headers['qg-tenant-id']});
      ctx.body = ctx.helper.ok(result);
      await ctx.service.redis.del(`pageInfo:${uuid}`);
      await ctx.service.redis.del(`page:${uuid}`);
    } catch (error) {
      if (error.message.indexOf('Data too long') > -1 && error.message.indexOf('page_data') > -1) {
        error.message = '配置组件过多，请对组件进行删减';
      }
      ctx.body = ctx.helper.fail(error);
    }
  }

  public async update(ctx: Context) {
    const pageInfo = ctx.request.body;
    if (!pageInfo.uuid) {
      pageInfo.uuid = uuidv1().replace(/-/g, '');
    }
    if (ctx.headers['qg-tenant-id']) {
      pageInfo.tenantId = +ctx.headers['qg-tenant-id'];
    }
    const uuid = pageInfo.uuid;
    try {
      const result = await ctx.model.PageInfo.update(pageInfo, {where: { uuid: pageInfo.uuid, tenantId: ctx.headers['qg-tenant-id'] }});
      const pageData = await ctx.model.PageInfo.findOne({where: { uuid }});
      const pageId = pageData.id;
      await ctx.model.PageHistory.create({ ...pageInfo, uuid, pageId, tenantId: ctx.headers['qg-tenant-id']});
      await ctx.service.redis.del(`pageInfo:${uuid}`);
      await ctx.service.redis.del(`page:${uuid}`);
      ctx.body = ctx.helper.ok(result);
    } catch (error) {
      if (error.message.indexOf('Data too long') > -1 && error.message.indexOf('page_data') > -1) {
        error.message = '配置组件过多，请对组件进行删减';
      }
      ctx.body = ctx.helper.fail(error);
    }
  }
  // todo 编辑器获取跳过redis，但需要注意
  public async get(ctx: Context) {
    const { isEditor } = ctx.query;
    let pageInfo = isEditor ? null : await ctx.service.redis.get(`pageInfo:${ctx.params.uuid}`);
    if (!pageInfo) {
      pageInfo = await ctx.model.PageInfo.findOne({where: { uuid: ctx.params.uuid }});
      // console.log('sql', pageInfo);

      if (ctx.query.lite && pageInfo) {
        // 如果存在sheme移除掉
        const page = JSON.parse(pageInfo.page || []);
        for (let i = 0; i < page.elements.length; i++) {
          delete page.elements[i].schame
        }
        if (page.scheme) {
          delete page.scheme;
        }
        pageInfo.page = JSON.stringify(page);
      }
      await ctx.service.redis.set(`pageInfo:${ctx.params.uuid}`, pageInfo);
    }
    ctx.body = ctx.helper.ok(pageInfo);
  }

  public async getList(ctx: Context) {
    const { type, pageSize, pageNo, author, pageName, isPublish, pageDescribe, uuid } = ctx.query;
    const { like } = ctx.model.Sequelize.Op;
    let where = omitBy({
      author: author && { like: `%${author}%`},
      pageName: pageName && { like: `%${pageName}%`},
      pageDescribe: pageDescribe && { like: `%${pageDescribe}%`},
      isPublish,
      uuid,
      tenantId: ctx.headers['qg-tenant-id'],
      enable: 1
    }, v => !v);
    if (type === 'list') {
      where = { ...where, isPublish: 1 };
    } else if (type === 'my') {
      where = { ...where };
    } else if (type === 'template') {
      where = { ...where, isTemplate: 1 };
    }
    const { count: total, rows: data } = await ctx.model.PageInfo.findAndCountAll({ where, limit: +pageSize || 10,
      offset: (+pageNo - 1) * +pageSize || 0,  order: [['updated_at', 'DESC']], include: [PageHistory.scope('relative')]});
    data.map(item => {
      item.pageHistory && item.pageHistory.reverse();
    })
    ctx.body = ctx.helper.ok({ total, data });
  }

  public async getTemplateList(ctx: Context) {
    const list = await ctx.model.PageInfo.findAll({ where: { isTemplate: 1, tenantId: ctx.headers['qg-tenant-id'] } });
    ctx.body = ctx.helper.ok(list);
  }

  public async clearCache(ctx: Context) {
    const where = {
      updated_at: {
        [ctx.model.Sequelize.Op.lt]: Date.now(),
        [ctx.model.Sequelize.Op.gt]: new Date(Date.now() - 1000 * 60 * 60 * 24 * 30)
      },
      tenantId: ctx.headers['qg-tenant-id'],
      enable: 1,
      isPublish: 1
    };
    const pageInfo = await ctx.model.PageInfo.findAll({
      attributes: ['uuid'],
      where
    });
    for (const item of pageInfo) {
      await ctx.service.redis.del(`page:${item.uuid}`);
      await ctx.service.redis.del(`pageInfo:${item.uuid}`);
      ctx.logger.info(`del redis page key page:${item.uuid}`);
    }
    ctx.body = ctx.helper.ok();
  }

  public async delete(ctx: Context) {
    const pageInfo = await ctx.model.PageInfo.update({ enable: 0 }, {where: { id: +ctx.params.pageId, tenantId: ctx.headers['qg-tenant-id'] }});
    const pageData = await ctx.model.PageInfo.find({where: { id: +ctx.params.pageId, tenantId: ctx.headers['qg-tenant-id'] }});
    await ctx.model.PageHistory.destroy({where: { pageId: pageData.dataValues.id }});
    ctx.body = ctx.helper.ok(pageInfo);
  }
  public async getServerTime(ctx: Context) {
    ctx.body = ctx.helper.ok(new Date().getTime());
  }
  // 恢复历史记录
  public async recoverPageData(ctx: Context) {
    const params = ctx.request.body;
    const id = params.id;
    const author = params.author;
    console.log(params)
    if (!id) {
      ctx.body = {};
      return;
    }
    const pageData = await ctx.model.PageHistory.findOne({where: {id: +id, tenantId: ctx.headers['qg-tenant-id']}})
    const data = Object.assign({}, pageData.dataValues);
    // 记录当前操作人
    data.author = author;
    delete data.updatedAt;
    delete data.createdAt;
    // 更新主表行数据
    const uuid = pageData.uuid;
    const updateData = Object.assign({}, data);
    delete updateData.uuid;
    delete updateData.pageId;
    delete updateData.id;
    await ctx.model.PageInfo.update(updateData, {where: { uuid: uuid, tenantId: ctx.headers['qg-tenant-id'] }});
    await ctx.service.redis.del(`pageInfo:${uuid}`);
    await ctx.service.redis.del(`page:${uuid}`);
    // 创建新历史记录
    const historyData = Object.assign({}, data);
    delete historyData.id;
    
    await ctx.model.PageHistory.create(historyData);
    ctx.body = ctx.helper.ok({});
  }
  // 获取历史记录页面预览信息
  public async getHistoryPreviewData(ctx: Context) {
    const pageInfo = await ctx.model.PageHistory.findOne({where: { id: ctx.params.id }});
    // console.log('sql', pageInfo);
    if (ctx.query.lite && pageInfo) {
      // 如果存在sheme移除掉
      const page = JSON.parse(pageInfo.page || []);
      for (let i = 0; i < page.elements.length; i++) {
        delete page.elements[i].schame
      }
      if (page.scheme) {
        delete page.scheme;
      }
      pageInfo.page = JSON.stringify(page);
    }
    ctx.body = ctx.helper.ok(pageInfo);
  }
}