package com.huatek.busi.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Maps;
import com.huatek.busi.common.FileTypeEnum;
import com.huatek.busi.common.SiteConstants;
import com.huatek.busi.common.util.FileUtils;
import com.huatek.busi.dto.SysFileDto;
import com.huatek.busi.entity.*;
import com.huatek.busi.init.SftpInit;
import com.huatek.busi.mapper.SysFileMapper;
import com.huatek.busi.service.*;
import com.huatek.busi.vo.RModelVo;
import com.huatek.busi.vo.SysFileVo;
import com.huatek.busi.where.SysFileSelectVo;
import com.huatek.frame.base.util.Constants;
import com.huatek.torch.frame.tools.ConstantUtil;
import com.huatek.torch.frame.tools.ResultUtil;
import com.huatek.torch.sql.dao.impl.BaseDao;
import com.huatek.torch.util.uuid.Uuid;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Component
@Service(interfaceClass = ISysFileService.class)
@Transactional(rollbackFor = Exception.class)
public class SysFileServiceImpl extends BaseDao<SysFile, String> implements ISysFileService {

    @Resource
    private SysFileMapper sysFileMapper;

    @Resource
    private SftpInit sftpInit;

    @Reference(check = false)
    BusiSiteTreeService busiSiteTreeService;

    @Reference(check = false)
    BusiSiteService busiSiteService;

    @Reference(check = false)
    ILabReportBasisDataService labReportBasisDataService;

    @Reference(check = false)
    ILabReportParamDataService labReportParamDataService;

    @Reference(check = false)
    ILabReportMarkStatisticService labReportMarkStatisticService;

    @Reference(check = false)
    IGlobalSettingItemService globalSettingItemService;

    @Reference(check = false)
    IRMasterDataService rMasterDataService;

    @Reference(check = false)
    IRMasterDataRecordService rMasterDataRecordService;

    @Override
    public Map<String, Object> list(SysFileSelectVo sysFileSelectVo){
        PageHelper.startPage(sysFileSelectVo.getPage(), sysFileSelectVo.getLimit());
        sysFileSelectVo.setFileType(FileTypeEnum.R_TEMPLATE.getKey());
        sysFileSelectVo.setDeleted(Constants.DEFAULT_NO);

        Page<SysFileDto> page = null;
        String equType = sysFileSelectVo.getEquType();
        if(Objects.equals(equType, SiteConstants.ExternalTypeEnum.GIS.getValue()) || Objects.equals(equType, SiteConstants.ExternalTypeEnum.BYQ.getValue())) {
            page = sysFileMapper.list1(sysFileSelectVo);
        } else if(Objects.equals(equType, SiteConstants.ExternalTypeEnum.CW.getValue())){
            page = sysFileMapper.listKgg(sysFileSelectVo);
        } else if(Objects.equals(equType, SiteConstants.ExternalTypeEnum.BLQ.getValue())){
            page = sysFileMapper.listBlq(sysFileSelectVo);
        } else if(Objects.equals(equType, SiteConstants.ExternalTypeEnum.GEN.getValue())){
            page = sysFileMapper.listGen(sysFileSelectVo);
        } else if(Objects.equals(equType, SiteConstants.ExternalTypeEnum.DL.getValue())){
            page = sysFileMapper.listDl(sysFileSelectVo);
        }
        return ResultUtil.put(ConstantUtil.REQUEST_SUCCESS, page.getTotal(), "BUSINESS.QUERY.SUCCESS", page.getResult());
    }

    @Override
    public void saveOrUpdate(SysFileVo sysFileVo){
        SysFile sysFile = new SysFile();
        sysFileVo.setId(Uuid.getUUID());
        sysFileVo.setCreateDate(LocalDateTime.now());
        sysFileVo.setDeleted(Constants.DEFAULT_NO);
        BeanUtils.copyProperties(sysFileVo, sysFile);
        this.add(sysFile);
    }

    @Override
    public List<SysFileDto> update(String businessId, String equType){
        sysFileMapper.update(businessId, equType);
        return sysFileMapper.findByDeleted(businessId, equType);
    }

    @Override
    public Map<String, Object> findListAnnex(SysFileSelectVo sysFileSelectVo){
        sysFileSelectVo.setFileType(FileTypeEnum.ANNEX.getKey());
        List<SysFileDto> list = sysFileMapper.findListAnnex(sysFileSelectVo);
        return ResultUtil.put(ConstantUtil.REQUEST_SUCCESS, "BUSINESS.QUERY.SUCCESS", list);
    }

    @Override
    public int updateByRefIdsAndEquType(List<String> refIds, String eqType){
        return sysFileMapper.updateByRefIdsAndEquType(refIds, eqType);
    }

    @Override
    public int updateByRefIdsAndEquTypes(String eqType, String refId){
        return sysFileMapper.updateByRefIdsAndEquTypes(eqType, refId);
    }

    @Override
    @Transactional(propagation= Propagation.SUPPORTS)
    public Map<String, Object> deleteFiles(List<String> refIds, String equType){
        // 去除重复元素
        refIds = refIds.stream().distinct().collect(Collectors.toList());
        // 删除离线报告主表数据
        rMasterDataService.updateByRefIdsAndEquType(refIds, equType);
        // 删除离线报告基础数据
        labReportBasisDataService.updateByRefIds(refIds, equType);
        // 删除离线报告参数
        labReportParamDataService.updateByRefIds(refIds, equType);
        // 删除离线报告打标参数
        labReportMarkStatisticService.updateByRefIds(refIds , equType);
        // 删除附件表数据
        updateByRefIdsAndEquType(refIds, equType);
        // 删除临时表数据
        rMasterDataRecordService.deleteBatch(refIds , equType);

        GlobalSettingItem globalSettingItem = globalSettingItemService.findOne();
        String localTempPath = globalSettingItem.getLocalTempPath();

        List<SysFileDto> sysFileDtoList = sysFileMapper.findAllByDeleted(refIds, equType);
        if(CollectionUtil.isNotEmpty(sysFileDtoList)){
            for (SysFileDto item :sysFileDtoList){
                String id = item.getId();
                String filePath = item.getFilePath();
                String fileName = item.getFileName();
                String suffixFilePath = item.getSuffixFilePath();

                if(StrUtil.isNotEmpty(filePath) && StrUtil.isNotEmpty(fileName) && StrUtil.isNotEmpty(suffixFilePath)){
                    // 远程下载文件至本地
                    String returnCode = sftpInit.download(filePath, fileName, localTempPath, fileName);
                    if(Objects.equals(returnCode, "1")){
                        return ResultUtil.put(ConstantUtil.REQUEST_FAIL, "BUSINESS.NOT.FIND.FILEPATH", "");
                    }
                    // 远程删除文件
                    sftpInit.delete("/" + filePath + "/", fileName);
                    // 本地文件上传远程服务器上
                    filePath = sftpInit.upload(suffixFilePath, localTempPath, File.separator + fileName, "delete");
                    sysFileMapper.updateFilePathById(id, filePath);
                    // 删除本地临时文件
                    FileUtils.deleteFile(localTempPath.replace("/", "\\") + "\\" + fileName);
                }
            }
            return ResultUtil.put(ConstantUtil.REQUEST_SUCCESS, "BUSINESS.DELETE.SUCCESS", "");
        }
        return ResultUtil.put(ConstantUtil.REQUEST_FAIL, "BUSINESS.DELETE.FAIL", "");
    }

    @Override
    public Integer findMaxCount(String eqType, String date, String fileType){
        return sysFileMapper.findMaxCount(eqType, date, fileType);
    }

    @Override
    public Map<String, Object> downloadFiles(String id){
        try{
            GlobalSettingItem globalSettingItem = globalSettingItemService.findOne();
            if(globalSettingItem != null){
                String localTempPath = globalSettingItem.getLocalTempPath();

                // 查询文件信息
                SysFileDto sysFileDto = sysFileMapper.findById(id);
                String filePath = sysFileDto.getFilePath();
                String remoteFile = sysFileDto.getFileName();

                // 下载本地文件夹
                String returnCode = sftpInit.download(filePath, remoteFile, localTempPath, remoteFile);
                if(Objects.equals(returnCode, "0")){
                    Map<String, Object> map = Maps.newHashMap();
                    map.put("filePath", localTempPath + File.separator + remoteFile);
                    map.put("fileName", remoteFile);
                    return map;
                }
                return ResultUtil.put(ConstantUtil.REQUEST_FAIL, "BUSINESS.NOT.FIND.FILEPATH", "");
            }
        }catch (Exception e){
            log.error("文件下载异常：{}", e.getMessage());
            return ResultUtil.put(ConstantUtil.REQUEST_FAIL, "BUSINESS.DOWNLOAD.FAIL", "");
        }
        return ResultUtil.put(ConstantUtil.REQUEST_FAIL, "BUSINESS.DOWNLOAD.FAIL", "");
    }

    @Override
    public File downloadExcel(String path, String equType, String pathName) {
        try {
            String basePath = this.getClass().getResource(path).getPath();
            InputStream inputStream = new FileInputStream(new File(basePath));
            Workbook workbook = WorkbookFactory.create(inputStream);
            if(workbook != null){
                int numberOfSheets = workbook.getNumberOfSheets();
                if(numberOfSheets > 0){
                    for (int i = 1; i < numberOfSheets; i++){
                        Sheet sheet = workbook.getSheetAt(i);
                        if(sheet != null){
                            // 获取第一行
                            Row row = sheet.getRow(0);
                            // 变电名称
                            BusiSiteTree busiSiteTree = busiSiteTreeService.findByEquType(equType);
                            if(row.getCell(3) == null){
                                row.createCell(3).setCellValue(busiSiteTree.getName());
                            }else {
                                row.getCell(3).setCellValue(busiSiteTree.getName());
                            }

                            // 站名编号
                            String siteId = busiSiteTree.getSiteId();
                            BusiSite busiSite = busiSiteService.findBusiSite(siteId);
                            if(busiSite != null){
                                if(row.getCell(1) == null){
                                    row.createCell(1).setCellValue(busiSite.getSiteName());
                                }else {
                                    row.getCell(1).setCellValue(busiSite.getSiteName());
                                }
                            }

                            // 设备编号
                            if(row.getCell(7) == null){
                                row.createCell(7).setCellValue(busiSiteTree.getSystemCode());
                            }else {
                                row.getCell(7).setCellValue(busiSiteTree.getSystemCode());
                            }

                            // 设备小类
//                            Set<String> hashSet = new HashSet();
//                            List<BusiSiteTree> busiSiteTreeList = busiSiteTreeService.findByParentId(busiSiteTree.getId());
                            if(Objects.equals(equType, "1")){
                                if(row.getCell(5) == null){
                                    row.createCell(5).setCellValue(sheet.getSheetName());
                                }else {
                                    row.getCell(5).setCellValue(sheet.getSheetName());
                                }
                            }else if(Objects.equals(equType, "2")){
//                                if(CollectionUtil.isEmpty(busiSiteTreeList)){
//                                    return ResultUtil.put(ConstantUtil.REQUEST_FAIL, "BUSINESS.FILE.DOWNLOAD.FAIL", "");
//                                }
//                                Set<String> set = new HashSet();
//                                for(BusiSiteTree busiSiteTree1 :busiSiteTreeList){
//                                    hashSet.add(busiSiteTree1.getId());
//                                    set.add(busiSiteTree1.getId() + "-" + busiSiteTree1.getName());
//                                }
//
//                                String allName = "";
//                                for (String s :set){
//                                    allName += s + ",";
//                                }
//                                allName = allName.substring(0, allName.length() -1);
//                                ImportExcel.createBox(sheet, 0, 0, 5, 5, allName.split(","));
                            }

                            // 设备名称
//                            if(Objects.equals(equType, "1")){
//                                Set<String> set = new HashSet();
//                                for(BusiSiteTree busiSiteTree1 :busiSiteTreeList){
//                                    set.add(busiSiteTree1.getId() + "-" + busiSiteTree1.getName());
//                                }
//
//                                String allName = "";
//                                for (String s :set){
//                                    allName += s + ",";
//                                }
//                                allName = allName.substring(0, allName.length() -1);
//                                ImportExcel.createBox(sheet, 0, 0, 9, 9, allName.split(","));
//                            }else if(Objects.equals(equType, "2")){
//                                Set<String> set = new HashSet<>();
//                                List<String> list = new ArrayList<>(hashSet);
//                                List<BusiSiteTree> busiSiteTreeAll = busiSiteTreeService.findByParentIds(list);
//                                if(CollectionUtil.isEmpty(busiSiteTreeAll)){
//                                    return ResultUtil.put(ConstantUtil.REQUEST_FAIL, "BUSINESS.FILE.DOWNLOAD.FAIL", "");
//                                }
//                                for (BusiSiteTree busiSiteTree1 :busiSiteTreeAll){
//                                    set.add(busiSiteTree1.getId() + "-" + busiSiteTree1.getName());
//                                }
//
//                                String allName = "";
//                                for (String s :set){
//                                    allName += s + ",";
//                                }
//                                allName = allName.substring(0, allName.length() -1);
//                                ImportExcel.createBox(sheet, 0, 0, 9, 9, allName.split(","));
//                            }
                        }
                    }

                    // 获取服务器临时文件夹路径
                    GlobalSettingItem globalSettingItem = globalSettingItemService.findOne();
                    if(globalSettingItem == null && StrUtil.isNotEmpty(globalSettingItem.getLocalTempPath())){
                        return null;
                    }
                    String localPath = globalSettingItem.getLocalTempPath() + File.separator + pathName;
                    log.info("<<<<<<<<<<<<<<<<获取本地路径>>>>>>>>>>>>>>>>>>>>>>>>>:{}", localPath);
                    return FileUtils.createExcel(workbook, localPath);
                }
            }
        }catch (Exception e){
            log.error("离线报告模板下载异常：{}", e.getMessage());
        }
        return null;
    }

    @Override
    public Map<String, Object> findFileList(String busId){
        List<SysFileDto> sysFileDto = sysFileMapper.findByBusId(busId);
        return ResultUtil.put(ConstantUtil.REQUEST_SUCCESS, "BUSINESS.QUERY.SUCCESS", sysFileDto);
    }
}
