'use strict';
var path = require('path');
var fs = require('fs');
const debug = require('debug')('info');
var Utils = require('../utils');
var Parse = require('../utils/parse');
var Read = require('../utils/read');
var shelljs = require('shelljs');
var co = require('co');
var log = require('../utils/log');
var _ = require('lodash');
const sysConfig = require('../../config');
const userConfig = require('../../config/user');
const i18n = require('../i18n_json');
const getLocale = require('../utils/locale').getLocale;

function write(path, json) {
  return fs.writeFileSync(path, JSON.stringify(json, null, 2), 'utf8');
}

function end(code, str, data) {
  var res = {
    data: data
  };
  if (code === 1) {
    res.code = code;
    res.isError = false;
    res.message = str || 'success';
  } else {
    res.code = code;
    res.isError = true;
    res.message = str || 'error';
  }
  return JSON.stringify(res);
}

module.exports = function (router, source) {
  var configUrl = path.join(source, '/package.json');

  router.get('/', function (req, res, next) {
    res.redirect('/index.html');
  });

  router.get('/index.html', function (req, res, next) {
    const config = Read.file(configUrl, res);
    const datav = Parse.convertDatav(config.datav, res, source);

    const logged = userConfig.loggedin;
    const user = logged && userConfig[userConfig.loggedin];
    const region = user && user.region || sysConfig.regionDefault;
    const locale = getLocale(userConfig, sysConfig);

    if (datav.children) {
      var childrenList = _getChildrenList(datav.children && datav.children.default, source, {locale}, res);
    }

    res.render('index.html', {
      name: config.name,
      version: config.version,
      _dir: config.main || 'index.js',
      datav: JSON.stringify(datav),
      children: childrenList || null,
      i18n: JSON.stringify(i18n.getAll()),
      region: region,
      locale,
      server: (user && user.server || sysConfig.serverDefault) + 'cube'
    });
  });

  router.post('/publish', function (req, res, next) {
    const logged = userConfig.loggedin;
    if (!logged) {
      res.end(end(0, i18n.get('publish.loginMessage')));
      return;
    }

    var config = Read.file(configUrl, res);
    var data = req.body;
    config.datav.view = data.view;

    if (data.type === '' || !data.type) {
      res.end(end(0, i18n.get('preview.typeErrorMessage')));
    }
    config.datav.type = [data.type];
    config.version = data.version;
    if (data.icon) {
      config.datav.icon = data.icon;
    }

    if (config.datav.protocol >= 2) {            // 为handler fold 位置修改的兼容代码
      Parse.fixConfig(config.datav.config);
    }

    write(configUrl, config);

    try {
      shelljs.config.verbose = false;
      shelljs.config.silent = true;
      shelljs.exec('datav pbl', {timeout: 1000 * 60 * 5}, function (code, stdout, stderr) {
        if (stdout.indexOf('upload successed') === -1) {
          log.warn(stdout);
          res.end(end(0, i18n.get('preview.publishFail')));
        } else {
          res.end(end(1, i18n.get('preview.publishSuccess')));
        }
      });
    } catch (e) {
      res.end(end(0, e.toString()));
    }
  });

  function saveConfig(configUrl, req, res) {
    var config = Read.file(configUrl, res);
    var data = req.body;
    data = data.config;
    try {
      Parse.convert2Datav(data, config.datav);
      write(configUrl, config);
      res.end(end(1, i18n.get('preview.syncSuccess')));
    } catch (e) {
      res.end(end(0, e.toString()));
    }
  }

  router.post('/config_save', function (req, res, next) {
    saveConfig(configUrl, req, res);
  });

  router.post('/child_config_save/:dir', function (req, res, next) {
    var _dir = req.params.dir;
    var childConfigUrl = path.join(source, 'children', _dir, 'package.json');

    saveConfig(childConfigUrl, req, res);
  });


  function saveData(configUrl, req, res) {
    var config = Read.file(configUrl, res);
    var data = req.body;
    if (!data || !config || !config.datav) {
      res.end(end(0, 'error: there is no data'));
    } else {
      var api_data = config.datav.api_data;
      for (var k in api_data) {
        var api = api_data[k];
        if (typeof api === 'string') {
          if (JSON.stringify(data[k]).length > 512 * 1024) {
            res.end(end(0, i18n.get('preview.largeSize')));
          }
          write(path.join(source, api), data[k]);
        } else {
          if (JSON.stringify(data[k]).length > 512 * 1024) {
            res.end(end(0, i18n.get('preview.largeSize')));
          }
          api_data[k] = data[k];
        }
      }
      write(configUrl, config);
      res.end(end(1, i18n.get('preview.syncSuccess')));
    }
  }

  router.post('/data_save', function (req, res, next) {
    saveData(configUrl, req, res);
  });

  router.post('/child_data_save/:dir', function (req, res, next) {
    var _dir = req.params.dir;
    var childConfigUrl = path.join(source, 'children', _dir, 'package.json');

    saveData(childConfigUrl, req, res);
  });


  router.post('/cnname_save', function (req, res, next) {
    var config = Read.file(configUrl, res);
    var data = req.body;
    if (!data || !config || !config.datav) {
      res.end(end(0, 'error: there is no data'));
    } else {
      config.datav['cn_name'] = data.name;
      write(configUrl, config);
      res.end(end(1, i18n.get('preview.syncSuccess')));
    }
  });

  function saveResource(req, res, base, filenameFun, cb) {
    var data; var filename;
    if (!req.file) {
      res.end(end(0, 'error: there is no data'));
    } else {
      data = req.file.buffer;

      // 图片大小限制
      if (data.length > 1024 * 200) {
        res.end(end(0, i18n.get('preview.imageSize')));
      }

      if (typeof filenameFun === 'function') {
        filename = filenameFun(req.file.originalname);
      } else if (typeof filenameFun === 'string') {
        filename = filenameFun;
      } else {
        filename = 'resource-' + Utils.randomWord(5) + path.extname(req.file.originalname);
      }
      var root = path.join(source, base);
      var filepath = path.join(root, filename);
      co(function* () {
        if (!fs.existsSync(root)) {
          fs.mkdirSync(root);
        }
        fs.writeFileSync(path.join(root, filename), data);
        cb && cb();
        res.end(JSON.stringify({
          code: 1,
          file: filename + '?time=' + new Date().getTime(),
          isError: false,
          message: i18n.get('preview.syncSuccess')
        }));
      }).catch(function (err) {
        log.err('resource save err: ', err.stack || err);
        res.end(end(0, err.toString()));
      });
    }
  }

  router.post('/resource_save', function (req, res, next) {
    saveResource(req, res, sysConfig.resourceDir);
  });

  router.post('/icon_save/:key', function (req, res, next) {
    var key = req.params.key || '316x238';
    saveResource(req, res, sysConfig.iconDir, key + 'icon.png', function () {
      let config = Read.file(configUrl, res);
      config.datav.icon = setIcon(config.datav.icon, key, path.join('icons', key + 'icon.png'));
      write(configUrl, config);
    });
  });

  return router;
};

function setIcon(iconObj, key, url) {
  var genIconObj = function (key, url) {
    let tmp = {};
    tmp[key] = url;
    return tmp;
  };

  if (!iconObj) {
    return genIconObj(key, url);
  }
  if (typeof iconObj === 'string') {
    let tmp = {};
    tmp.default = iconObj;
    tmp[key] = url;
    return tmp;
  }
  if (typeof iconObj === 'object') {
    iconObj[key] = url;
    return iconObj;
  }
  return genIconObj(key, url);
}

function _getI18N(root, locale, res) {
  var i18n = {};
  var i18nURL = path.join(root, `/i18n/${locale}.json`);
  debug('i18nURL:', i18nURL);
  if (!locale) {
    debug(`${root} local locale start...`);
  } else if (!fs.existsSync(i18nURL)) {
    // 多语言文件缺失
    // log.warn(`${i18nURL} is not exist.`);
    debug(root, '缺失:', i18nURL);
  } else {
    i18n[locale] = Read.file(i18nURL, res);
  }
  return i18n;
}

function _getChildrenList(children = [], source, sysConfig, res) {
  var childrenList = [];
  try {
    var childrenUrl = path.join(source, '/children');
    var childrenDir = fs.readdirSync(childrenUrl);
    if (childrenDir && childrenDir.length) {
      childrenDir.forEach(function (_dir) {
        var _childrenUrl = path.join(childrenUrl, _dir);
        var _childrenI18N = _getI18N(childrenUrl, sysConfig.locale);
        if (fs.statSync(_childrenUrl).isDirectory()) {
          var _childrenConfig = Read.file(path.join(_childrenUrl, 'package.json'));
          if (children.indexOf(_childrenConfig.name) !== -1) {
            var _datav = Parse.convertDatav(_childrenConfig.datav, res, _childrenUrl);
            childrenList.push({
              _dir: `/children/${_dir}/${_childrenConfig.main || 'index.js'}`,
              name: _childrenConfig.name,
              version: _childrenConfig.version,
              datav: _datav,
              i18n: _childrenI18N || _childrenConfig.datav,
              _datav: _childrenConfig.datav,
            });
          }
        }
      });
    }
  } catch (e) {
    log.err(e);
  }
  return childrenList;
}

