const projectsService = require('../service/projects.service');
const pagesRoleService = require('../service/pagesRole.service');
const pagesService = require('../service/pages.service');
const menuService = require('../service/menu.service');
const roleService = require('../service/roles.service');
const projectUserService = require('../service/project.user.service');
const templateUserService = require('../service/templates.service');
const pageService = require('../service/pages.service');
const publishService = require('../service/publish.service');
const request = require('../utils/request');
const util = require('../utils/util');
const { MODEL_BASE_URL } = require('../config');

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

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

  // mars-admin 项目列表
  async getProjectList(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 projectsService.getProjectCount(template, uid);
    if (total == 0) {
      return util.success(ctx, {
        list: [],
        total: 0,
        pageSize: +pageSize,
        pageNum: +pageNum,
      });
    }
    const list = await projectsService.getProjectList(pageNum, pageSize, template, uid);

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

  async create(ctx) {
    const { id, ...params } = ctx.request.body;
    const { userId, userName } = util.decodeToken(ctx);
    if (id) {
      if (!util.isNumber(id)) {
        return ctx.throw(400, '模板ID格式异常');
      }
      const project = await projectsService.getProjectByTemplateId(id);
      if (!project) {
        return ctx.throw(400, '模板不存在');
      }
      const insertRecord = await projectsService.installProject({
        ...project,
        userId,
        userName,
        name: params.name || project.name,
        remark: params.remark || project.remark,
        logo: params.logo || project.logo,
      });
      let dictMap = {};
      // 开启模型服务后,需要复制模型
      if (ENABLE_MODEL_SERVICE) {
        // 获取项目模型列表
        const res = await request
          .post(
            `${MODEL_BASE_URL}/api/model/copy`,
            JSON.stringify({
              oldProjectId: String(project.id),
              newProjectId: String(insertRecord.insertId),
            }),
            {
              headers: {
                authorization: ctx.request.headers?.authorization,
              },
            },
          )
          .catch((error) => {
            ctx.throw(400, '模型创建失败:' + error);
          });
        const result = JSON.parse(res.data);
        dictMap = result.oldNewDataDictionaryIdMap;
      }

      // 获取模板菜单列表
      const menusList = await menuService.getMenuByTemplateId(project.id);
      const originIdMap = {};
      let rootList = menusList.filter((menu) => !menu.parentId);

      // 递归创建菜单和页面
      while (rootList.length) {
        const parentIds = [];
        for (let menu of rootList) {
          // 保存父级菜单id
          parentIds.push(menu.id);
          if (menu.pageId) {
            // 获取菜单绑定的页面信息
            const page = await pagesService.getPagesById(menu.pageId);
            let pageRecord = { pageId: 0 };
            if (page) {
              page.pageData &&
                Object.keys(dictMap).forEach((key) => {
                  page.pageData = page.pageData.replaceAll(`"dataDictionaryKey":"${key}"`, `"dataDictionaryKey":"${dictMap[key]}"`);
                });
              // 写入页面数据
              pageRecord = await pagesService.createPage(page.name, userId, userName, page.remark, page.pageData, insertRecord.insertId);
            }
            // 写入菜单数据
            const newRecord = await menuService.create({
              ...menu,
              parentId: originIdMap[menu.parentId],
              userId,
              userName,
              projectId: insertRecord.insertId,
              pageId: pageRecord.insertId,
            });
            originIdMap[menu.id] = newRecord.insertId;
          } else {
            const newRecord = await await menuService.create({
              ...menu,
              parentId: originIdMap[menu.parentId],
              userId,
              userName,
              projectId: insertRecord.insertId,
            });
            originIdMap[menu.id] = newRecord.insertId;
          }
        }
        // 获取下一级菜单
        rootList = menusList.filter((menu) => parentIds.find((pid) => pid === menu.parentId));
      }
      await templateUserService.updateInstallCount(id);
      util.success(ctx, '同步成功');
    } else {
      if (!params.name) {
        return ctx.throw(400, '项目名称不能为空');
      }

      if (!params.remark) {
        return ctx.throw(400, '项目描述不能为空');
      }

      if (!params.logo) {
        return ctx.throw(400, '项目logo不能为空');
      }
      await projectsService.createProject({
        ...params,
        userId,
        userName,
      });
      util.success(ctx);
    }
  },

  async delete(ctx) {
    const { id, type } = ctx.request.body;
    if (!util.isNumber(id)) {
      return ctx.throw(400, 'id参数不正确');
    }
    const { userId } = util.decodeToken(ctx);
    const [projectInfo] = await projectsService.getProjectInfoById(+id);
    if (!projectInfo || projectInfo.userId != userId) {
      return ctx.throw(400, '您暂无权限删除该项目');
    }
    // 删除项目本身
    const res = await projectsService.deleteProject(id, userId);
    // 删除项目对应开发者权限
    await pagesRoleService.deleteByPageId(id);
    // 删除项目菜单
    await menuService.deleteMenuByProjectId(id);
    // 删除项目角色
    await roleService.deleteByProjectId(id);
    // 删除项目对应访问者权限
    await projectUserService.deleteUserByProjectId(id);
    // 删除模型表
    await request.delete(`${MODEL_BASE_URL}/api/model/projectId/${id}`, {
      headers: {
        authorization: ctx.request.headers?.authorization,
      },
    });
    if (type == 'all') {
      await pagesService.deletePageByProjectId(id, userId);
    } else {
      await pagesService.updatePageForProjectId(id);
    }
    if (res.affectedRows > 0) {
      util.success(ctx);
    } else {
      return ctx.throw(400, '当前暂无权限');
    }
  },

  async update(ctx) {
    const { id, name, remark, logo } = ctx.request.body;
    if (!util.isNumber(id)) {
      return ctx.throw(400, 'id参数不正确');
    }
    if (!name) {
      return ctx.throw(400, '项目名称不能为空');
    }
    if (!remark) {
      return ctx.throw(400, '项目描述不能为空');
    }
    if (!logo) {
      return ctx.throw(400, '项目logo不能为空');
    }

    await projectsService.updateProjectInfo(ctx.request.body);
    util.success(ctx);
  },

  // 检查是否有项目权限
  async checkProjectAuth(ctx) {
    const { id } = ctx.request.body;
    if (!util.isNumber(id)) {
      return ctx.throw(400, '项目ID不正确');
    }
    const { userId } = util.decodeToken(ctx);
    const list = await projectsService.checkAuth(id);
    if (list.length === 0) {
      return util.success(ctx, '404');
    }
    if (list[0].userId !== userId && list.filter((item) => item.devUserId === userId).length === 0) {
      return util.success(ctx, '403');
    }
    util.success(ctx, '');
  },

  async detail(ctx) {
    const { id } = ctx.params;
    if (!util.isNumber(id)) {
      return ctx.throw(400, '项目ID不能为空');
    }
    const info = await projectsService.getProjectInfoById(id);
    if (!info?.length) {
      return util.fail(ctx, '当前项目不存在', 404);
    }

    util.success(ctx, info[0]);
  },

  /**
   * 项目下页面列表 - 一键发布
   */
  async oneClickPublishing(ctx) {
    const { userId, userName } = util.decodeToken(ctx);
    const { id } = ctx.request.body;
    if (!util.isNumber(id)) {
      return ctx.throw(400, '项目ID不能为空');
    }
    const info = await projectsService.getProjectInfoById(id);
    if (!info?.length) {
      return util.fail(ctx, '当前项目不存在', 404);
    }
    const authList = await projectsService.checkAuth(id);
    if (authList.length === 0) {
      util.success(ctx, '暂无发布权限');
      return false;
    }
    if (authList[0].userId !== userId && authList.filter((item) => item.devUserId === userId).length === 0) {
      util.success(ctx, '暂无发布权限');
      return false;
    }
    const ids = await pageService.getPageIdsByProjectId(Number(id));
    for (let { id: pageId } of ids) {
      // 获取菜单绑定的页面信息
      const page = await pagesService.getPagesById(pageId);
      // 只发布有数据和未发布的页面
      if (page && page.pageData && page.stgState != 3) {
        const result = await publishService.createPublish(pageId, page.name, page.pageData, userName, userId, 'stg');
        await pagesService.updatePageState(result.insertId, pageId, 'stg', '');
      }
    }
    util.success(ctx, '发布成功');
  },
};