//#import Util.js
//#import base64.js
//#import HttpUtil.js
//#import session.js
//#import $@projectCode:services/modelService.jsx
//#import @handlers/include/checklogin.jsx
//#import @handlers/include/util.jsx
//#import $owl_dfiles:services/modelService.jsx
//#import $owl_task_info:services/modelService.jsx
//#import $owl_excel_templates:services/modelService.jsx
//#import excel.js
//#import file.js

var formSpecs = @formSpecs;

var allChoices = {};

function getAllChoices(fieldSpec){
   if(fieldSpec._ft==='subform'){
       var fields = fieldSpec.fields;
         for(var i=0;i<fields.length;i++){
             var f = fields[i];
             if(f._ft==='subform'){
                 getAllChoices(f);
             }
            else{
                if(f._ft==='field' && f.fieldType==='choice'){
                    var optiosMap = {};
                    var options = f.options;
                    if(options){
                        for(var j=0;j<options.length;j++){
                            var option = options[j];
                            optiosMap[option[0]] = option[1];
                        }
                        allChoices[f.key] = optiosMap;
                    }
                }
            }
         }
   }
}

function tranverseFields(formSpec, callback, ctx){
    formSpec.fields.forEach( function(field){
        if (field[ '_ft' ] == 'field') {
            callback( field, ctx );
        }
        else if (field[ '_ft' ] == 'subform') {
            var context = { parentField: field }
            tranverseFields( field, callback, context );
        }
        else if (field[ '_ft' ] == 'array') {
            var context = { parentField: field }
            tranverseFields( field, callback, context )
        }
    } );
}

function normalizeValue(value,spec){
    if(value == null){
        return null;
    }
    switch (spec.fieldType){
        case 'string':
            return 's'+value;
        case 'number':
            return 'n' + value;
        case 'date':
            try{
                var d = null;
                if(isNaN(value)){
                    d = new Date(value).getTime();
                }
                else{
                    d = new Date(Number(value)).getTime();
                }
                return 'd'+ d;
            }
            catch(e){
                return null;
            }

        case 'choice':
            for(var i=0; i<spec.options.length; i++){
                var option = spec.options[i];
                if(option[0]==value){
                    return 's'+option[1];
                }
            }
            return 's'+value;
        default:
            return "s"+value;
    }
}

function getExportDoc(obj){
    tranverseFields(formSpecs,function(f,ctx){
        if (ctx.parentField && ctx.parentField._ft == 'array') {
            var items = @projectCodeService.getValue( ctx.parentField.key, obj )
            if(items){
                for(var i=0; i<items.length; i++){
                    var item = items[i];
                    var value = item[f.origKey];
                    value = normalizeValue(value,f);
                    item[f.origKey] = value;
                }
            }
        }
        else{
            var value = @projectCodeService.getValue( f.key, obj );
            value = normalizeValue(value,f);
        @projectCodeService.setValue(f.key,value,obj);
        }
    },{});
    return obj;
}

function getAllDocs(searchArgs,sort,tableId,roleId,orgId,loginId,permissions){
    var keyword = searchArgs.keyword;
    var effectiveSort = buildSort(sort);
    var filters = getFilters(searchArgs);
    var permissionFilter = getListPermissionFilter(tableId,roleId,orgId,loginId,permissions);

    if(permissionFilter){
        filters.push(permissionFilter);
    }

    var from = 0;
    var size = 9999;
    var query = {
        "query": {
            "bool": {
                "must": {
                    "query_string": {
                        "query":getKeywordQuery(keyword)
                    }
                },
                "must_not": {
                    "match": {
                        "del": "T"
                    }
                },
                "filter": filters
            }
        },
        "from" : from, "size" : size,
        sort:effectiveSort || [{owl_createTime:{order:"desc"}}]
    }

    var elasticSearchUrl = $.getEnv( "elasticSearchUrl" );

    var headers = { "Content-Type": "application/json;charset=utf-8" };
    var elasticSearchUser = $.getEnv("elasticSearchUser");
    var elasticSearchPass = $.getEnv("elasticSearchPass");
    if(elasticSearchUser && elasticSearchPass){
        var auth =Base64.encode(elasticSearchUser + ":" + elasticSearchPass);
        var basicAuth = "Basic " + auth;
        headers["Authorization"] = basicAuth;
    }
    var searchUrl = elasticSearchUrl+"/@projectCode/_search";
    var sndTxt = JSON.stringify(query);
    $.log(sndTxt);

    var s = HttpUtils.postRaw( searchUrl, sndTxt, headers);
    var result = JSON.parse(s);

    var hits = result.hits.hits;

    if(hits){
        var objs = hits.map(function(hit){return hit._source});
        return objs;
    }
    return [];

}

function getDocsByIds(ids){
    var docs = @projectCodeService.getObjects(ids);
    return docs;
}

function main(){
    taskParams = JSON.parse(taskParams);
    var templateId = taskParams.templateId;

    var template = owl_excel_templatesService.get(templateId);
    if(!template || !template.template){
        $.log("没有配置模版,templateId=" + templateId);
        return null;
    }

    var templateId = taskParams.templateId;

    var templateUrl = template.template[0].url;

    var loginId = taskParams.loginId;
    var roleId = taskParams.roleId;
    var orgId = taskParams.orgId;
    var spec = @spec;
    var tableId = taskParams.tableId;
    var permissions = getPermissions(roleId,tableId);

    ///////////////////////////////

//判断是subplatform,还是shop,还是platform
    var searchArgs = taskParams.searchArgs;

    var sort = taskParams.sort;
    var exportRange = taskParams.exportRange;
    var outputTarget = taskParams.outputTarget;
    var docs = null;


    if(exportRange === "all"){
        docs = getAllDocs(searchArgs,sort,tableId,roleId,orgId,loginId,permissions);
    }
    else{
        var ids = taskParams.ids;
        docs = getDocsByIds(ids);
    }

    for(var i=0; i<docs.length; i++){
        var doc = docs[i];
        doc = getExportDoc(doc);
        docs[i] = doc;
    }

    if(template.exportType==='doc'){
        if(outputTarget==='multifile'){
            for(var i=0; i<docs.length; i++){
                var exportDoc = docs[i];

                var fileId = Excel.generateExcelFromTemplate( templateUrl, exportDoc );
                if(template.toField){
                    var id=exportDoc.id;
                    var doc = @projectCodeService.get(id);
                    var url = FileService.getFullPath(fileId);
                    var docName =template.name + "_" +fileId;

                    doc[template.toField] = {
                        url: "" + url,
                        fileId: "" + fileId,
                        name:"" + docName
                    }
                    @projectCodeService.update(doc);
                }
                else{
                    var url = FileService.getFullPath(fileId);

                    var docName =template.name + "_" +fileId;

                    if(exportDoc.name){
                        docName =  exportDoc.name + "_" +template.name;
                    }
                    else{
                        docName =  exportDoc.id + "_" +template.name;
                    }

                    var download = {
                        templateId:templateId,
                        templateName:template.name,
                        description:docName,
                        _orgId:orgId,
                        _orgIds:[orgId],
                        file:{
                            url: "" + url,
                            fileId: "" + fileId,
                            name:"" + docName
                        }
                    }

                    owl_dfilesService.add(download);
                }
            }
        }
        else if(outputTarget==='singlefile'){
            //single file
            var urls = [];
            for(var i=0; i<docs.length; i++){
                var exportDoc = docs[i];
                var fileId = Excel.generateExcelFromTemplate( templateUrl, exportDoc );
                var url = FileService.getFullPath(fileId);
                urls.push(url);
            }

            var fileId = $.zipUrls(urls,taskParams.password);
            var fileUrl = FileService.getFullPath(fileId);
            var docName =template.name + "_" +fileId;
            var download = {
                templateId:templateId,
                templateName:template.name,
                description:JSON.stringify(taskParams),
                _orgId:orgId,
                _orgIds:[orgId],
                file:{
                    url: "" + fileUrl,
                    fileId: "" + fileId,
                    name:"" + docName
                }
            }
            owl_dfilesService.add(download);
        }
    }
    else if(template.exportType==='list'){
        var theDoc = {docs:docs}
        var fileId = Excel.generateExcelFromTemplate( templateUrl, theDoc );
        var fileUrl = FileService.getFullPath(fileId);
        var docName =template.name + "_" +fileId;
        var download = {
            templateId:templateId,
            templateName:template.name,
            description:JSON.stringify(taskParams),
            _orgId:orgId,
            _orgIds:[orgId],
            file:{
                url: "" + fileUrl,
                fileId: "" + fileId,
                name:"" + docName
            }
        }
        owl_dfilesService.add(download);
    }

    var taskInfo = owl_task_infoService.get(taskInfoId);
    taskInfo.state = "success";
    taskInfo.percent = 100;
    taskInfo.endDate = new Date().getTime();
    taskInfo.state = "succeeded";
    taskInfo.msg = "生成Excel文件成功";
    owl_task_infoService.update(taskInfo);

}
main();