const pageService = require('../service/pages.service');
const pagesRoleService = require('../service/pagesRole.service');
const userService = require('../service/user.service');
const templateService = require('../service/templates.service');
const request = require('../utils/request');
const util = require('../utils/util');
const { MODEL_BASE_URL, ENABLE_MODEL_SERVICE } = require('../config');

module.exports = {
  async list(ctx) {
    const { userId } = util.decodeToken(ctx);
    const { pageNum, pageSize, keyword, projectId } = ctx.request.query;
    const { total } = await pageService.listCount(keyword, userId, Number(projectId));
    if (total == 0) {
      return util.success(ctx, {
        list: [],
        total: 0,
        pageSize: +pageSize || 12,
        pageNum: +pageNum || 1,
      });
    }
    const list = await pageService.list(pageNum || 1, pageSize || 12, keyword, userId, Number(projectId));

    util.success(ctx, {
      list,
      total,
      pageSize: +pageSize,
      pageNum: +pageNum,
    });
  },

  // mars-admin 项目列表
  async getPageList(ctx) {
    const { pageNum = 1, pageSize = 10, isTemplate, userId } = ctx.request.query;
    const template = util.isNumber(isTemplate) ? Number(isTemplate) : '';
    const uid = util.isNumber(userId) ? Number(userId) : '';
    const { total } = await pageService.getPageCount(template, uid);
    if (total == 0) {
      return util.success(ctx, {
        list: [],
        total: 0,
        pageSize: +pageSize,
        pageNum: +pageNum,
      });
    }
    const list = await pageService.getPageList(pageNum, pageSize, template, uid);
    util.success(ctx, {
      list,
      total,
      pageSize: +pageSize,
      pageNum: +pageNum,
    });
  },

  async listPageTemplate(ctx) {
    const { pageNum, pageSize, keyword } = ctx.request.query;
    const { total } = await pageService.listPageTemplateCount(keyword);
    if (total == 0) {
      return util.success(ctx, {
        list: [],
        total: 0,
        pageSize: +pageSize || 12,
        pageNum: +pageNum || 1,
      });
    }
    const list = await pageService.listPageTemplate(pageNum || 1, pageSize || 12, keyword);
    util.success(ctx, {
      list,
      total,
      pageSize: +pageSize,
      pageNum: +pageNum,
    });
  },

  async detail(ctx) {
    const { id } = ctx.request.params;
    if (!util.isNumber(id)) {
      return ctx.throw(400, '页面ID不能为空');
    }
    const { userId } = util.decodeToken(ctx);
    // 查询页面信息
    const [pageInfo] = await pageService.getPageInfoById(+id);
    if (!pageInfo) {
      return util.fail(ctx, '当前页面不存在', 404);
    }
    // 查询页面开发者
    const list = await pagesRoleService.getPagesRoleList([id, pageInfo.projectId].join(','));
    // 如果不是创建者,又不是开发者,无法访问
    if (pageInfo.userId !== userId && list.filter((item) => item.userId === userId && item.role === 1).length === 0) {
      return util.fail(ctx, '您当前暂无查看权限', 403);
    }
    util.success(ctx, pageInfo || {});
  },

  async copy(ctx) {
    const { userId, userName } = util.decodeToken(ctx);
    const { id, name, remark, projectId } = ctx.request.body;
    if (!util.isNumber(id)) {
      return ctx.throw(400, '页面ID不能为空');
    }
    if (!name) {
      return ctx.throw(400, '页面名称不能为空');
    }
    if (!util.isNumber(projectId)) {
      return ctx.throw(400, '项目ID不能为空');
    }
    const [pageInfo] = await pageService.getPageInfoById(+id);
    if (!pageInfo) {
      return util.fail(ctx, '页面不存在', 404);
    }
    const { pageData, appType } = pageInfo;
    await pageService.createPage(name, userId, userName, remark, pageData, projectId, appType);
    util.success(ctx);
  },

  async delete(ctx) {
    const { id } = ctx.request.body;
    if (!util.isNumber(id)) {
      return ctx.throw(400, '页面ID不能为空');
    }
    const { userId } = util.decodeToken(ctx);
    const [pageInfo] = await pageService.getPageSimpleById(+id);
    if (!pageInfo || pageInfo.userId !== userId) {
      return util.fail(ctx, '您暂无权限删除该页面');
    }
    const res = await pageService.deletePage(id, userId);
    await pagesRoleService.deleteByPageId(id);
    if (res.affectedRows > 0) {
      util.success(ctx);
    } else {
      return ctx.throw(400, '当前暂无权限', 403);
    }
  },

  async create(ctx) {
    const { userId, userName } = util.decodeToken(ctx);
    const { name, remark, projectId, id, appType = 1 } = ctx.request.body;
    if (!name) {
      return ctx.throw(400, '页面名称不能为空');
    }
    if (!util.isNumber(projectId)) {
      return ctx.throw(400, '项目ID不能为空');
    }

    if (id) {
      if (!util.isNumber(id)) {
        return ctx.throw(400, '模板ID格式异常');
      }
      const page = await pageService.getPageByTemplateId(id);
      if (!page) {
        return ctx.throw(400, '模板不存在', 404);
      }
      // 开启模型服务后,需要复制模型
      if (ENABLE_MODEL_SERVICE) {
        // 获取项目模型列表
        const res = await request.post(
          `${MODEL_BASE_URL}/api/model/model/copy`,
          JSON.stringify({
            oldProjectId: String(page.projectId),
            newProjectId: String(projectId),
          }),
          {
            headers: {
              authorization: ctx.request.headers?.authorization,
            },
          },
        );
        if (res.status !== 200) {
          return ctx.throw(400, '模型创建失败');
        }
        const result = JSON.parse(res.data);
        const dictMap = result.oldNewDataDictionaryIdMap;
        page.pageData &&
          Object.keys(dictMap).forEach((key) => {
            page.pageData = page.pageData.replaceAll(`"dataDictionaryKey":"${key}"`, `"dataDictionaryKey":"${dictMap[key]}"`);
          });
      }
      await pageService.createPage(name, userId, userName, remark, page.pageData, projectId, appType);
      await templateService.updateInstallCount(id);
      util.success(ctx);
    } else {
      await pageService.createPage(name, userId, userName, remark, '', projectId, appType);
      util.success(ctx);
    }
  },

  async update(ctx) {
    const { id, name, remark = '', pageData, previewImg = '', projectId, isPublic } = ctx.request.body;
    if (!util.isNotEmpty(id)) {
      return ctx.throw(400, '页面ID不能为空');
    }
    const { userId } = util.decodeToken(ctx);
    const [pageInfo] = await pageService.getPageSimpleById(+id);
    if (!pageInfo) {
      return util.fail(ctx, '当前页面不存在', 404);
    }
    // 判断开发者权限
    const list = await pagesRoleService.getPagesRoleList([id, pageInfo.projectId].join(','));
    if (pageInfo.userId !== userId && list.filter((item) => item.userId === userId).length === 0) {
      return util.fail(ctx, '您当前暂无编辑权限', 403);
    }
    await pageService.updatePageInfo(id, name, remark, pageData, previewImg, projectId, isPublic);
    util.success(ctx);
  },

  // 页面角色 - 成员列表
  async roleList(ctx) {
    const { pageId } = ctx.request.body;
    if (!pageId) {
      return ctx.throw(400, '页面ID不能为空');
    }
    const list = await pagesRoleService.getPagesRoleList(pageId);
    util.success(ctx, { list });
  },

  /**
   * 页面或者项目 - 添加成员
   * page_id: 页面ID或者项目ID,共用同一张表
   */
  async roleAdd(ctx) {
    const { type, pageId, role, userName } = ctx.request.body;
    if (!type) {
      return ctx.throw(400, '成员类型不能为空');
    }

    if (!pageId || isNaN(+pageId)) {
      return ctx.throw(400, '页面ID或项目ID不能为空');
    }

    if (!role) {
      return ctx.throw(400, '角色不能为空');
    }

    if (!userName) {
      return ctx.throw(400, '开发者ID或名称不能为空');
    }
    const res = await userService.search(userName);
    if (!res) {
      return ctx.throw(400, '当前用户不存在');
    }
    const { userId: createdUId, userName: createdUName } = util.decodeToken(ctx);
    await pagesRoleService.create(type, pageId, role, res.id, userName, createdUId, createdUName);
    util.success(ctx);
  },

  // 删除页面成员
  async roleDelete(ctx) {
    const { id } = ctx.request.body;
    if (!util.isNumber(id)) {
      return ctx.throw(400, 'ID不能为空');
    }
    await pagesRoleService.delete(id);
    util.success(ctx);
  },

  // 页面回滚
  async rollback(ctx) {
    const { pageId, lastPublishId, env } = ctx.request.body;
    if (!util.isNotEmpty(pageId)) {
      return ctx.throw(400, '页面ID不能为空');
    }

    if (!util.isNotEmpty(lastPublishId)) {
      return ctx.throw(400, '回滚ID不能为空');
    }

    if (!util.checkEnv(env)) {
      return ctx.throw(400, '环境不能为空');
    }
    await pageService.updateLastPublishId(pageId, lastPublishId, env);
    util.success(ctx);
  },
};