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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.github.wxiaoqi.security.admin.constant.AdminCommonConstant;
import com.github.wxiaoqi.security.auth.client.annotation.IgnoreUserToken;
import com.github.wxiaoqi.security.common.annotation.HeadName;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.rest.BaseController;
import com.github.wxiaoqi.security.common.util.process.ResultCode;
import com.github.wxiaoqi.security.common.vo.PageDataVO;
import com.upyuns.platform.rs.gtdata.GtDataRestClient;
import com.upyuns.platform.rs.gtdata.GtFileInfo;
import com.upyuns.platform.rs.website.biz.DataMenuBiz;
import com.upyuns.platform.rs.website.biz.DataTempcacheBiz;
import com.upyuns.platform.rs.website.biz.FileDataBiz;
import com.upyuns.platform.rs.website.biz.GainDataBiz;
import com.upyuns.platform.rs.website.controller.web.GainDataController;
import com.upyuns.platform.rs.website.dto.FileDataDTo;
import com.upyuns.platform.rs.website.dto.GainDataDTO;
import com.upyuns.platform.rs.website.entity.*;
import com.upyuns.platform.rs.website.vo.DataMenuTree;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import tk.mybatis.mapper.entity.Example;

import javax.persistence.Column;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.github.wxiaoqi.security.common.constant.CommonConstants.SYS_TRUE;
import static com.upyuns.platform.rs.website.controller.AdminGaindataController.GainDataAdminDTO.STATISTICSTYPE_SUPPLIER;
import static com.upyuns.platform.rs.website.controller.AdminGaindataController.GainDataAdminDTO.STATISTICSTYPE_TOPMENU;

@RestController
@RequestMapping("Gaindata")
@Slf4j
public class AdminGaindataController extends BaseController<GainDataBiz, GainData> {


    @Autowired
    DataTempcacheBiz dataTempcacheBiz;

    @Autowired
    DataMenuBiz dataMenuBiz;

    @Autowired
    FileDataBiz fileDataBiz;

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

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

    @Autowired
    GtDataRestClient gtDataRestClient;

    @Override
    public ObjectRestResponse<GainData> baseAdd(@RequestBody GainData gainData) {
        super.baseAdd(gainData);
        GainData updateGainData = new GainData();
        updateGainData.setId(gainData.getId());
        //创建目录
        if(!FileUtil.exist(baseUploadPath+gaindataPath+"/"+gainData.getId())) {
            FileUtil.mkdir(baseUploadPath+gaindataPath+"/"+gainData.getId());
        }
        updateGainData.setDataPath(baseUploadPath+gaindataPath+"/"+gainData.getId());
        baseBiz.updateSelectiveById(updateGainData);
        return ObjectRestResponse.succ();
    }

    @RequestMapping(value = "/getPageList",method = RequestMethod.GET)
    public ObjectRestResponse<PageDataVO> getPageList(GainDataDTO dto) {
//        PageDataVO pageDataVO = PageDataVO.pageInfo(dto.getPage(), dto.getLimit(), ()->baseBiz.selectByExample(example));
        return ObjectRestResponse.succ(baseBiz.selectPageVO(dto));
    }

    @Data
    static public class GainDataVO extends GainData {
        public List<GaindataLog> gaindataLogs;
        public List<FileData> gaindataFiles;
    }

    @RequestMapping(value = "/deleteById",method = RequestMethod.DELETE)
    public ObjectRestResponse deleteById(Integer id) {
        GainData monitorimage = new GainData();
        monitorimage.setId(id);
        monitorimage.setIsDel(1);
        baseBiz.updateSelectiveById(monitorimage);
        return ObjectRestResponse.succ();
    }




    @ApiModelProperty("查看文件列表")
    @RequestMapping(value = "/getFileDataList",method = RequestMethod.GET)
    public ObjectRestResponse<PageDataVO<FileData>> getList(FileDataDTo fileDataDTo){
        return ObjectRestResponse.succ(fileDataBiz.selectLogicAlls(fileDataDTo));
    }



    @ApiModelProperty("添加修改文件")
    @RequestMapping(value = "/addFileData",method = RequestMethod.POST)
    public ObjectRestResponse <FileData> addislandShip(@RequestBody FileData fileData) {

        if(null != fileData.getDatatempId()) {
            DataTempcache dataTempcache = dataTempcacheBiz.selectById(fileData.getId());
            fileData.setFilename(dataTempcache.getFilename());
            fileData.setFiletype(dataTempcache.getFiletype());
            fileData.setFilesize(dataTempcache.getFilesize());
            fileData.setGtdataPath(dataTempcache.getGtdataPath());
            fileData.setHasGtdata(dataTempcache.getHasGtdata());
            if(dataTempcache.getUptype() == DataTempcache.UPTYPE_UPLOAD || dataTempcache.getUptype() == DataTempcache.UPTYPE_URL ) {
                fileData.setFilepath(dataTempcache.getFilepath());
                fileData.setFileurl(dataTempcache.getFilename());
                fileData.setStoragetype(FileData.STORAGETYPE_UPLOAD);
            }else {
                fileData.setStoragetype(FileData.STORAGETYPE_GTDATA);
            }
        } if(null != fileData.getStoragetype() && FileData.STORAGETYPE_GTDATA == fileData.getStoragetype()) {
//            //gtdtat 获取数据
            Map<String, Object> responseMap = gtDataRestClient.list(fileData.getGtdataPath());
            if(null != responseMap && null != responseMap.get("HttpStatusCode") && null != responseMap.get("files") && 200 == (Integer) responseMap.get("HttpStatusCode")) {
//                (List<GtFileInfo>)responseMap.get("files")
                List<GtFileInfo> gtFileInfos = Convert.toList(GtFileInfo.class, responseMap.get("files"));
                GtFileInfo gtFileInfo = gtFileInfos.get(0);
                String filename = gtFileInfo.getFilename();
                String filesize = gtFileInfo.getSize();

                String filetype = filename.substring(filename.lastIndexOf("."));
                long fileSize = Long.valueOf(filesize);
                //  double fileSizeInKB = (double) fileSize / 1024; // 转换为 KB
                double fileSizeInMB = (double) fileSize / (1024 * 1024); // 转换为 MB
                double roundedFileSizeInMB = Math.round(fileSizeInMB * 100.0) / 100.0; // 保留两位小数
                String fileSizeString = String.format("%.2f MB", roundedFileSizeInMB);

                fileData.setHasGtdata(SYS_TRUE);
                fileData.setFilename(filename);
                fileData.setFiletype(filetype);
                fileData.setFilesize(fileSizeString);
            }else {
                return ObjectRestResponse.createFailedResult(ResultCode.FAILED_CODE, "分布式路径不对");
            }
        }

//        String name = fileData.getFilename();
//        List<FileData> islandShips = fileDataBiz.selectByWeekend(o -> {
//            o.andEqualTo(FileData::getFilename, name + "");
//            o.andEqualTo(FileData::getIsDel,0);
//            if (fileData.getId() != null) {
//                o.andNotEqualTo(FileData::getId, fileData.getId());  //修改的時候 不把自己搜出來
//            }
//            return  o;
//        });
//        if (islandShips.size()!=0){
//            return ObjectRestResponse.createFailedResult(ResultCode.EXIST_CODE, ResultCode.getMsg(ResultCode.EXIST_CODE));
//        }

        if (fileData.getId()!=null){
            fileDataBiz.updateSelectiveById(fileData);
        }else {
            fileData.setIsDel(0);
            fileDataBiz.insertSelective(fileData);
        }
        if(null != fileData.getGainId()) {
            baseBiz.updateSelectiveById(new GainData(){{
                setId(fileData.getGainId());
                setHasGtdata(HASGTDATA_UPD);
            }});
        }

        return ObjectRestResponse.succ();
    }

    @DeleteMapping("/filedeleteById")
    public ObjectRestResponse deleteInoPortAnalyse(Integer id) {
        FileData fileData = new FileData();
        fileData.setId(id);
        fileData.setIsDel(1);
        fileDataBiz.updateSelectiveById(fileData);
        return ObjectRestResponse.succ();
    }

    @ApiModelProperty("统计")
    @IgnoreUserToken
    @RequestMapping(value = "/app/unauth/statistics",method = RequestMethod.GET)
    public ObjectRestResponse<List<GainData>> statistics(GainDataAdminDTO dto) {
        Example example = baseBiz.initExample(dto);

        List<GainData> list = baseBiz.selectByExample(example);
        List<DataMenu> dataMenuList = dataMenuBiz.selectListAll();
        List<GainDataController.GainDataVO> voList = Convert.toList(GainDataController.GainDataVO.class, list);
        Map<Integer, DataMenu> dataMenuMap = dataMenuList.parallelStream().collect(Collectors.toMap(DataMenu::getId, Function.identity()));
        for(GainDataController.GainDataVO gainDataVO : voList) {
            if(null != gainDataVO.getMenuId()) {
                DataMenu topMenu = baseBiz.getTopMenu(dataMenuMap, dataMenuMap.get(gainDataVO.getMenuId()));
                if(null != topMenu) {
                    gainDataVO.setTopMenuId(topMenu.getId());
                    gainDataVO.setTopMenuName(topMenu.getTitle());
                }
            }
        }
        Map<String, Long> map = CollUtil.newHashMap();
        if(dto.getStatisticsType() == null || dto.getStatisticsType() == STATISTICSTYPE_SUPPLIER) {
                        map = list.parallelStream().filter(o -> StrUtil.isNotBlank(o.getSupplier())).collect(Collectors.groupingBy(GainData::getSupplier, Collectors.counting()));
        }else if(dto.getStatisticsType() == STATISTICSTYPE_TOPMENU) {
            map = voList.parallelStream().filter(o -> (null != o.getMenuId())).collect(Collectors.groupingBy(GainDataController.GainDataVO::getTopMenuName, Collectors.counting()));
        }

        return ObjectRestResponse.succ(map);
    }

    @ApiModelProperty("统计-供应商")
    @IgnoreUserToken
    @RequestMapping(value = "/app/unauth/statistics/supplier",method = RequestMethod.GET)
    public ObjectRestResponse statisticsSupplier(GainDataAdminDTO dto) {
        Example example = baseBiz.initExample(dto);

        List<GainData> list = baseBiz.selectByExample(example);
        List<DataMenu> dataMenuList = dataMenuBiz.selectListAll();
        List<GainDataController.GainDataVO> voList = Convert.toList(GainDataController.GainDataVO.class, list);
        Map<Integer, DataMenu> dataMenuMap = dataMenuList.parallelStream().collect(Collectors.toMap(DataMenu::getId, Function.identity()));
        for(GainDataController.GainDataVO gainDataVO : voList) {
            if(null != gainDataVO.getMenuId()) {
                DataMenu topMenu = baseBiz.getTopMenu(dataMenuMap, dataMenuMap.get(gainDataVO.getMenuId()));
                if(null != topMenu) {
                    gainDataVO.setTopMenuId(topMenu.getId());
                    gainDataVO.setTopMenuName(topMenu.getTitle());
                }
            }
        }

        List<SupplierStatistics> returnList = CollUtil.newArrayList();
        Map<String, Long> map = CollUtil.newHashMap();
        map = list.parallelStream().filter(o -> StrUtil.isNotBlank(o.getSupplier())).collect(Collectors.groupingBy(GainData::getSupplier, Collectors.counting()));
        handleTree(dto, returnList, map);
        return ObjectRestResponse.succ(returnList);
    }

    private void handleTree(GainDataAdminDTO dto, List<SupplierStatistics> returnList, Map<String, Long> map) {
        for(String supplierName : map.keySet()) {
            dto.setSupplier(supplierName);
            Example example = baseBiz.initExample(dto);

            List<GainData> list2 = baseBiz.selectByExample(example);
            List<DataMenu> dataMenuList = dataMenuBiz.selectListAll();
            List<GainDataBiz.DataMenuStats> dataMenuStatsList = Convert.toList(GainDataBiz.DataMenuStats.class, dataMenuList);
            List<GainDataController.GainDataVO> voList = Convert.toList(GainDataController.GainDataVO.class, list2);
            Map<Integer, GainDataBiz.DataMenuStats> dataMenuMap = dataMenuStatsList.parallelStream().collect(Collectors.toMap(DataMenu::getId, Function.identity()));
            for(GainDataController.GainDataVO gainDataVO : voList) {
                if(null != gainDataVO.getMenuId()) {
                    baseBiz.handleDataNum(dataMenuMap, dataMenuMap.get(gainDataVO.getMenuId()));
                }
            }
            List<GainDataBiz.DataMenuStats> dataMenuStats =  CollUtil.newArrayList(dataMenuMap.values());

            SupplierStatistics supplierStatistics = new SupplierStatistics();
            supplierStatistics.setSupplierName(supplierName);
            supplierStatistics.setNum(map.get(supplierName));
            supplierStatistics.setDatas(dataMenuBiz.getImageMenuStatsTree(dataMenuStats, AdminCommonConstant.ROOT));
            returnList.add(supplierStatistics);
        }
    }

    @Data
    public static class SupplierStatistics {
        private String supplierName;
        private Long num;
        private List<DataMenuTree> datas;
    }

    @ApiModelProperty("统计-目录")
    @IgnoreUserToken
    @RequestMapping(value = "/app/unauth/statistics/menu",method = RequestMethod.GET)
    public ObjectRestResponse statisticsMenu(GainDataAdminDTO dto) {
        Example example = baseBiz.initExample(dto);

        List<GainData> list = baseBiz.selectByExample(example);
        List<DataMenu> dataMenuList = dataMenuBiz.selectListAll();
        List<GainDataBiz.DataMenuStats> dataMenuStatsList = Convert.toList(GainDataBiz.DataMenuStats.class, dataMenuList);
        List<GainDataController.GainDataVO> voList = Convert.toList(GainDataController.GainDataVO.class, list);
        Map<Integer, GainDataBiz.DataMenuStats> dataMenuMap = dataMenuStatsList.parallelStream().collect(Collectors.toMap(DataMenu::getId, Function.identity()));
        for(GainDataController.GainDataVO gainDataVO : voList) {
            if(null != gainDataVO.getMenuId()) {
                baseBiz.handleDataNum(dataMenuMap, dataMenuMap.get(gainDataVO.getMenuId()));
            }
        }
        List<GainDataBiz.DataMenuStats> dataMenuStats =  CollUtil.newArrayList(dataMenuMap.values());

        return ObjectRestResponse.succ(dataMenuBiz.getImageMenuStatsTree(dataMenuStats, AdminCommonConstant.ROOT));
    }

    @Data
    static class GainDataAdminDTO extends GainDataDTO {
        public static final int STATISTICSTYPE_SUPPLIER = 1;
        public static final int STATISTICSTYPE_TOPMENU = 2;
        private Integer statisticsType;
    }


    @GetMapping("getPageListExport")
    public void pageLogicExport(GainDataDTO gainDataDTO) throws Exception{
        gainDataDTO.setNeedLog(true);
        gainDataDTO.setNeedFile(true);
        try {
            export(GainDataHead.class, () -> {
                List<GainDataVO> datas = baseBiz.selectNoPageVO(gainDataDTO);

                List<Object> list = CollUtil.newArrayList();
                Map<Integer, DataMenu> dataMenuMap = CollUtil.newHashMap();
                for(int i = 0; i < datas.size(); i++) {
                    //OrderNo Name IdCard
                    GainDataVO vo = datas.get(i);
                    GainDataHead head1 = new GainDataHead();

                    DataMenu dataMenu = getDataMenu(dataMenuMap, vo.getMenuId());

                    if(dataMenu == null) {
                        continue;
                    }else if(dataMenu.getParentId() != AdminCommonConstant.ROOT)  {
                        head1.setSecondMenuName(dataMenu.getTitle());
                        DataMenu pDataMenu = getDataMenu(dataMenuMap, vo.getMenuId());
                        head1.setFirstMenuName(pDataMenu.getTitle());
                    }else {
                        head1.setFirstMenuName(dataMenu.getTitle());
                        head1.setSecondMenuName("默认");
                    }
                    head1.setName(vo.getName());
                    head1.setSupplier(vo.getSupplier());
                    head1.setOpNum(vo.getGaindataLogs().size()+ "");
                    head1.setFileNum(vo.getGaindataFiles().size()+ "");
//                    head1.setAppUserMobile(vo.getAppUserMobile());
//                    head1.setAppUserNickname(vo.getAppUserNickname());
//                    head1.setAppUserRealName(vo.getAppUserRealName());
//                    head1.setIdcard(vo.getIdcard());
//                    head1.setBeforePositionName(vo.getBeforePositionName());
//                    head1.setPositionName(vo.getPositionName());
//                    head1.setRemark(vo.getRemark());
//                    if(StrUtil.isBlank(head1.getBeforePositionName())) {
//                        head1.setBeforePositionName("普通用户");
//                    }
//                    if(StrUtil.isBlank(head1.getPositionName())) {
//                        head1.setPositionName("普通用户");
//                    }
//                    switch (vo.getStatus()) {
//                        case AgentForm.STATUS_TOBE :
//                            head1.setStatus("未处理");
//                            break;
//                        case AgentForm.STATUS_ING :
//                            head1.setStatus("已处理");
//                            break;
//                        case AgentForm.STATUS_REFUSE :
//                            head1.setStatus("拒绝");
//                            break;
//                    }
                    head1.setCrtTime(DateUtil.date(vo.getCrtTime()).toString());
                    list.add(head1);
                }
                return list;
            },"报表导出");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    private DataMenu getDataMenu(Map<Integer, DataMenu> dataMenuMap, Integer menuId) {
        DataMenu dataMenu = dataMenuMap.get(menuId);
        if(dataMenu == null) {
            dataMenu = dataMenuBiz.selectById(menuId);
            dataMenuMap.put(menuId, dataMenu);
        }
        return dataMenu;
    }

    @Data
    public static class GainDataHead {
        @HeadName("项目名称")
        private String firstMenuName;
        @HeadName("项目分类")
        private String secondMenuName;
        @HeadName("名称")
        private String name;

        @HeadName("供应商")
        private String supplier;

        @HeadName("文件数")
        private String fileNum;

        @HeadName("操作次数")
        private String opNum;

//        @HeadName("状态")
//        private String status;

        @HeadName("备注")
        private String remark;

        @HeadName("提交时间")
        private String crtTime;
    }
}
