package cn.com.capcloud.api.action;

import cn.com.capcloud.api.action.service.*;
import cn.com.capcloud.api.action.service.util.ReflectionUtil;
import cn.com.capcloud.api.action.service.util.TextUtil;
import cn.com.capcloud.ccui.core.common.json.JackJSON;
import cn.com.capcloud.ccui.core.common.json.JackJSONObject;
import cn.com.capcloud.ccui.core.common.utils.StringUtil;
import cn.com.capcloud.core.noentitydb.BaseService;
import cn.com.capcloud.core.noentitydb.DefaultActionFace;
import cn.com.capcloud.core.noentitydb.JtPage;
import cn.com.capcloud.core.system.user.User;
import cn.com.capcloud.core.system.user.UserService;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class ApiImportExportAction {

    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(ApiImportExportAction.class);
    @Autowired
    private BaseService baseService;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private ApiService apiService;
    @Autowired
    private ImportExportService importExportService;
    @Autowired
    private FileService fileService;
    @Autowired
    private UserService userService;
    @Autowired
    private DataSourceService dsService;
    @Autowired
    private ShowValueService svService;
    @Autowired
    private ActionResolveService actionResolveService;

    private String successResponse(Object data) {
        JackJSONObject retJson = JackJSONObject.fromObject(apiService.getReturnDataByCode("ok"));
        retJson.put("data", data);
        return JackJSON.toJSONString(retJson);
    }

    private String failResponse(JackJSONObject retJson) {
        return JackJSON.toJSONString(retJson);
    }

    public String exportExcelData(String jsonStr,HttpServletRequest request){
        JackJSONObject retJson=new JackJSONObject();
        JackJSONObject dataJson=new JackJSONObject();
        Map<String,Object> dsMap=dsService.findDataSourceByJsonStr(jsonStr,retJson,dataJson);
        if (dsMap==null) {
            return failResponse(retJson);
        }
        Map<String, Object> queryMap=dsService.resolveQuery(jsonStr,retJson,retJson);
        if(queryMap==null){
            return failResponse(retJson);
        }
        ActionResolveService.ActionResolveResult actionResolveResult =
                actionResolveService.resolveAction(dsMap, retJson);
        if (actionResolveResult == null) {
            return failResponse(retJson);
        }
        DefaultActionFace actionImpl = actionResolveResult.getActionImpl();
        Boolean existsAction = actionResolveResult.isExistsAction();
        String actionClass = actionResolveResult.getActionClass();
        String sql;
        String buildExcelSql=String.valueOf(queryMap.get("build_excel_sql"));
        String buildSql = String.valueOf(queryMap.get("build_sql"));
        if(existsAction&&StringUtil.isNotEmpty(buildExcelSql)){
            sql = ReflectionUtil.mySelfMethodRetStr(actionClass,buildExcelSql,jsonStr,retJson,request);
        } else if (existsAction && StringUtil.isNotEmpty(buildSql)){
            sql = ReflectionUtil.mySelfMethodRetStr(actionClass, buildSql, jsonStr, retJson, request);
        }else{
            sql = actionImpl.buildExcelSql(jsonStr,retJson,request);
        }
        if("-1".equals(sql)){
            return failResponse(retJson);
        }
        String powerSql;
        String buildPowerSql = String.valueOf(queryMap.get("build_power_sql"));
        if (existsAction && StringUtil.isNotEmpty(buildPowerSql)) {
            powerSql = ReflectionUtil.mySelfMethodRetStr(actionClass, buildPowerSql, jsonStr, retJson, request);
        } else {
            powerSql = actionImpl.buildPowerSql(jsonStr, retJson, request);
        }
        if ("-1".equals(powerSql)) {
            return failResponse(retJson);
        }
        sql = sql + powerSql;
        String orderBy=dsService.getOrderBySql(jsonStr,retJson);
        if ("-1".equals(orderBy)) {
            return failResponse(retJson);
        }
        List<Map<String, Object>> dataList = new ArrayList<>();
        if(!sql.equals("")){
            dataList = jdbcTemplate.queryForList(sql);
        }
        dataList=JackJSON.parseObject(TextUtil.nullToStrFilter(dataList), ArrayList.class);
        JtPage jtPage=new JtPage();
        jtPage.setContent(dataList);
        jtPage = actionImpl.showAllDesensitizeExportExcel(jsonStr,retJson,request,jtPage);
        if(jtPage==null){
            return failResponse(retJson);
        }
        String showAllAfterExportExcel=String.valueOf(queryMap.get("show_all_after_export_excel"));
        if(existsAction&&StringUtil.isNotEmpty(showAllAfterExportExcel)){
            jtPage = ReflectionUtil.mySelfMethodRetJtPage(actionClass,showAllAfterExportExcel,jsonStr,retJson,request,jtPage);
        }else{
            jtPage = actionImpl.showAllAfterExportExcel(jsonStr,retJson,request,jtPage);
        }
        if(jtPage==null){
            return failResponse(retJson);
        }
        Map<String,Object> returnMap=importExportService.exportExcelDataByXlsx(jsonStr,retJson,jtPage);
        if(returnMap.size()==0){
            return failResponse(retJson);
        }
        return successResponse(returnMap);
    }

    public String exportWordData(String jsonStr, HttpServletRequest request){
        User user=userService.getUser(request);
        JackJSONObject retJson=new JackJSONObject();
        JackJSONObject dataJson=new JackJSONObject();
        Map<String,Object> dsMap=dsService.findDataSourceByJsonStr(jsonStr,retJson,dataJson);
        if (dsMap==null) {
            return failResponse(retJson);
        }
        Map<String, Object> queryMap=dsService.resolveQuery(jsonStr,retJson,retJson);
        if(queryMap==null){
            return failResponse(retJson);
        }
        ActionResolveService.ActionResolveResult actionResolveResult =
                actionResolveService.resolveAction(dsMap, retJson);
        if (actionResolveResult == null) {
            return failResponse(retJson);
        }
        DefaultActionFace actionImpl = actionResolveResult.getActionImpl();
        Boolean existsAction = actionResolveResult.isExistsAction();
        String actionClass = actionResolveResult.getActionClass();
        /**
         * 如果不是使用默认的主键当查询条件，请注意前端传过来的查询条件要唯一的。
         */
        String pkFieldId=String.valueOf(JackJSONObject.fromObject(jsonStr).get("pkFieldId"));
        if(StringUtil.isEmpty(pkFieldId)){
            pkFieldId=String.valueOf(dsMap.get("ds_pk_id"));
        }
        String tableName=String.valueOf(dsMap.get("ds_table_name"));
        String dsTableName=dsService.getDsTableName(dsMap,queryMap,user);
        String pkId=String.valueOf(JackJSONObject.fromObject(jsonStr).get("pkId"));
        Map<String,Object> returnMap;
        if(tableName.equals(dsTableName)){
            returnMap = baseService.findOne(tableName, pkId,pkFieldId);
        }else{
            returnMap = jdbcTemplate.queryForMap("select * from "+dsTableName+" _khc where _khc."+pkFieldId+"='"+pkId+"'");
        }
        returnMap=JackJSON.parseObject(TextUtil.nullToStrFilter(returnMap), HashMap.class);
        if(returnMap.size()>0){
            svService.valueToShowValue(jsonStr,request,returnMap);
            String findOneAfterExportWord=String.valueOf(queryMap.get("find_one_after_export_word"));
            if(existsAction&&StringUtil.isNotEmpty(findOneAfterExportWord)){
                returnMap = ReflectionUtil.mySelfMethodRetMap(actionClass,findOneAfterExportWord,jsonStr,retJson,request,returnMap);
            }else{
                returnMap = actionImpl.findOneAfterExportWord(jsonStr,retJson,request,returnMap);
            }
            if(returnMap.size()==0){
                return failResponse(retJson);
            }
        }
        returnMap = fileService.createWord(jsonStr,retJson,request,returnMap);
        if(returnMap.size()==0){
            return failResponse(retJson);
        }
        return successResponse(returnMap);
    }
    //单条导出
    public String exportExcelOneData(String jsonStr, HttpServletRequest request){
        User user=userService.getUser(request);
        JackJSONObject retJson=new JackJSONObject();
        JackJSONObject dataJson=new JackJSONObject();
        Map<String,Object> dsMap=dsService.findDataSourceByJsonStr(jsonStr,retJson,dataJson);
        if (dsMap==null) {
            return failResponse(retJson);
        }
        Map<String, Object> queryMap=dsService.resolveQuery(jsonStr,retJson,retJson);
        if(queryMap==null){
            return failResponse(retJson);
        }
        ActionResolveService.ActionResolveResult actionResolveResult =
                actionResolveService.resolveAction(dsMap, retJson);
        if (actionResolveResult == null) {
            return failResponse(retJson);
        }
        DefaultActionFace actionImpl = actionResolveResult.getActionImpl();
        Boolean existsAction = actionResolveResult.isExistsAction();
        String actionClass = actionResolveResult.getActionClass();
        /**
         * 如果不是使用默认的主键当查询条件，请注意前端传过来的查询条件要唯一的。
         */
        String pkFieldId=String.valueOf(JackJSONObject.fromObject(jsonStr).get("pkFieldId"));
        if(StringUtil.isEmpty(pkFieldId)){
            pkFieldId=String.valueOf(dsMap.get("ds_pk_id"));
        }
        String tableName=String.valueOf(dsMap.get("ds_table_name"));
        String dsTableName=dsService.getDsTableName(dsMap,queryMap,user);
        String pkId=String.valueOf(JackJSONObject.fromObject(jsonStr).get("pkId"));
        Map<String,Object> returnMap;
        if(tableName.equals(dsTableName)){
            returnMap = baseService.findOne(tableName, pkId,pkFieldId);
        }else{
            returnMap = jdbcTemplate.queryForMap("select * from "+dsTableName+" _khc where _khc."+pkFieldId+"='"+pkId+"'");
        }
        returnMap=JackJSON.parseObject(TextUtil.nullToStrFilter(returnMap), HashMap.class);
        returnMap=svService.valueRewrite(jsonStr,request,returnMap);
        if(returnMap.size()>0){
            svService.valueToShowValue(jsonStr,request,returnMap);
            String findOneAfterExportWord=String.valueOf(queryMap.get("find_one_after_export_excel"));
            if(existsAction&&StringUtil.isNotEmpty(findOneAfterExportWord)){
                returnMap = ReflectionUtil.mySelfMethodRetMap(actionClass,findOneAfterExportWord,jsonStr,retJson,request,returnMap);
            }else{
                returnMap = actionImpl.findOneAfterExportExcel(jsonStr,retJson,request,returnMap);
            }
            if(returnMap.size()==0){
                return failResponse(retJson);
            }
        }
        returnMap = fileService.createExcel(jsonStr,retJson,request,returnMap);
        if(returnMap.size()==0){
            return failResponse(retJson);
        }
        return successResponse(returnMap);
    }

    public String exportExcelTemplate(String jsonStr,HttpServletRequest request){
        JackJSONObject retJson=new JackJSONObject();
        JackJSONObject dataJson=new JackJSONObject();
        String uuid=dsService.getDataSourceUuid(jsonStr,retJson,dataJson);
        if ("-1".equals(uuid)) {
            return failResponse(retJson);
        }
        Map<String, Object> queryMap=dsService.resolveQuery(jsonStr,retJson,retJson);
        if(queryMap==null){
            return failResponse(retJson);
        }
        Map<String,Object> returnMap=importExportService.exportExcelTemplate(dsService.getQueryInfo(jsonStr),queryMap);
        return successResponse(returnMap);
    }

    //旧版导入是上传附件并解析数据然后导入库
    public String importExcelData(HttpServletRequest request){
        JackJSONObject retJson=new JackJSONObject();
        String uuid = dsService.getDataSourceUuid(retJson, request);
        String queryCode = apiService.getRequestValueByKey(request, retJson, "queryCode");
        if ("-1".equals(queryCode)) {
            return JackJSON.toJSONString(retJson);
        }
        Map<String, Object> queryMap = dsService.getQuery(uuid, queryCode, retJson);
        if (queryMap.size() == 0) {
            return JackJSON.toJSONString(retJson);
        }
        if(queryMap==null){
            return failResponse(retJson);
        }
        Map<String,Object> returnMap=importExportService.importExcelData(retJson,request);
        if(returnMap.size()==0){
            return failResponse(retJson);
        }
        return successResponse(returnMap);
    }

    //新版导入是先上传附件拿到附件信息再请求此接口传附件信息然后根据文件信息找到文件再解析数据导入库
    public String importExcelDataNew(String jsonStr, HttpServletRequest request){

        JackJSONObject retJson=new JackJSONObject();
        JackJSONObject dataJson=new JackJSONObject();
        Map<String,Object> dsMap=dsService.findDataSourceByJsonStr(jsonStr,retJson,dataJson);
        if (dsMap==null) {
            return failResponse(retJson);
        }
        Map<String, Object> queryMap=dsService.resolveQuery(jsonStr,retJson,retJson);
        if(queryMap==null){
            return failResponse(retJson);
        }
        String fileArray=apiService.getJsonValueByKey(jsonStr,retJson,"fileArray");
        if("-1".equals(fileArray)){
            return failResponse(retJson);
        }
        ActionResolveService.ActionResolveResult actionResolveResult =
                actionResolveService.resolveAction(dsMap, retJson);
        if (actionResolveResult == null) {
            return failResponse(retJson);
        }
        DefaultActionFace actionImpl = actionResolveResult.getActionImpl();
        Boolean existsAction = actionResolveResult.isExistsAction();
        String actionClass = actionResolveResult.getActionClass();
        String importExcelDataBefore=String.valueOf(queryMap.get("import_excel_data_before"));
        Map<String,Object> returnMap;
        if(existsAction&&StringUtil.isNotEmpty(importExcelDataBefore)){
            returnMap = ReflectionUtil.mySelfMethodRetMap(actionClass,importExcelDataBefore,jsonStr,retJson,request);
        }else{
            returnMap = actionImpl.importExcelDataBefore(jsonStr,retJson,request);
        }
        if(returnMap.size()==0){
            return failResponse(retJson);
        }
        return successResponse(returnMap);
    }

    public String importJsonData(String jsonStr, HttpServletRequest request){

        JackJSONObject retJson=new JackJSONObject();
        JackJSONObject dataJson=new JackJSONObject();
        String uuid=dsService.getDataSourceUuid(jsonStr,retJson,dataJson);
        Map<String, Object> queryMap=dsService.resolveQuery(jsonStr,retJson,retJson);
        if(queryMap==null){
            return failResponse(retJson);
        }
        String importJsonStr=apiService.getJsonValueByKey(jsonStr,retJson,"importJsonStr");
        if("-1".equals(importJsonStr)){
            return failResponse(retJson);
        }
        Map<String,Object> returnMap=importExportService.importJsonData(jsonStr,retJson,request);
        if(returnMap.size()==0){
            return failResponse(retJson);
        }
        return successResponse(returnMap);
    }

    public String updateJsonData(String jsonStr, HttpServletRequest request){

        JackJSONObject retJson=new JackJSONObject();
        JackJSONObject dataJson=new JackJSONObject();
        String uuid=dsService.getDataSourceUuid(jsonStr,retJson,dataJson);
        Map<String, Object> queryMap=dsService.resolveQuery(jsonStr,retJson,retJson);
        if(queryMap==null){
            return failResponse(retJson);
        }
        String importJsonStr=apiService.getJsonValueByKey(jsonStr,retJson,"updateJsonStr");
        if("-1".equals(importJsonStr)){
            return failResponse(retJson);
        }
        Map<String,Object> returnMap=importExportService.updateJsonData(jsonStr,retJson,request);
        if(returnMap.size()==0){
            return failResponse(retJson);
        }
        return successResponse(returnMap);
    }

    /**
     * 生成PDF，对应一条数据
     */
    public String createOnePdf(String jsonStr,HttpServletRequest request){
        JackJSONObject retJson=new JackJSONObject();
        JackJSONObject dataJson=new JackJSONObject();
        Map<String,Object> dsMap=dsService.findDataSourceByJsonStr(jsonStr,retJson,dataJson);
        if (dsMap==null) {
            return failResponse(retJson);
        }
        Map<String, Object> formMap=dsService.resolveForm(jsonStr,retJson,retJson);
        if(formMap==null){
            return failResponse(retJson);
        }
        ActionResolveService.ActionResolveResult actionResolveResult =
                actionResolveService.resolveAction(dsMap, retJson);
        if (actionResolveResult == null) {
            return failResponse(retJson);
        }
        DefaultActionFace actionImpl = actionResolveResult.getActionImpl();
        Boolean existsAction = actionResolveResult.isExistsAction();
        String actionClass = actionResolveResult.getActionClass();
        String createPdf=String.valueOf(formMap.get("create_pdf"));
        String beforeRet;
        if(existsAction&&StringUtil.isNotEmpty(createPdf)){
            beforeRet=ReflectionUtil.mySelfMethodRetStr(actionClass,createPdf,jsonStr,retJson,request);
        }else{
            beforeRet=actionImpl.createPdf(jsonStr,retJson,request);
        }
        if("-1".equals(beforeRet)){
            return failResponse(retJson);
        }
        Map<String,Object> returnMap=fileService.createOnePdf(jsonStr,retJson,request);
        if(returnMap.size()==0){
            return failResponse(retJson);
        }
        return successResponse(returnMap);
    }
}

