const fs = require('fs')

const conf = require('../config')
const com = require('@god/node-com')

const axios = require('axios')
const AdmZip = require('adm-zip')

/* 支持 finally函数 */
require('promise.prototype.finally').shim()

/* 通过API统一过拦截器，接口代理转发请求 */
const agentProcessor = () => {
  /* 目录在服务器，启动时，直接创建号 */
  let _totalDir = '001' // 默认表示，存储从第一学期开始
  com.Tool.Directory.mkdir('upload_tmp/' + _totalDir)

  return (req, res) => {
    /* 获取 日志必须 返回 + 视频行为日志信息 */
    const _logJson = com.Log.EzijingVideo.setLogVideo(req, {
      _totalDir
    })

    let headers = req.headers
    let options = {}
    /* 删除一些 不必要属性 */
    let pwdBase64 = headers['pmd5'] || ''
    delete headers['pmd5'] // pwd base64
    try {
      options = {
        timeout: 60 * 1000,
        url: req.params[0], // .replace(/tenant\//gi, '')
        baseURL: conf.agentApiUrl,
        method: req.method,
        data: req.body,
        params: req.query
      }
      options.url = options.url.replace(/tenant\//gi, '')
      headers['apikey'] = conf.apiKey
      if (/user_center/gi.test(options.url)) {
        headers['Host'] = 'sso.ezijing.com'
        headers['host'] = 'sso.ezijing.com'
      } else {
        // headers['Host'] = 'lms-api.ezijing.com'
        // headers['host'] = 'lms-api.ezijing.com'
        headers['Host'] = conf.host
        headers['host'] = conf.host
      }
      /* 测试 */
      // if (/\/essay/gi.test(options.url) && /post/gi.test(req.method)) {
      //   console.time('essay')
      //   options.baseURL = 'http://192.168.10.199:8081/'
      //   options.url = options.url.replace(/tenant\//gi, '')
      //   console.log(options.baseURL + options.url)
      // }
      headers['accept'] = '*/*'
      delete headers['accept-language']
      com.Tool.ReqType.toUrlEncoded(req, options)
      let _fileName = com.Tool.ReqType.toFormData(req, options)

      /* 获取cookie,解析SUP，设置token */
      headers['ticket'] = com.Tool.Cookie.getTicketByCAS('_SUP', req) // _SUP获取
      headers['token'] = headers['ticket']

      axios.defaults.headers = headers
      axios.defaults.withCredentials = true

      /* 处理特殊请求,在域名为e-learing2时生效 */
      // let _stoken = com.Tool.Cookie.getCookie('_SUP', req)
      // if (_stoken) {
      //   headers['stoken'] = _stoken
      // }

      /* 重新转发请求 */
      let _reqTime = 0
      let _status = 0
      axios(options)
        .then((data) => {
          /* 记录 请求处理时长 + 请求状态 */
          _reqTime =
            new Date().getTime() - _logJson._nodeServerCurrentTime + 'ms'
          _status = 200

          // /* 兼容老版本，登录接口 清除_SUP; 退出登录 清除_SUP */
          /* 重新修改，改为只能服务端 设置 cookie */
          if (
            /user_center\/login/gi.test(options.url) ||
            /user_center\/code_login/gi.test(options.url)
          ) {
            com.Tool.Cookie.setTicketByCAS(
              '_SUP',
              '.ezijing.com',
              data.data.ticket,
              res
            )
            com.Tool.Cookie.setCookie('_AUTH', '.ezijing.com', pwdBase64, res)
          }
          if (/user_center\/logout/gi.test(options.url)) {
            res.clearCookie('_SUP', { path: '/', domain: '.ezijing.com' })
            res.clearCookie('_AUTH', { path: '/', domain: '.ezijing.com' })
          }
          /* 如果是大作业提价，先docx解析，解析不出来则报错 */
          if (
            /util\/upload-file/gi.test(options.url) &&
            req.body.special &&
            req.body.special === 'course-work'
          ) {
            let _strContent = ''
            let contentXml = null
            try {
              let zip = new AdmZip(_fileName[0]) // filePath为文件路径
              contentXml = zip.readAsText('word/document.xml') // 将document.xml读取为text内容；
              _strContent = contentXml.replace(/<[/]{0,1}\w[^>]*>/gi, '')
              // contentXml.match(/<w:t[^>]*?>[\s\S]*?<\/w:t>/ig).forEach((item) => {
              // _strContent += item.slice(5, -6) // 不能换行，应该是 解析某些换行规则会比较慢
              // })
              data.data.dataStr = Buffer.from(_strContent, 'utf8').toString(
                'base64'
              )
            } catch (e) {
              res.status(500).json({
                message:
                  '文档上传出错，错误原因：请不要直接修改后缀“.doc”为“.docx”或者正文内容必须大于400字',
                errMsg: 'err',
                code: 500
              })
              return
            }
          }

          /* getInfo 时，则写入 用户基本信息 */
          if (/user_center\/get_user_info/gi.test(options.url)) {
            /* check-access接口 */
            // headers['Host'] = 'lms-api.ezijing.com'
            // headers['host'] = 'lms-api.ezijing.com'
            headers['Host'] = conf.host
            headers['host'] = conf.host
            axios.defaults.headers = headers
            axios({
              timeout: 30 * 1000,
              url: 'user/check-access',
              baseURL: conf.agentApiUrl,
              method: 'GET',
              data: {},
              params: ''
            })
              .then((_data) => {
                if (_data.data.id) {
                  data.data['auth_key'] = headers['token']
                  data.data['id'] = headers['uid']
                  data.data.student_info = _data.data
                  let _name =
                    (data.data.student_info &&
                      data.data.student_info.personal_name) ||
                    data.data.nickname
                  let _email =
                    (data.data.student_info && data.data.student_info.email) ||
                    data.data.email
                  com.Log.EzijingVideo.writeBasicInfo(req, _logJson, {
                    _name, // 用于重新 定位学生目录
                    _email, // 用于重新 定位学生目录
                    _totalDir // 用于重新 定位学生目录
                  })
                  res.status(200).send(data.data)
                } else {
                  res.status(403).send({
                    name: 'Unauthorized',
                    message: '非学习系统用户，请联系管理员',
                    code: 0,
                    status: 401
                  })
                }
              })
              .catch((e) => {
                try {
                  res.status(e.response.status).send(e.response.data)
                } catch (e) {
                  res.status(500).send({
                    name: 'undefined',
                    message: '接口请求异常',
                    code: 0,
                    status: 500
                  })
                }
              })
          } else {
            res.status(200).send(data.data)
          }
        })
        .catch((e) => {
          /* 记录 请求处理时长 + 请求状态 */
          _reqTime =
            new Date().getTime() - _logJson._nodeServerCurrentTime + 'ms'
          _status = (e.response && e.response.status) || 500

          /* 未登录，则全部清空 _SUP */
          if (e.response && e.response.status === 403) {
            res.clearCookie('_SUP', { path: '/', domain: '.ezijing.com' })
            res.clearCookie('_AUTH', { path: '/', domain: '.ezijing.com' })
          }
          /* 返回执行代码出错 或者 服务器请求错误 */
          if (e.response && e.response.data) {
            /* 如果未登录 强制 弹出到 登录页 */
            // setPorxyHeader(e.response, res)
            res.status(e.response.status).json(e.response.data)
            console.error(
              _logJson._uuid +
                String.fromCharCode(0x001) +
                JSON.stringify(options) +
                String.fromCharCode(0x001) +
                JSON.stringify(axios.defaults.headers) +
                String.fromCharCode(0x001) +
                JSON.stringify(e.response.data)
            )
          } else {
            res.status(500).json({
              message: '系统错误，请稍后重试或联系管理员',
              errMsg: 'Error Proxy Request or BackData Excute Error',
              code: 500
            })
            console.error(_logJson._uuid, e)
          }
        })
        .finally(() => {
          /* 请求结束，删除服务器端 缓存文件 */
          if (_fileName.length) {
            for (let i = 0; i < _fileName.length; i++) {
              fs.unlinkSync(_fileName[i])
            }
          }
          /* 视频行为日志 写入 */
          com.Log.EzijingVideo.writeLogVideo(_logJson, {
            _reqTime,
            _status
          })
        })
    } catch (e) {
      res.status(500).json({
        message: '系统错误，请稍后重试或联系管理员',
        errMsg: 'Network Server Excute Error',
        code: 500
      })
      console.error(_logJson._uuid, e)
    }
  }
}

module.exports = {
  agentProcessor: agentProcessor
}
