package com.rongwei.bscommon.sys.service.impl;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rongwei.bscommon.sys.feign.RwAdminFeign;
import com.rongwei.bscommon.sys.service.SubConfigService;
import com.rongwei.bsentity.enums.InsttypeEnum;
import com.rongwei.bsentity.vo.KdSubsystemDetailVo;
import com.rongwei.rwcommon.base.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author shangmi
 * @title SubConfigServiceImpl
 * @date 2024/1/5 14:31
 * @description
 */
@Service
public class SubConfigServiceImpl implements SubConfigService {

    //0-21
    private final String[] JSON_NAME = {
            "urladdr", "insttype", "roption", "global", "base", "editPage", "id",
            "rowEdit", "layout", "form", "data", "tableColumnName", "columns",
            "tableColumnType", "tableName", "label", "dataSource", "formData",
            "insttype", "heads", "field","fullpid","linkUrl"
    };

    private final String[] TYPE_NAME = {
            "controlType", "enumType",
            "dict", "customapi", "custom", "sql", "pagesource",
            "customApiUrl", "customEnum", "customSql", "cacheIdSql",
            "ic-image-upload","file-upload"
    };

    private final String[] UNDERLYING_CONFIG = {
            "roption","dataSource","formData","mainsql"
    };

    @Autowired
    private RwAdminFeign rwAdminFeign;

    /**
     * 查询菜单字段详细
     *
     * @param id 菜单ID
     * @return {@link List< KdSubsystemDetailVo>}
     * @date 2024/1/8 11:48
     * @author shangmi
     */

    @Override
    public R getModulesById(String id) {
        R sysModule = rwAdminFeign.infoSysModule(id);
        // 获得pagePartID
        JSONObject module = JSONUtil.parseObj(sysModule.getData());
        Object urlAddr = module.get(JSON_NAME[0]);
        if (urlAddr == null) {
            return R.error("该菜单未配置编辑页或页编辑，请重新选择！");
        }
        String[] split = urlAddr.toString().split("/");
        String pagePartId = split[split.length - 1];

        // 获取编辑页信息
        String pagePart = getPagePart(pagePartId);
        if (pagePart == null) {
            return R.error("该菜单未配置编辑页或页编辑，请重新选择！");
        }
        String fullPid = module.getStr(JSON_NAME[21]);
        String subsystemId = fullPid.split(",")[1];
        // 查询页面展示的所有字段
        IPage<KdSubsystemDetailVo> res = new Page<>();
        res.setRecords(getTableNameByData(pagePart,subsystemId));
        return R.ok(res);
    }

    /**
     * 通过菜单ID查询菜单SQL
     *
     * @param id
     * @return {@link R}
     * @date 2024/1/13 16:57
     * @author shangmi
     *
     */

    @Override
    public R getTableSqlByModuleId(String id) {

        R sysModule = rwAdminFeign.infoSysModule(id);
        // 获得pagePartID
        JSONObject module = JSONUtil.parseObj(sysModule.getData());
        Object urlAddr = module.get(JSON_NAME[0]);
        if (urlAddr == null) {
            return R.error("该菜单未配置编辑页或页编辑，请重新选择！");
        }
        String[] split = urlAddr.toString().split("/");
        String pagePartId = split[split.length - 1];

        if (pagePartId == null) {
            return null;
        }
        R sysPagePart = rwAdminFeign.infoPagePart(pagePartId);
        //提取JSON中的sql
        return R.ok(JSONUtil.parseObj(JSONUtil.parseObj(JSONUtil.parseObj(JSONUtil.parseObj(sysPagePart.getData())
                .get(UNDERLYING_CONFIG[0])).get(UNDERLYING_CONFIG[1])).get(UNDERLYING_CONFIG[2])).get(UNDERLYING_CONFIG[3]));
    }


    /**
     * 根据pagePartID查到该ID
     *
     * @param pagePartId
     * @return {@link String}
     * @date 2024/1/5 16:54
     * @author shangmi
     */

    public String getPagePart(String pagePartId) {
        if (pagePartId == null) {
            return null;
        }
        R sysPagePart = rwAdminFeign.infoPagePart(pagePartId);
        JSONObject pagePart = JSONUtil.parseObj(sysPagePart.getData());
        if (InsttypeEnum.TABLE.getMassage().equals(pagePart.get(JSON_NAME[1], String.class))) {
            // 判断当前页面如果是table页且非行编辑时，将内部editPage页的ID获取并重新调用本方法
            if(!JSONUtil.parseObj(JSONUtil.parseObj(JSONUtil.parseObj(pagePart.get(JSON_NAME[2])).get(JSON_NAME[3]))
                            .get(JSON_NAME[4])).get(JSON_NAME[7], Boolean.class)){
                return pagePart.get(JSON_NAME[2], String.class);
            }else{
                return getPagePart(JSONUtil.parseObj(JSONUtil.parseObj(JSONUtil.parseObj(JSONUtil.parseObj(pagePart.get(JSON_NAME[2]))
                        .get(JSON_NAME[3])).get(JSON_NAME[4])).get(JSON_NAME[5])).get(JSON_NAME[6], String.class));
            }
        } else if (InsttypeEnum.FORM.getMassage().equals(pagePart.get(JSON_NAME[1], String.class))
                || (InsttypeEnum.TABLE.getMassage().equals(pagePart.get(JSON_NAME[1], String.class))
                && JSONUtil.parseObj(JSONUtil.parseObj(JSONUtil.parseObj(pagePart
                .get(JSON_NAME[2])).get(JSON_NAME[3])).get(JSON_NAME[4])).get(JSON_NAME[7], Boolean.class))) {
            // 当前页面为form时或者table是行编辑时返回他们的roption
            return pagePart.get(JSON_NAME[2], String.class);
        }
        return null;
    }


    /**
     * 查询页面展示的所有表名
     *
     * @param pagePart 编辑页ID
     * @param subsystemId   子系统ID
     * @return {@link List<String>}
     * @date 2024/1/8 10:09
     * @author shangmi
     */

    public List<KdSubsystemDetailVo> getTableNameByData(String pagePart,String subsystemId) {
        boolean instType = "table".equals(JSONUtil.parseObj(JSONUtil.parseObj(JSONUtil.parseObj(pagePart).get(JSON_NAME[16])).get(JSON_NAME[17])).get(JSON_NAME[18], String.class));
        // 获得layout中的form
        List<String> form = JSONUtil.toList(JSONUtil.parseObj(JSONUtil.parseObj(pagePart).get(JSON_NAME[8])).get(instType ? JSON_NAME[19] : JSON_NAME[9], String.class), String.class);
        // 将页面上展示的真实字段获取到
        List<String> tableColumNameList = form.stream().map(info -> instType ? JSONUtil.parseObj(info).get(JSON_NAME[20], String.class)
                        : JSONUtil.parseObj(JSONUtil.parseObj(info).get(JSON_NAME[10])).get(JSON_NAME[11], String.class))
                .filter(Objects::nonNull).collect(Collectors.toList());
        // 获取到columns中的base集合
        List<String> base = JSONUtil.toList(JSONUtil.parseObj(JSONUtil.parseObj(pagePart).get(JSON_NAME[12])).get(JSON_NAME[4], String.class), String.class);
        //获得FromID
        String[] linkUrl = JSONUtil.parseObj(JSONUtil.parseObj(JSONUtil.parseObj(pagePart).get(JSON_NAME[3])).get(JSON_NAME[4])).get(JSON_NAME[22], String.class).split("/");
        // 遍历获取base中的信息
        return base.stream()
                .filter(info -> tableColumNameList.contains(JSONUtil.parseObj(JSONUtil.parseObj(info).get(JSON_NAME[4])).get(JSON_NAME[11], String.class)))
                .map(info -> {
                    KdSubsystemDetailVo kdSubsystemDetail = new KdSubsystemDetailVo();
                    JSONObject json = JSONUtil.parseObj(JSONUtil.parseObj(info).get(JSON_NAME[4]));
                    String tableColumnNane = json.get(JSON_NAME[11], String.class);
                    kdSubsystemDetail.setTABLECOLUMNNANE(tableColumnNane);
                    kdSubsystemDetail.setPID(subsystemId);
                    kdSubsystemDetail.setFROMID(linkUrl[linkUrl.length-1]);
                    kdSubsystemDetail.setTABLECOLUMNTYPE(json.get(JSON_NAME[13], String.class));
                    kdSubsystemDetail.setTABLENAME(json.get(JSON_NAME[14], String.class));
                    kdSubsystemDetail.setLABEL(json.get(JSON_NAME[15], String.class));
                    JSONObject controlType = JSONUtil.parseObj(JSONUtil.parseObj(json.get(TYPE_NAME[0])));
                    String enumType = controlType.get(TYPE_NAME[1], String.class);
                    kdSubsystemDetail.setCONTROLTYPE(controlType.get(TYPE_NAME[0], String.class));
                    kdSubsystemDetail .setENUMTYPE(enumType);
                    if(TYPE_NAME[11].equals(controlType.get(TYPE_NAME[0]))||TYPE_NAME[12].equals(controlType.get(TYPE_NAME[0]))){
                        kdSubsystemDetail.setDATAORIGIN("file");
                        kdSubsystemDetail.setENUMTYPE("file_upload");
                    }
                    if (enumType == null) {
                        return kdSubsystemDetail;
                    }
                    if (TYPE_NAME[2].equals(enumType)) {
                        kdSubsystemDetail.setDATAORIGIN(controlType.get(TYPE_NAME[2], String.class));
                    } else if (TYPE_NAME[3].equals(enumType)) {
                        kdSubsystemDetail.setDATAORIGIN(controlType.get(TYPE_NAME[7], String.class));
                    } else if (TYPE_NAME[4].equals(enumType)) {
                        kdSubsystemDetail.setDATAORIGIN(controlType.get(TYPE_NAME[8], String.class));
                    } else if (TYPE_NAME[5].equals(enumType)) {
                        kdSubsystemDetail.setDATAORIGIN(controlType.get(TYPE_NAME[9], String.class));
                    } else if (TYPE_NAME[6].equals(enumType)) {
                        kdSubsystemDetail.setDATAORIGIN(controlType.get(TYPE_NAME[10], String.class));
                    }
                    return kdSubsystemDetail;
                }).collect(Collectors.toList());
    }


}
