package com.upyuns.platform.rs.website.biz;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.github.wxiaoqi.security.common.vo.PageDataVO;
import com.upyuns.platform.rs.gtdata.GtDataRestClient;
import com.upyuns.platform.rs.website.controller.AdminGaindataController;
import com.upyuns.platform.rs.website.dto.GainDataDTO;
import com.upyuns.platform.rs.website.entity.DataMenu;
import com.upyuns.platform.rs.website.entity.FileData;
import com.upyuns.platform.rs.website.entity.GaindataLog;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.upyuns.platform.rs.website.entity.GainData;
import com.upyuns.platform.rs.website.mapper.GainDataMapper;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import tk.mybatis.mapper.entity.Example;

import java.util.List;
import java.util.Map;

import static com.github.wxiaoqi.security.common.constant.CommonConstants.SYS_FALSE;

/**
 * 成果数据
 *
 * @author zjw
 * @email jiaoruizhen@126.com
 * @date 2024-05-15 18:31:38
 */
@Slf4j
@Service
public class GainDataBiz extends BaseBiz<GainDataMapper,GainData> {

    @Autowired
    DataMenuBiz dataMenuBiz;

    @Value("${universal.gaindataPath}")
    private String gaindataPath;

    @Autowired
    FileDataBiz fileDataBiz;

    @Autowired
    GtDataRestClient gtDataRestClient;

    @Autowired
    GaindataLogBiz gaindataLogBiz;


    public DataMenu getTopMenu(Map<Integer, DataMenu> dataMenuMap, DataMenu dataMenu){
        if(dataMenu != null && dataMenu.getParentId() != null && dataMenu.getParentId() != -1) {
            if(null == dataMenuMap.get(dataMenu.getParentId())) {
                return dataMenu;
            }else {
                return getTopMenu(dataMenuMap,dataMenuMap.get(dataMenu.getParentId()));
            }
        }else {
            return dataMenu;
        }
    }

    @Data
    static public class DataMenuStats extends DataMenu {
        Integer dataNum = 0;
    }

    public void handleDataNum(Map<Integer, DataMenuStats> dataMenuMap, DataMenu dataMenu){
        if(dataMenu != null) {
            DataMenuStats stats =  dataMenuMap.get(dataMenu.getId());
            stats.setDataNum(stats.getDataNum() + 1);
            if(dataMenu.getParentId() != null && dataMenu.getParentId() != -1) {
                if(null == dataMenuMap.get(dataMenu.getParentId())) {
                    return;
                }else {
                    handleDataNum(dataMenuMap,dataMenuMap.get(dataMenu.getParentId()));
                }
            }else {
                return;
            }
        }
    }

    public Example initExample(GainDataDTO dto) {
        Example example = new Example(GainData.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("isDel", 0);
        criteria.andEqualTo("status",2);
        if (StringUtils.isNotBlank(dto.getMenuId())){
            criteria.andEqualTo("menuId", dto.getMenuId());
        }

        if (StrUtil.isNotBlank(dto.getTopMenuId())){
            criteria.andIn("menuId", dataMenuBiz.getIdsByTopId(Integer.valueOf(dto.getTopMenuId())));
        }

        if (StrUtil.isNotBlank(dto.getTime())){
            criteria.andEqualTo("time", dto.getTime());
        }
        if (StrUtil.isNotBlank(dto.getSupplier())){
            criteria.andLike("supplier", "%" + dto.getSupplier() + "%");
        }
        if (StrUtil.isNotBlank(dto.getName())){
            criteria.andLike("name", "%" + dto.getName() + "%");
        }
        if (null != dto.getCrtTimeStart()){
            criteria.andGreaterThanOrEqualTo("crtTime", DateUtil.beginOfDay(dto.getCrtTimeStart()));
        }
        if (null != dto.getCrtTimeEnd()){
            criteria.andLessThanOrEqualTo("crtTime", DateUtil.endOfDay(dto.getCrtTimeEnd()));
        }
        return example;
    }

    public void dealGtdata(List<GainData> list) {
        for(GainData gainData: list) {
            String gtdataPath = gainData.getGtdataPath();
            //判断gtdata路径是否存在
            if(StrUtil.isBlank(gtdataPath)) {
                //根据id创建gtdata目录
                gtdataPath = "/rscloudmart"+ gaindataPath + "/" + gainData.getId();
                gtDataRestClient.mkdirs(gtdataPath);
//                gainData.setGtdataPath(gtdataPath);
                String finalGtdataPath = gtdataPath;
                updateSelectiveById(new GainData() {{
                    setId(gainData.getId());
                    setGtdataPath(finalGtdataPath);
                    setHasGtdata(HASGTDATA_FIN);
                }});
            }else {
                //判断路径是否存在
                //isExist(parentPath).get("exist").toString().equals("true")
                if(!gtDataRestClient.isExist(gtdataPath).get("exist").toString().equals("true")){
                    gtDataRestClient.mkdirs(gtdataPath);
                    updateSelectiveById(new GainData() {{
                        setId(gainData.getId());
                        setHasGtdata(HASGTDATA_FIN);
                    }});
                }
            }

            //查询包含的数据是否存在
            List<FileData> fileDataList = fileDataBiz.selectList(new FileData(){{
                setGainId(gainData.getId());
                setIsDel(SYS_FALSE);
                setHasGtdata(HASGTDATA_NOT);
            }});

            Boolean flag = true;
            for(FileData fileData : fileDataList) {
                if(StrUtil.isBlank(fileData.getGtdataPath())) {
                    String fileGtdataPath = gtdataPath + "/" + fileData.getFilename();
                    FileData finalFileData = fileData;
                    fileDataBiz.updateSelectiveById(new FileData(){{
                        setId(finalFileData.getId());
                        setGtdataPath(fileGtdataPath);
                    }});
                    fileData = fileDataBiz.selectById(fileData.getId());
                }
                if(!gtDataRestClient.isExist(fileData.getGtdataPath()).get("exist").toString().equals("true")){
                    Map<String, Object> responseMap = gtDataRestClient.createLarge(fileData.getFilepath(), fileData.getGtdataPath());
                    if (responseMap == null || 200 != (Integer) responseMap.get("HttpStatusCode")) {
                        log.error(JSONUtil.toJsonStr(responseMap), responseMap);
                        flag = false;
//                        continue;
                    }
                }
            }

            if(flag) {
                fileDataBiz.updateSelectiveById(new FileData(){{
                    setId(gainData.getId());
                    setHasGtdata(HASGTDATA_FIN);
                }});
            }
        }
    }

    public PageDataVO<AdminGaindataController.GainDataVO> selectPageVO(GainDataDTO dto) {
        Example example = initExample(dto);
//        Example example = new Example(GainData.class);
        Example.Criteria criteria = example.createCriteria();
//        criteria.andEqualTo("isDel", 0);
        example.setOrderByClause("crt_time desc");
        PageDataVO<AdminGaindataController.GainDataVO> pageDataVO = PageDataVO.pageInfo(dto.initQuery(), ()->selectByExample(example), AdminGaindataController.GainDataVO.class);
        if(dto.getNeedLog()) {
            pageDataVO.getData().forEach(gainDataVO -> {
                gainDataVO.setGaindataLogs(gaindataLogBiz.selectAll(new GaindataLog(){{
                    setGainId(gainDataVO.getId());
                    setIsDel(SYS_FALSE);
                }}));
            });
        }
        return pageDataVO;
    }

    public List<AdminGaindataController.GainDataVO> selectNoPageVO(GainDataDTO dto) {
        Example example = initExample(dto);
//        Example example = new Example(GainData.class);
        Example.Criteria criteria = example.createCriteria();
//        criteria.andEqualTo("isDel", 0);
        example.setOrderByClause("crt_time desc");
        List<AdminGaindataController.GainDataVO> pageDataVO = Convert.toList(AdminGaindataController.GainDataVO.class, selectByExample(example));
        if(dto.getNeedLog() || dto.getNeedFile()) {
            pageDataVO.forEach(gainDataVO -> {
                if(dto.getNeedLog()) {
                    gainDataVO.setGaindataLogs(gaindataLogBiz.selectAll(new GaindataLog(){{
                        setGainId(gainDataVO.getId());
                        setIsDel(SYS_FALSE);
                    }}));
                }
                if(dto.getNeedFile()) {
                    gainDataVO.setGaindataFiles(fileDataBiz.selectAll(new FileData(){{
                        setGainId(gainDataVO.getId());
                        setIsDel(SYS_FALSE);
                    }}));
                }
            });
        }
        return pageDataVO;
    }
}