const { v4 } = require('uuid');
const libService = require('../service/lib.service');
const util = require('../utils/util');
const { md5Encry } = require('../utils/sign');
const config = require('../config');
const imgcloud = require('../service/imgcloud.service');

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

  async installList(ctx) {
    const { userId } = util.decodeToken(ctx);
    const list = await libService.installList(userId);
    util.success(ctx, list);
  },

  async detail(ctx) {
    const { id } = ctx.request.params;
    if (!util.isNotEmpty(id)) {
      return ctx.throw(400, '组件id不能为空');
    }
    const { userId } = util.decodeToken(ctx);
    const [result = {}] = await libService.getDetailById(+id, userId);
    util.success(ctx, result);
  },

  async create(ctx) {
    const { tag, name, description = '' } = ctx.request.body;
    const { userId, userName } = util.decodeToken(ctx);
    if (!userId || !userName) {
      return ctx.throw(400, '账号信息异常,请重新登录');
    }
    if (!tag) {
      return ctx.throw(400, '组件标识不能为空');
    }
    if (/^[a-zA-Z]+$/g.test(tag) === false) {
      return ctx.throw(400, '组件标识只支持英文');
    }
    if (!name) {
      return ctx.throw(400, '组件名称不能为空');
    }

    await libService.createLib('MC' + tag, name, description, userId, userName);
    util.success(ctx);
  },

  async delete(ctx) {
    const { id } = ctx.request.params;
    if (!util.isNumber(id)) {
      return ctx.throw(400, '组件id不正确');
    }
    const { userId } = util.decodeToken(ctx);
    const res = await libService.deleteLibById(id, userId);
    if (res.affectedRows > 0) {
      await libService.deletePublishById(id, userId);
      util.success(ctx);
    } else {
      ctx.throw(400, '当前暂无权限');
    }
  },

  async update(ctx) {
    const { id, tag, name, description = '' } = ctx.request.body;
    if (!util.isNumber(id)) {
      return ctx.throw(400, '组件id不正确');
    }

    if (!tag || !name) {
      return ctx.throw(400, '参数异常');
    }
    const { userId } = util.decodeToken(ctx);
    const lib = libService.getOwnLibById(id, userId);
    if (!lib) return ctx.throw(400, '暂无权限修改');
    await libService.updateLib(tag, name, description, id);
    util.success(ctx);
  },

  async save(ctx) {
    const { id, reactCode, lessCode, configCode, mdCode, hash } = ctx.request.body;
    if (!util.isNumber(id)) {
      return ctx.throw(400, '组件id不正确');
    }

    if (!reactCode) {
      return ctx.throw(400, '源码不能为空');
    }

    if (!configCode) {
      return ctx.throw(400, '组件配置不能为空');
    }
    const { userId } = util.decodeToken(ctx);
    const lib = libService.getOwnLibById(id, userId);
    if (!lib) return ctx.throw(400, '暂无权限保存');

    await libService.saveLib({
      reactCode,
      lessCode,
      configCode,
      mdCode,
      hash,
      id,
    });
    util.success(ctx);
  },

  async publish(ctx) {
    const { libId, reactCompile, configCode, cssCompile, releaseHash } = ctx.request.body;
    if (!util.isNumber(libId)) {
      return ctx.throw(400, '组件id不正确');
    }

    if (!reactCompile) {
      return ctx.throw(400, 'react代码不能为空');
    }

    if (!configCode) {
      return ctx.throw(400, '组件配置不能为空');
    }

    if (!releaseHash) {
      return ctx.throw(400, '缺少hash参数');
    }

    const { userId, userName } = util.decodeToken(ctx);
    const detail = await libService.getPublishByLibId(libId);
    const jsName = md5Encry(userId + reactCompile + Date.now()) + '.js';
    const cssName = md5Encry(userId + cssCompile + Date.now()) + '.css';
    const configName = md5Encry(userId + configCode + Date.now()) + '.js';
    await util.uploadString(userId, jsName, reactCompile);
    await util.uploadString(userId, cssName, cssCompile);
    await util.uploadString(userId, configName, configCode);
    let prefix = config.OSS_CDNDOMAIN;
    if (config.OSS_TYPE === 'minio') {
      prefix = `${config.OSS_USESSL ? 'https://' : 'http://'}${config.OSS_ENDPOINT}:${config.OSS_PORT}/${config.OSS_BUCKET}`;
    } else if (config.OSS_TYPE === 'baidu') {
      if (config.OSS_CDNDOMAIN) {
        prefix = config.OSS_CDNDOMAIN;
      } else {
        prefix = config.OSS_ENDPOINT;
      }
    } else {
      if (config.OSS_CDNDOMAIN) {
        prefix = config.OSS_CDNDOMAIN;
      } else {
        prefix = `https://${config.OSS_BUCKET}.${config.OSS_REGION}.aliyuncs.com`;
      }
    }
    const reactUrl = `${prefix}/libs/${userId}/${jsName}`;
    const cssUrl = `${prefix}/libs/${userId}/${cssName}`;
    const configUrl = `${prefix}/libs/${userId}/${configName}`;
    if (detail) {
      if (detail && detail.releaseHash === releaseHash) {
        return ctx.throw(400, '当前已经是最新版本');
      }
      await libService.updateLibPublish({
        libId,
        reactUrl,
        cssUrl,
        configUrl,
        releaseHash,
      });
    } else {
      const id = v4();
      await libService.publish({
        libId,
        releaseId: id,
        reactUrl,
        cssUrl,
        configUrl,
        releaseHash,
        userId,
        userName,
      });
    }
    await imgcloud.create(userId, userName, jsName, jsName, 'application/javascript', Buffer.byteLength(reactCompile, 'utf8'), reactUrl);
    await imgcloud.create(userId, userName, cssName, cssName, 'text/css', Buffer.byteLength(cssCompile, 'utf8'), cssUrl);
    await imgcloud.create(userId, userName, configName, configName, 'application/javascript', Buffer.byteLength(configCode, 'utf8'), configUrl);
    util.success(ctx);
  },
};