package cn.com.capcloud.api.action.service;

import cn.com.capcloud.api.action.service.util.QueryConditionUtil;
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.JackJSONArray;
import cn.com.capcloud.ccui.core.common.json.JackJSONObject;
import cn.com.capcloud.ccui.core.common.utils.StringUtil;
import cn.com.capcloud.core.util.*;
import cn.com.capcloud.core.noentitydb.BaseService;
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.Service;

import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.*;

@Service
public class ApiService {

    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(ApiService.class);

    @Autowired
    private UserService userService;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private ReadProperty readProperty;
    @Autowired
    private BaseService baseService;
    @Autowired
    private DataSourceService dsService;
    @Autowired
    private ShowValueService svService;

    public Map<String, Object> getReturnDataByCode(String code) {
        return ApiDao.getReturnDataByCode(code,jdbcTemplate);
    }

    public Map<String,Object> executeMyActionMethod(String jsonStr, JackJSONObject retJson, HttpServletRequest request) {
        String dsCode=getJsonValueByKey(jsonStr,retJson,"dsCode");
        Map<String,Object> map=dsService.findDataSourceByCode(dsCode);
        String className=String.valueOf(map.get("my_action_class"));
        if(StringUtil.isEmpty(className)){
            retJson.putAll(JackJSONObject.fromObject(getReturnDataByCode("6010")));
            retJson.put("message",retJson.get("message")+" dsCode："+dsCode);
            return new HashMap<>();
        }else{
            String methodName=getJsonValueByKey(jsonStr,retJson,"methodName");
            if("-1".equals(methodName)){
                return new HashMap<>();
            }else{
                if(ReflectionUtil.isMethod(className,methodName)){
                    return ReflectionUtil.mySelfMethodRetMap(className,methodName,jsonStr,retJson,request);
                }else{
                    retJson.putAll(JackJSONObject.fromObject(getReturnDataByCode("6010")));
                    retJson.put("message",retJson.get("message")+" methodName："+methodName+"()");
                    return new HashMap<>();
                }
            }
        }
    }

    private String getRequiredValue(JackJSONObject source, JackJSONObject retJson, String key) {
        String value = String.valueOf(source.get(key));
        if (StringUtil.isEmpty(value)) {
            retJson.putAll(JackJSONObject.fromObject(getReturnDataByCode("7010")));
            retJson.put("message", retJson.get("message") + "：" + key);
            return "-1";
        }
        return value;
    }

    public String getJsonValueByKey(String jsonStr, JackJSONObject retJson, String key) {
        return getRequiredValue(JackJSONObject.fromObject(jsonStr), retJson, key);
    }
    public String getRequestValueByKey(HttpServletRequest request, JackJSONObject retJson, String key) {
        String data = request.getParameter("data");
        if (data == null) {
            retJson.putAll(JackJSONObject.fromObject(getReturnDataByCode("7010")));
            retJson.put("message", retJson.get("message") + "：" + key);
            return "-1";
        }
        return getRequiredValue(JackJSONObject.fromObject(data), retJson, key);
    }

    /**
     * 加密字符串
     */
    public String smEncrypt(String str) {
        return TextUtil.smDecrypt(str,readProperty.getSmPubKey());
    }
    /**
     * 解密字符串
     */
    public String smDecrypt(String str) {
        return TextUtil.smDecrypt(str,readProperty.getSmPriKey());
    }

    public Map<String, Object> getPageInfo(String jsonStr,JackJSONObject retJson, HttpServletRequest request){
        User user=userService.getUser(request);
        JackJSONObject params=JackJSONObject.fromObject(jsonStr);
        String pageCode=String.valueOf(params.get("pageCode"));
        String queryPageSql="SELECT * FROM tbl_data_page WHERE status='0' and page_code='"+pageCode+"'";
        List<Map<String, Object>> pageList=jdbcTemplate.queryForList(queryPageSql);
        if(pageList.size()==0){
            retJson.putAll(JackJSONObject.fromObject(getReturnDataByCode("404")));
            retJson.put("message",retJson.get("message"));
            return new HashMap<>();
        }
        String pageId=String.valueOf(pageList.get(0).get("id"));
        String pageParentUuid=String.valueOf(pageList.get(0).get("uuid"));
        String queryPageRoleIdSql="SELECT DISTINCT role_id FROM tbl_data_page_role WHERE page_id="+pageId;
        List<Map<String, Object>> roleIdList=jdbcTemplate.queryForList(queryPageRoleIdSql);
        if(roleIdList.size()>0){
            String whereInSql="";
            for (int i = 0; i < roleIdList.size(); i++) {
                whereInSql+=roleIdList.get(i).get("role_id")+",";
            }
            whereInSql=whereInSql.substring(0,whereInSql.length()-1);
            String countSql="SELECT count(1) FROM tbl_system_roleuser WHERE user_id="+user.getId()+" AND role_id IN ("+whereInSql+")";
            Integer count=jdbcTemplate.queryForObject(countSql,Integer.class);
            if(count==0){
                retJson.putAll(JackJSONObject.fromObject(getReturnDataByCode("4031")));
                retJson.put("message",retJson.get("message")+"："+pageCode);
                return new HashMap<>();
            }
        }
        Map<String, Object> retMap=pageList.get(0);
        String queryComponentSql="SELECT * FROM tbl_data_page_component WHERE status='0' and component_status='0' and page_parent_uuid='"+pageParentUuid+"' order by sort asc";
        List<Map<String, Object>> componentList=jdbcTemplate.queryForList(queryComponentSql);
        componentList=svService.filterDataByRole(componentList,request);
        String queryInfoStr=String.valueOf(params.get("queryInfo"));
        String urlWhereSQL="";
        if(StringUtil.isNotEmpty(queryInfoStr)){
            JackJSONObject queryInfo=JackJSONObject.fromObject(queryInfoStr);
            // 遍历并输出所有字段
            for (Object key : queryInfo.keySet()) {
                Object value = queryInfo.get(key);
                urlWhereSQL+=" and "+key+" = '"+value+"'";
            }
        }
        for (int i = 0; i < componentList.size(); i++) {
            String isShowNum=String.valueOf(componentList.get(i).get("is_show_num"));
            if(!isShowNum.equals("Y")){
                continue;
            }
            String showNumDataType=String.valueOf(componentList.get(i).get("show_num_data_type"));
            if(showNumDataType.equals("2")){
                String cSql=String.valueOf(componentList.get(i).get("c_sql"));
                cSql=cSql.replaceAll("&nbsp;"," ");
                cSql=cSql.replaceAll("&quot;","\'");
                cSql=cSql.replace("${user_id}",String.valueOf(user.getId()));
                cSql=cSql.replace("${urlWhereSQL}",urlWhereSQL);
                componentList.get(i).put("sql_value",jdbcTemplate.queryForObject(cSql,String.class));
                continue;
            }
            if(showNumDataType.equals("3")){
                //扩展类
            }
        }
        retMap.put("componentData",componentList);
        return retMap;
    }

    public String getWhereSqlByFieldInfo(String tableSql,List<Map<String,Object>> fieldList, String jsonStr,JdbcTemplate jdbcTemplate,JackJSONObject retJson){
        JackJSONObject queryParamJson=JackJSONObject.fromObject(jsonStr).getJackJSONObject("queryParam");
        try {
            queryParamJson.size();
        } catch (Exception e) {
            return tableSql+" where 1=1 ";//todo 后续需要动态拼接：and status=0
        }
        return QueryConditionUtil.getWhereSqlByFieldInfo(tableSql,fieldList,jsonStr,jdbcTemplate,retJson);
    }

    public void executeJobByMethodName(String jobClassPath, Map<String,Object> dsMap,Map<String,Object> dataMap,String methodName){
        try {
            // 1. 加载类
            Class<?> jobClass = Class.forName(jobClassPath);

            // 2. 创建类的实例
            Object jobInstance = jobClass.getDeclaredConstructor().newInstance();

            // 3. 获取 `methodName` 方法（带有 Map<String, Object> 和 Map<String, Object> 参数）
            Method initMethod = jobClass.getMethod(methodName, Map.class, Map.class);

            // 4. 调用 `methodName` 方法
            initMethod.invoke(jobInstance, dsMap, dataMap);

        } catch (ClassNotFoundException e) {
            System.err.println("类路径错误，未找到类: " + jobClassPath);
        } catch (NoSuchMethodException e) {
            System.err.println("找不到 "+methodName+" 方法，请确保该方法存在并且参数正确。");
        } catch (Exception e) {
            System.err.println("调用 "+methodName+" 方法时发生错误: " + e.getMessage());
        }
    }

}

