package com.hzs.member.structure.controller.api;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hzs.common.core.constant.CountryConstants;
import com.hzs.common.core.constant.MemberConstants;
import com.hzs.common.core.constant.MemberFrameworkConstants;
import com.hzs.common.core.constant.TableNameConstants;
import com.hzs.common.core.domain.R;
import com.hzs.common.core.enums.ECategory;
import com.hzs.common.core.enums.EGrade;
import com.hzs.common.core.enums.EPlaceDept;
import com.hzs.common.core.enums.EYesNo;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.core.web.controller.BaseController;
import com.hzs.common.core.web.domain.AjaxResult;
import com.hzs.common.domain.member.achieve.CuMemberSettlePeriod;
import com.hzs.common.domain.member.ext.CuMemberSettleExt;
import com.hzs.common.domain.system.base.BdCountry;
import com.hzs.common.domain.system.config.BdBonusExpand;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.member.achieve.service.ICuMemberSettlePeriodService;
import com.hzs.member.achieve.service.ICuMemberTreeService;
import com.hzs.member.base.service.ICuMemberService;
import com.hzs.member.structure.controller.vo.CuMemberSettlePeriodVo;
import com.hzs.system.base.ICountryServiceApi;
import com.hzs.system.base.ISystemConfigServiceApi;
import com.hzs.system.config.IGradeServiceApi;
import com.hzs.system.config.dto.GradeDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/member-structure")
@Slf4j
public class ApiMemberStructureController extends BaseController {

    @Autowired
    private ICuMemberSettlePeriodService iCuMemberSettlePeriodService;
    @Autowired
    private ICuMemberTreeService iCuMemberTreeService;
    @Autowired
    private ICuMemberService iCuMemberService;

    @DubboReference
    IGradeServiceApi iGradeServiceApi;
    @DubboReference
    ICountryServiceApi iCountryServiceApi;
    @DubboReference
    ISystemConfigServiceApi systemConfigServiceApi;

    public List<Tree<String>> setTreeList(List<Tree<String>> build, Integer numberOfPlies, Map<Integer, BdCountry> allCountryData) {
        for (Tree<String> stringTree : build) {
            Integer level = (Integer) stringTree.get("level");
            if (level < (numberOfPlies - 1)) {
                if (stringTree.getChildren() != null) {
                    if (stringTree.getChildren().size() == 0) {
                        Tree<String> emptyNode1 = TreeUtil.createEmptyNode(RandomUtil.randomNumbers(5));
//                        emptyNode1.putExtra("placeDept", EPlaceDept.LEFT_DEPT.getValue());
                        emptyNode1.putExtra("level", level + 1);
//                        emptyNode1.putExtra("memberCode", "");
//                        emptyNode1.setName("-");
                        emptyNode1.setParentId(stringTree.getId());
                        emptyNode1.setId(RandomUtil.randomNumbers(3));
//                        emptyNode1.putExtra("avatarUrl", MemberFrameworkConstants.xuni);
//                        emptyNode1.putExtra("settleCountryUrl", nationalFlag1);
//                        emptyNode1.putExtra("settleCountryUrl2", nationalFlag2);
//                        emptyNode1.putExtra("countryUrl", nationalFlag1);
//                        emptyNode1.putExtra("countryUrl2", nationalFlag2);
                        stringTree.getChildren().add(emptyNode1);
                        setTreeList(stringTree.getChildren(), numberOfPlies, allCountryData);

                        Tree<String> emptyNode2 = TreeUtil.createEmptyNode(RandomUtil.randomNumbers(5));
//                        emptyNode2.putExtra("placeDept", EPlaceDept.RIGHT_DEPT.getValue());
                        emptyNode2.putExtra("level", level + 1);
//                        emptyNode2.putExtra("memberCode", "");
//                        emptyNode2.setName("-");
                        emptyNode2.setParentId(stringTree.getId());
                        emptyNode2.setId(RandomUtil.randomNumbers(3));
//                        emptyNode2.putExtra("settleCountryUrl", nationalFlag1);
//                        emptyNode2.putExtra("settleCountryUrl2", nationalFlag2);
//                        emptyNode2.putExtra("countryUrl", nationalFlag1);
//                        emptyNode2.putExtra("countryUrl2", nationalFlag2);
//                        emptyNode2.putExtra("avatarUrl", MemberFrameworkConstants.xuni);
                        stringTree.getChildren().add(emptyNode2);
                        setTreeList(stringTree.getChildren(), numberOfPlies, allCountryData);
                    } else if (stringTree.getChildren().size() == 1) {
                        List<Tree<String>> cli = stringTree.getChildren();
                        Integer pd = (Integer) cli.get(0).get("placeDept");
                        Tree<String> emptyNode = TreeUtil.createEmptyNode(RandomUtil.randomNumbers(5));
                        if (pd.equals(EPlaceDept.LEFT_DEPT.getValue())) {
//                            emptyNode.putExtra("placeDept", EPlaceDept.RIGHT_DEPT.getValue());
                            emptyNode.putExtra("level", level + 1);
//                            emptyNode.putExtra("memberCode", "");
//                            emptyNode.setName("-");
//                            emptyNode.putExtra("settleCountryUrl", nationalFlag1);
//                            emptyNode.putExtra("settleCountryUrl2", nationalFlag2);
//                            emptyNode.putExtra("countryUrl", nationalFlag1);
//                            emptyNode.putExtra("countryUrl2", nationalFlag2);
//                            emptyNode.putExtra("avatarUrl", MemberFrameworkConstants.xuni);
                            emptyNode.setParentId(stringTree.getId());
                            emptyNode.setId(RandomUtil.randomNumbers(3));
                            stringTree.getChildren().add(emptyNode);
                            setTreeList(stringTree.getChildren(), numberOfPlies, allCountryData);
                        } else {
//                            emptyNode.putExtra("placeDept", EPlaceDept.LEFT_DEPT.getValue());
                            emptyNode.putExtra("level", level + 1);
//                            emptyNode.putExtra("memberCode", "");
//                            emptyNode.setName("-");
                            emptyNode.setParentId(stringTree.getId());
                            emptyNode.setId(RandomUtil.randomNumbers(3));
//                            emptyNode.putExtra("avatarUrl", MemberFrameworkConstants.xuni);
//                            emptyNode.putExtra("settleCountryUrl", nationalFlag1);
//                            emptyNode.putExtra("settleCountryUrl2", nationalFlag2);
//                            emptyNode.putExtra("countryUrl", nationalFlag1);
//                            emptyNode.putExtra("countryUrl2", nationalFlag2);
                            stringTree.getChildren().add(emptyNode);
                            List<Tree<String>> strTree = stringTree.getChildren();
                            List<Tree<String>> sortChildren = new ArrayList<>();
                            sortChildren.add(strTree.get(1));
                            sortChildren.add(strTree.get(0));
                            stringTree.setChildren(sortChildren);
                            setTreeList(sortChildren, numberOfPlies, allCountryData);
                        }
                    } else {
                        List<Tree<String>> children = stringTree.getChildren();
                        List<Tree<String>> sortChildren = new ArrayList<>();
                        int pd = Integer.parseInt(children.get(0).get("placeDept").toString());
                        if (pd == 1) {
                            sortChildren.add(children.get(0));
                            sortChildren.add(children.get(1));
                        } else {
                            sortChildren.add(children.get(1));
                            sortChildren.add(children.get(0));
                        }
                        stringTree.setChildren(sortChildren);
                        setTreeList(stringTree.getChildren(), numberOfPlies, allCountryData);
                    }
                } else {
                    // 等于空
                    List<Tree<String>> children = new ArrayList<>();
                    Tree<String> emptyNode1 = TreeUtil.createEmptyNode(RandomUtil.randomNumbers(5));
//                    emptyNode1.putExtra("placeDept", EPlaceDept.LEFT_DEPT.getValue());
                    emptyNode1.putExtra("level", level + 1);
//                    emptyNode1.putExtra("memberCode", "");
//                    emptyNode1.setName("-");
//                    emptyNode1.putExtra("avatarUrl", MemberFrameworkConstants.xuni);
//                    emptyNode1.putExtra("settleCountryUrl", nationalFlag1);
//                    emptyNode1.putExtra("settleCountryUrl2", nationalFlag2);
//                    emptyNode1.putExtra("countryUrl", nationalFlag1);
//                    emptyNode1.putExtra("countryUrl2", nationalFlag2);
                    emptyNode1.setParentId(stringTree.getId());
                    emptyNode1.setId(RandomUtil.randomNumbers(3));
                    children.add(emptyNode1);

                    Tree<String> emptyNode2 = TreeUtil.createEmptyNode(RandomUtil.randomNumbers(5));
//                    emptyNode2.putExtra("placeDept", EPlaceDept.RIGHT_DEPT.getValue());
                    emptyNode2.putExtra("level", level + 1);
//                    emptyNode2.putExtra("memberCode", "");
//                    emptyNode2.setName("-");
//                    emptyNode2.putExtra("settleCountryUrl", nationalFlag1);
//                    emptyNode2.putExtra("settleCountryUrl2", nationalFlag2);
//                    emptyNode2.putExtra("countryUrl", nationalFlag1);
//                    emptyNode2.putExtra("countryUrl2", nationalFlag2);
//                    emptyNode2.putExtra("avatarUrl", MemberFrameworkConstants.xuni);
                    emptyNode2.setParentId(stringTree.getId());
                    emptyNode2.setId(RandomUtil.randomNumbers(3));
                    children.add(emptyNode2);

                    stringTree.setChildren(children);
                    setTreeList(children, numberOfPlies, allCountryData);
                }
            }
        }
        return build;
    }

    /**
     * 查询最近一月所有期数
     *
     * @return
     */
    @GetMapping("/get-member-settle-period")
    public AjaxResult getMemberSettlePeriod() {
        // 查询最近一月的数据
        DateTime dateTime = DateUtil.lastMonth();
        QueryWrapper<CuMemberSettlePeriod> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("SETTLE_DATE");
        Date date = DateUtils.currentDate();
        if (DateUtils.getCurrentHour() < 2) {
            date = DateUtils.beforeDate(2, ChronoUnit.DAYS, date);
        }
        queryWrapper.between("SETTLE_DATE", dateTime, date);
        List<CuMemberSettlePeriod> list = iCuMemberSettlePeriodService.list(queryWrapper);
        List<CuMemberSettlePeriodVo> resultList = new ArrayList<>();
        for (CuMemberSettlePeriod cuMemberSettlePeriod : list) {
            CuMemberSettlePeriodVo cuMemberSettlePeriodVo = BeanUtil.copyProperties(cuMemberSettlePeriod, CuMemberSettlePeriodVo.class);
            if (DateUtils.parseDateToFormat(DateUtils.YYYY_MM_DD, cuMemberSettlePeriod.getSettleDate()).equals(DateUtils.parseDateToFormat(DateUtils.YYYY_MM_DD, DateUtils.currentDate()))) {
                cuMemberSettlePeriodVo.setIsThisDay(EYesNo.YES.getIntValue());
            } else {
                cuMemberSettlePeriodVo.setIsThisDay(EYesNo.NO.getIntValue());
            }
            resultList.add(cuMemberSettlePeriodVo);
        }
        return AjaxResult.success(resultList);
    }


    /**
     * 获取头像信息
     *
     * @return
     */
    @GetMapping("/get-avatar-info")
    public AjaxResult getAvatarUrl() {
        Integer pkCountry = SecurityUtils.getPkCountry();
        JSONArray array = new JSONArray();
        // 虚拟
        JSONObject other = new JSONObject();
        other.put("name", ECategory.getLabelByValue(Math.abs(EGrade.VIRTUALLY.getIndex())));
        other.put("value", MemberFrameworkConstants.xuni);
        array.add(other);
        // 已注销
        JSONObject zxOther = new JSONObject();
        zxOther.put("name", ECategory.getLabelByValue(Math.abs(EGrade.LOGGED_OUT.getIndex())));
        zxOther.put("value", MemberFrameworkConstants.LOG_OFF);
        array.add(zxOther);
        // 待激活  非中国
        if (!SecurityUtils.getPkCountry().equals(CountryConstants.CHINA_COUNTRY)) {
            JSONObject djhOther = new JSONObject();
            djhOther.put("name", ECategory.getLabelByValue(Math.abs(EGrade.DEAD_POINT.getIndex())));
            djhOther.put("value", MemberFrameworkConstants.toBeActivated);
            array.add(djhOther);
        }
        R<List<GradeDTO>> list = iGradeServiceApi.selectGradeAll(pkCountry);

        for (GradeDTO date : list.getData()) {
            JSONObject js = new JSONObject();
            js.put("name", date.getGradeName());
            js.put("value", date.getIcon());
            array.add(js);
        }
        return AjaxResult.success(array);
    }

    @GetMapping("/az-framework")
    public AjaxResult azFramework() {
        Integer level = 1;
        List<Tree<String>> result = null;
        Date date = new Date();
        String time = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, date);
        LocalDate beforeLocalDate = DateUtils.getStringToLocalDate(time).minus(1, ChronoUnit.DAYS);
        time = beforeLocalDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        Long pkMember = SecurityUtils.getUserId();
        Integer period = null;
        CuMemberSettlePeriod csPeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(time);
        if (csPeriod != null) {
            period = csPeriod.getPkId();
        }

        // 查询 历史
        String settleTableName = TableNameConstants.CU_MEMBER_SETTLE + period;
        Integer tableNumber = iCuMemberTreeService.queryExistOracleTable(settleTableName);
        if (tableNumber != null && tableNumber == 1) {
            // 表示表格存在
            // 查询顶点
            CuMemberSettleExt memberSettleExt = iCuMemberTreeService.queryCuMemberTreeByPkMemberTable(settleTableName, pkMember);
            if (null == memberSettleExt.getPkPlaceParent()) {
                // 0元会员
                return AjaxResult.success();
            }
            if (MemberConstants.GJ30720200CODE.equals(memberSettleExt.getParentMemberCode())) {
                memberSettleExt.setParentMemberCode(memberSettleExt.getMemberCode());
            }
            memberSettleExt.setLevel(0);
            //查询下级
            List<CuMemberSettleExt> list = iCuMemberTreeService.queryCuMemberTreePlaceParentHistoryFramework(settleTableName, pkMember, new ArrayList<>(), level);
            // 无法查询到自身 所有单独查询自身并且添加
            list.add(memberSettleExt);
            List<Tree<String>> build = iCuMemberService.systemAzSetListTree(list, memberSettleExt);
            // 安置架构 无点位 追加空点位
            R<Map<Integer, BdCountry>> allCountryMap = iCountryServiceApi.getAllCountryMap();
            Map<Integer, BdCountry> allCountryData = allCountryMap.getData();
            result = setTreeList(build, level, allCountryData);
        }

        BdBonusExpand bdBonusExpand = systemConfigServiceApi.getBdBonusExpand().getData();
        assert result != null;
        String leftFirstSurplusStr = result.get(0).get("leftFirstSurplus").toString();
        String rightFirstSurplusStr = result.get(0).get("rightFirstSurplus").toString();
        BigDecimal leftFirstSurplus = new BigDecimal(leftFirstSurplusStr.replaceAll(",", ""));
        BigDecimal rightFirstSurplus = new BigDecimal(rightFirstSurplusStr.replaceAll(",", ""));
        result.get(0).putExtra("leftFirstSurplus", leftFirstSurplus.toString());
        result.get(0).putExtra("rightFirstSurplus", rightFirstSurplus.toString());
        result.get(0).putExtra("leftFirstSurplusAll", formatBigDecimal(leftFirstSurplus));
        result.get(0).putExtra("rightFirstSurplusAll", formatBigDecimal(rightFirstSurplus));
        log.info("result : {}", JSONUtil.toJsonStr(result));
        if (leftFirstSurplus.compareTo(rightFirstSurplus) >= 0) {
            // 左大右小
            if (leftFirstSurplus.compareTo(bdBonusExpand.getExpandBig()) > 0) {
                result.get(0).putExtra("leftFirstSurplus", bdBonusExpand.getExpandBig().toString());
            }
            if (rightFirstSurplus.compareTo(bdBonusExpand.getExpandSmall()) > 0) {
                result.get(0).putExtra("rightFirstSurplus", bdBonusExpand.getExpandSmall().toString());
            }
        } else {
            // 左小右大
            if (leftFirstSurplus.compareTo(bdBonusExpand.getExpandSmall()) > 0) {
                result.get(0).putExtra("leftFirstSurplus", bdBonusExpand.getExpandSmall().toString());
            }
            if (rightFirstSurplus.compareTo(bdBonusExpand.getExpandBig()) > 0) {
                result.get(0).putExtra("rightFirstSurplus", bdBonusExpand.getExpandBig().toString());
            }
        }
        JSONObject data = new JSONObject();
        data.put("tree", result);
        return AjaxResult.success(data);
    }

    private static final BigDecimal FIVE_MILLION = BigDecimal.valueOf(5_000_000); // 500万的固定值

    /**
     * 格式化BigDecimal数值为指定规则的字符串
     *
     * @param input 输入的BigDecimal数值（需非null）
     * @return 格式化后的字符串（小于500万返回四舍五入两位小数，否则返回"500万+"）
     */
    public static String formatBigDecimal(BigDecimal input) {
        if (input == null) {
            throw new IllegalArgumentException("输入数值不能为null");
        }
        int compareResult = input.compareTo(FIVE_MILLION);
        if (compareResult < 0) {
            BigDecimal rounded = input.setScale(2, RoundingMode.HALF_UP);
            return rounded.toString();
        } else {
            return "5000000";
        }
    }
}
