/**
 * Created by Zhong on 2017/8/11.
 */
import mongoose from 'mongoose';
import BaseController from "../../common/base/base_controller";
import stdgljutil  from "../../../public/cache/std_glj_type_util";
import GljDao from "../models/gljModel";
import rationItemDao from "../../ration_repository/models/ration_item";
const multiparty = require("multiparty");
const excel = require("node-xlsx");
const LZString = require('lz-string');
const gljModel = mongoose.model('std_glj_lib_gljList');
const stdRationModel = mongoose.model('std_ration_lib_ration_items');
const cplRationModel = mongoose.model('complementary_ration_items');
const fs = require('fs');
const compilationModel = mongoose.model('compilation');
const gljLibModel = mongoose.model('std_glj_lib_map');

let gljDao = new GljDao();
let callback = function(req, res, err, message, data){
    res.json({error: err, message: message, data: data});
};

class GljController extends BaseController{
    getGljDistType (req, res) {
        let gljDistTypeCache = stdgljutil.getStdGljTypeCacheObj().toArray();
        if(gljDistTypeCache.length >0 ){
            callback(req, res, null, '', gljDistTypeCache);
        }
        else {
            callback(req, res, 1, 'Error', null);
        }
    }
    getGljTree(req,res){
        let data = JSON.parse(req.body.data);
        gljDao.getGljTypes(data.gljLibId, function(err,data){
            callback(req,res,err, 'Get Tree', data)
        });
    }
    async updateRationBasePrc(req, res){
        let basePrcArr = JSON.parse(req.body.basePrcArr);
        let repId = req.body.repId;
        let absoluteUrl = null;
        let stdGljLib = await gljLibModel.findOne({ID: repId});
        if(stdGljLib){
            let compilation = await compilationModel.findOne({_id: mongoose.Types.ObjectId(stdGljLib.compilationId)});
            let tempUrl = compilation.overWriteUrl ? req.app.locals.rootDir + compilation.overWriteUrl : req.app.locals.rootDir;
            absoluteUrl = fs.existsSync(tempUrl) && fs.statSync(tempUrl).isFile()? tempUrl : null;
        }
        rationItemDao.updateRationBasePrc(basePrcArr, absoluteUrl, function (err, message) {
            if(err){
                callback(req, res, err, message, null);
            }
            else{
                callback(req, res, err, message, null);
            }
        });
    }

    getRationGljIds(req, res){
        let rationLibs = req.body.rationLibs;
        gljDao.getRationGljIds(rationLibs, function (err, msg, data) {
            callback(req, res, err, msg, data);
        })
    }
    createNewGljTypeNode(req, res) {
        let repId = req.body.repositoryId;
        let lastNodeId = req.body.lastNodeId;
        let lastOpr = req.body.lastOpr;
        let nodeData = JSON.parse(req.body.rawNodeData);
        gljDao.createNewNode(repId, lastOpr, lastNodeId, nodeData, function(err, msg, data){
            callback(req,res,err,msg, data)
        });
    }
    updateGljNodes(req, res) {
        let nodes = JSON.parse(req.body.nodes);
        let repId = req.body.repId,
            lastOpr = req.body.lastOpr;
        gljDao.updateNodes(repId, lastOpr, nodes, function(err,results){
            callback(req,res, err, results)
        });
    }
    deleteGljNodes(req, res) {
        let nodes = JSON.parse(req.body.nodes);
        let preNodeId = req.body.preNodeId;
        let preNodeNextId = req.body.preNodeNextId;
        let repId = req.body.repId, lastOpr = req.body.lastOpr;
        gljDao.removeNodes(repId, lastOpr, nodes, preNodeId, preNodeNextId, function(err,results){
            callback(req,res, err, results)
        });
    }
    updateNodes(req, res){
        let data = JSON.parse(req.body.data);
        gljDao.updateNodes(data.updateData, data.lastOpr, function (err, data) {
            callback(req, res, err, '', data);
        });
    }
    getGljItems(req, res) {
        let repId = req.body.repositoryId,
            gljType = req.body.type,
            gljCode = req.body.code;
        if (gljCode) {
            gljDao.getGljItem(repId, gljCode, function(err, data){
                callback(req,res,err,'Get Items', data)
            });
        } else if (gljType) {
            gljDao.getGljItemByType(repId, gljType, function(err, data){
                callback(req,res,err,'Get Types', data)
            });
        } else {
            gljDao.getGljItemsByRep(repId, function(err, data){
                callback(req,res,err,'Get Items',data)
            });
        }
    }
    getGljItemsByIds(req, res) {
        let gljIds = JSON.parse(req.body.gljIds);
        gljDao.getGljItems(gljIds, function(err, data){
            callback(req,res,err,'Get Items',data)
        });
    }
    getGljItemsByCodes(req, res) {
        let gljCodes = JSON.parse(req.body.gljCodes),
            repId = req.body.repId;
        gljDao.getGljItemsByCode(repId, gljCodes, function(err, data){
            callback(req,res,err,'Get Items',data)
        });
    }
    updateComponent(req, res){
        let libId = req.body.libId,
            updateArr = req.body.updateArr,
            oprtor = req.body.oprtor;
        gljDao.updateComponent(libId, oprtor, updateArr, function (err, message, rst) {
            callback(req, res, err, message, rst);
        })
    }
    async batchUpdateComponent(req, res){
        const form = new multiparty.Form();
        form.parse(req, async function(err, fields, files) {
            try{
                let compressData = fields.compressData !== undefined && fields.compressData.length > 0 ? fields.compressData[0] : null;
                if(!compressData){
                    throw '数据错误';
                }
                let updateDatas = JSON.parse(LZString.decompressFromUTF16(compressData));
                let bulkArr = [];
                for(let uData of updateDatas){
                    bulkArr.push({updateOne: {filter: {ID: uData.ID}, update: {$set: {component: uData.component}}}});
                }
                if(bulkArr.length > 0){
                    await gljModel.bulkWrite(bulkArr);
                }
                res.json({err: 0, data: null, msg: 'success'});
            }
            catch (err){
                res.json({err: 1, data: null, msg: err});
            }
        });
    }
    mixUpdateGljItems(req, res){
        let repId = req.body.repositoryId,
            updateItems = JSON.parse(req.body.updateItems),
            addItems = JSON.parse(req.body.addItems),
            removeIds = JSON.parse(req.body.removeIds),
            lastOpr = req.body.lastOpr;
        gljDao.mixUpdateGljItems(repId, lastOpr, updateItems, addItems, removeIds, function(err, message, rst){
            if (err) {
                console.log(err);
                callback(req, res, err, message, null);
            } else {
                callback(req, res, err, message, rst);
            }
        });
    }
    getGljItemsOccupied(req, res){
        let repId = req.body.repId,
            occupation = req.body.occupation;
        gljDao.getGljItemsOccupied(repId, occupation, function (err, message, rst) {
            callback(req, res, err, message, rst);
        })
    }
    async isUsed(req, res){
        try{
            let data = JSON.parse(req.body.data);
            let gljIds = data.gljIds;
            let stdRation = await stdRationModel.findOne({isDeleted: false, 'rationGljList.gljId': {$in: gljIds}});
            if(stdRation){
                res.json({error: 0, message: 'success', data: {isUsed: true}});
            }
            else {
                let cplRation = await cplRationModel.findOne({$or: [{deleteInfo: null}, {'deleteInfo.deleted': false}], 'rationGljList.gljId': {$in: gljIds}});
                if(cplRation){
                    res.json({error: 0, message: 'success', data: {isUsed: true}});
                }
                else {
                    res.json({error: 0, message: 'success', data: {isUsed: false}});
                }
            }
        }
        catch (error){
            res.json({error: 1, message: error, data: null});
        }
    }

    async getReference(req, res) {
        try {
            const {repositoryId, gljId} = JSON.parse(req.body.data);
            const info = await gljDao.getReference(repositoryId, gljId);
            res.json({error: 0, message: 'success', data: info});
        } catch (err) {
            console.log(err);
            res.json({error: 1, message: 'fail', data: null});
        }
    }

    async importPrice(request, response) {
        let responseData = {
            err: 0,
            msg: ''
        };
        const allowHeader = ['application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'];
        const uploadOption = {
            uploadDir: './public'
        };
        const form = new multiparty.Form(uploadOption);
        let uploadFullName;
        form.parse(request, async function(err, fields, files) {
            try{
                const gljLibId = fields.gljLibId !== undefined && fields.gljLibId.length > 0 ?
                    fields.gljLibId[0] : 0;
                if (gljLibId <= 0) {
                    throw '参数错误';
                }
                const file = files.file !== undefined ? files.file[0] : null;
                if (err || file === null) {
                    throw '上传失败';
                }
                // 判断类型
                if (file.headers['content-type'] === undefined || allowHeader.indexOf(file.headers['content-type']) < 0) {
                    throw '不支持该类型';
                }
                // 重命名文件名
                uploadFullName = uploadOption.uploadDir + '/' + file.originalFilename;
                fs.renameSync(file.path, uploadFullName);

                const sheet = excel.parse(uploadFullName);
                if (sheet[0] === undefined || sheet[0].data === undefined || sheet[0].data.length <= 0) {
                    throw 'excel没有对应数据';
                }
                //更新人材机价格
                await gljDao.batchUpdateGljPrice(gljLibId, sheet[0].data);
                console.log('endeeee');
                // 删除文件
                if(uploadFullName && fs.existsSync(uploadFullName)){
                    fs.unlink(uploadFullName);
                }
                response.json(responseData);
            }
            catch (error){
                console.log(error);
                if(uploadFullName && fs.existsSync(uploadFullName)){
                    fs.unlink(uploadFullName);
                }
                responseData.err = 1;
                responseData.msg = error;
                response.json(responseData);
            }
        });
    }

    async importComponents(request, response) {
        let responseData = {
            err: 0,
            msg: ''
        };
        const allowHeader = [
            'application/vnd.ms-excel', 
            'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            'application/octet-stream'
        ];
        const uploadOption = {
            uploadDir: './public'
        };
        const form = new multiparty.Form(uploadOption);
        let uploadFullName;
        form.parse(request, async function(err, fields, files) {
            try{
                const gljLibId = fields.gljLibId !== undefined && fields.gljLibId.length > 0 ?
                    fields.gljLibId[0] : 0;
                if (gljLibId <= 0) {
                    throw '参数错误';
                }
                const file = files.file !== undefined ? files.file[0] : null;
                if (err || file === null) {
                    throw '上传失败';
                }
                // 判断类型
                if (file.headers['content-type'] === undefined || allowHeader.indexOf(file.headers['content-type']) < 0) {
                    throw '不支持该类型';
                }
                // 重命名文件名
                uploadFullName = uploadOption.uploadDir + '/' + file.originalFilename;
                fs.renameSync(file.path, uploadFullName);

                const sheet = excel.parse(uploadFullName);
                if (sheet[0] === undefined || sheet[0].data === undefined || sheet[0].data.length <= 0) {
                    throw 'excel没有对应数据';
                }
                // 更新组成物
                await gljDao.importComponents(gljLibId, sheet[0].data);
                // 删除文件
                if(uploadFullName && fs.existsSync(uploadFullName)){
                    fs.unlink(uploadFullName);
                }
                response.json(responseData);
            }
            catch (error){
                console.log(error);
                if(uploadFullName && fs.existsSync(uploadFullName)){
                    fs.unlink(uploadFullName);
                }
                responseData.err = 1;
                responseData.msg = typeof error !== 'string' ? error.toString() : error;
                response.json(responseData);
            }
        });
    }
}

export default GljController;
