package com.zfire.mall.manager.logic.comlist;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zfire.mall.manager.bean.admin.AdminUserCom;
import com.zfire.mall.manager.bean.listV2.ComListVO;
import com.zfire.mall.manager.commonmapper.listV2.CommonCMapper;
import com.zfire.mall.manager.constant.Constant;
import com.zfire.mall.manager.exception.RemoteServiceException;
import com.zfire.mall.manager.logic.common.CommonLogic;
import com.zfire.mall.manager.plus.entity.ComDetail;
import com.zfire.mall.manager.plus.entity.ComDetailLog;
import com.zfire.mall.manager.plus.entity.ComList;
import com.zfire.mall.manager.plus.service.ComDetailLogService;
import com.zfire.mall.manager.plus.service.ComDetailService;
import com.zfire.mall.manager.plus.service.ComListService;
import com.zfire.mall.manager.utils.CommonUtils;
import com.zfire.mall.manager.utils.excel.ExcelUtils;
import com.zfire.mall.manager.utils.oss.OSSUtil;
import com.zfire.mall.manager.zfire.bean.ZfireParamBean;
import com.zfire.mall.manager.zfire.util.FieldUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ComListLogic {


    //static ExecutorService executorService = Executors.newFixedThreadPool(8);

    @Autowired
    CommonLogic commonLogic;
    @Autowired
    OSSUtil ossUtil;
    @Autowired
    CommonCMapper commonCMapper;
    @Autowired
    ComDetailService comDetailService;
    @Autowired
    ComListService comListService;
    @Autowired
    ComDetailLogService comDetailLogService;


    public IPage<ComListVO> listV2(ZfireParamBean zfireParamBean){
        zfireParamBean = FieldUtils.supplyParam(zfireParamBean);
        return commonCMapper.queryComList(new Page(zfireParamBean.getPageNum(),zfireParamBean.getPageSize()),zfireParamBean);
    }



    public IPage<ComList> list(String title, String remark, Boolean needDown,Integer pageNo, Integer pageSize){
        AdminUserCom adminUser = commonLogic.getAdminUser();
        List<Integer> notIncomListIds = new ArrayList<>();
        if(needDown != null && needDown) {
            List<ComDetailLog> logs = comDetailLogService.lambdaQuery().eq(ComDetailLog::getAdminUserId, adminUser.getAdminUserId()).list();
            notIncomListIds = logs.stream().map(ComDetailLog::getComListId).distinct().collect(Collectors.toList());
        }
        IPage<ComList> page = comListService.lambdaQuery()
                .in(CollectionUtils.isNotEmpty(adminUser.getAdminCompanyIds()),ComList::getAdminCompanyId,adminUser.getAdminCompanyIds())
                .eq(needDown != null && needDown && CollectionUtils.isNotEmpty(notIncomListIds),ComList::getId,notIncomListIds)
                .in(needDown != null && needDown,ComList::getAdminUserId,adminUser.getAdminUserId())
                .like(StringUtils.isNotEmpty(title), ComList::getTitle, title)
                .like(StringUtils.isNotEmpty(remark),ComList::getRemark,remark)
                .orderByDesc(ComList::getCreateTime)
                .page(new Page<>(pageNo, pageSize));
        return page;
    }


    public void delete(Integer id,HttpServletRequest request){
        AdminUserCom admin = commonLogic.getAdminUser();
        if(!admin.getIsMaster()){
            throw new RemoteServiceException("非主账号不可删除");
        }
        comListService.removeById(id);
    }


    public void yonge(String title,String remark, String file, HttpServletRequest request) throws RemoteServiceException, IOException {

        AdminUserCom admin = commonLogic.getAdminUser(request);
        //新增主表
        ComList comList = new ComList();
        comList.setAdminCompanyId(admin.getLoginCompanyId());
        comList.setTitle(title);
        comList.setRemark(remark);
        comList.setFileName(title);
        comList.setOperatorUserName(admin.getUserName());
        comList.setOperatorNickName(admin.getNickName());
        comList.setCreateTime(new Date());
        comList.insert();
        //上传主文件到oss,并记录
        //CommonFile commonFile = commonLogic.uploadFile(file);

        //新增拆分的附件明细表
        ComDetail bean = new ComDetail();
        bean.setAdminCompanyId(admin.getLoginCompanyId());
        bean.setTitle(title);
        bean.setComListId(comList.getId());
        bean.setFileName(title);
        bean.setAdminUserId(admin.getAdminUserId());
        bean.setCustomerNumber("");
        bean.setFileUrl(file);
        bean.setCreateTime(new Date());
        bean.insert();

        String url = ossUtil.getUrl(file);
        InputStream inputStream = commonLogic.getFileInputStreamByUrl(url);
        List<Object> objects = ExcelUtils.importExcel(inputStream);
        //拆分excel并上传oss
        List<Map<String,Object>> fileUrls = this.createExcel(objects);
        if(fileUrls == null){
            throw new RemoteServiceException("拆分失败");
        }
        for(Map<String,Object> fileUrl : fileUrls){
            String websitNumber = (String)fileUrl.get("websitNumber");
            String filePath = (String)fileUrl.get("filePath");
            //新增拆分的附件明细表
            ComDetail comDetail = new ComDetail();
            comDetail.setAdminCompanyId(admin.getLoginCompanyId());
            comDetail.setTitle(title);
            comDetail.setComListId(comList.getId());
            comDetail.setFileName(title);
            comDetail.setAdminUserId(websitNumber);
            comDetail.setCustomerNumber(websitNumber);
            comDetail.setFileUrl(filePath);
            comDetail.setCreateTime(new Date());
            comDetail.insert();
        }

    }

    public String download(Integer id,HttpServletRequest request,HttpServletResponse response) throws IOException {
        AdminUserCom admin = commonLogic.getAdminUser(request);

        ComDetail comDetail = comDetailService.lambdaQuery()
                .eq(ComDetail::getComListId, id)
                .eq(ComDetail::getCustomerNumber, admin.getCustomerNumber()).one();

        if(comDetail == null){
            throw new RemoteServiceException("暂无您可下载的内容");
        }

        ComDetailLog comDetailLog = new ComDetailLog();
        comDetailLog.setCreateTime(new Date());
        comDetailLog.setComListId(id);
        comDetailLog.setTitle(comDetail.getTitle());
        comDetailLog.setAdminUserId(admin.getAdminUserId());
        comDetailLog.setAdminNickName(admin.getNickName());
        comDetailLog.insert();

        String fileUrl = comDetail.getFileUrl();
        //String imgFile = ossUtil.getUrlWw(fileUrl);
        //CommonUtils.downloadFile(imgFile,admin.getWebsitNumber()+"-"+comDetail.getTitle()+".csv",response);
        return fileUrl;
    }


    public IPage<ComDetailLog> logList(Integer id,Integer pageNo,Integer pageSize,HttpServletRequest request){
        IPage<ComDetailLog> page = comDetailLogService.lambdaQuery()
                .eq(ComDetailLog::getComListId, id)
                .orderByDesc(ComDetailLog::getCreateTime)
                .page(new Page<>(pageNo, pageSize));
        return page;
    }


    /**
     * 创建Excel
     */
    public List<Map<String,Object>> createExcel(List<Object> datas) {
        try {
           // List<Object> datas = ExcelUtils.importExcel(file);
            List<Object> tableHeaders =(List<Object>)datas.get(0);

            Map<String,List<List<Object>>> map = new HashMap<>();
            log.info("【中心下发文件1】"+ DateUtil.formatDate(new Date()));
            for(int i=1 ;i<datas.size(); i++){
                List<Object> row = (List<Object>) datas.get(i);
                CommonUtils.initList2(row,row.size()+1);
                //网点编号
                String websitNumber = (String) row.get(0);

                List<List<Object>> objects = map.get(websitNumber);
                if(objects == null){
                    objects = new ArrayList<>();
                }
                //row.remove(0);
                objects.add(row);

                if(!map.containsKey(websitNumber)){
                    map.put(websitNumber,objects);
                }
            }
            log.info("【中心下发文件2】"+ DateUtil.formatDate(new Date()));
            List<Map<String,Object>> fileUrls = new ArrayList<>();
            for(String websitNumber : map.keySet()){
                //String filePath = "B:/"+email+"-"+file.getName()+".xlsx";
                long currentTime = System.currentTimeMillis();
                String filePath = Constant.Ali.OSS_TYPE_PIC + websitNumber + currentTime + ".csv";
//                executorService.submit( ()->{
//                    try {
                        this.write(filePath,tableHeaders,map.get(websitNumber));
//                    } catch (IOException e) {
//                        log.error("上传文件失败");
//                    }
//                });
                Map<String,Object> mp = new HashMap<>();
                mp.put("websitNumber",websitNumber);
                mp.put("filePath",filePath);
                fileUrls.add(mp);
            }
            log.info("【中心下发文件3】"+ DateUtil.formatDate(new Date()));
            return fileUrls;
        } catch (Exception e) {
            log.error("【创建excel失败】",e);
        }
        return null;
    }


    /**
     * 生成Excel文件的方法write
     */
    public void write(String fileName, List<Object> tableHeaders,List<List<Object>> rows) throws IOException {
        // 初始一个workbook
        XSSFWorkbook workbook = new XSSFWorkbook();
        // 创建单个sheet
        XSSFSheet sheet = workbook.createSheet("sheet1");
        // 创建第一行，设置列名
        XSSFRow row0 = sheet.createRow(0);
        row0.setHeight((short) 400);             // 设置行高         // Excel的列
        XSSFFont font = workbook.createFont();// 设置字体
        font.setColor(HSSFFont.COLOR_NORMAL);           // 设置单元格字体的颜色
        XSSFCellStyle style = workbook.createCellStyle();// 样式
        // 设置边框颜色
        style.setTopBorderColor(IndexedColors.BLACK.getIndex());
        style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
        style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
        style.setRightBorderColor(IndexedColors.BLACK.getIndex());
        // 设置文本格式
        XSSFDataFormat format = workbook.createDataFormat();
        style.setDataFormat(format.getFormat("@"));

        short cellNumber = (short) tableHeaders.size();  // 表的列数
        for (int k = 0; k < cellNumber; k++) {
            short b = 5000;
            XSSFCell cell = row0.createCell(k);          // 创建第0行第k列
            cell.setCellValue((String)tableHeaders.get(k));  // 设置第0行第k列的值
            sheet.setColumnWidth(k, b);         // 设置列的宽度
            style.setFont(font);                // 设置字体风格
            cell.setCellStyle(style);
        }

        XSSFCellStyle styleContext = workbook.createCellStyle();
        styleContext.setWrapText(true);
        // 设置边框颜色
        styleContext.setTopBorderColor(IndexedColors.BLACK.getIndex());
        styleContext.setBottomBorderColor(IndexedColors.BLACK.getIndex());
        styleContext.setLeftBorderColor(IndexedColors.BLACK.getIndex());
        styleContext.setRightBorderColor(IndexedColors.BLACK.getIndex());
        // 设置文本格式
        styleContext.setDataFormat(format.getFormat("@"));

        if (rows.size() > 0) {
            // 创建剩余行
            for (int rowIndex = 0; rowIndex < rows.size(); rowIndex++) {
                XSSFRow row = sheet.createRow(rowIndex+1);
                List<Object> values = rows.get(rowIndex);
                // 创建多列
                for (int cellIndex = 0; cellIndex < values.size(); cellIndex++) {
                    XSSFCell cell = row.createCell(cellIndex);
                    cell.setCellStyle(styleContext);               // 设置风格
                    cell.setCellValue((String)values.get(cellIndex));
                }
            }
        }
        ByteArrayOutputStream ba = new ByteArrayOutputStream();
        try {

            workbook.write(ba);
            ByteArrayInputStream bio = new ByteArrayInputStream(ba.toByteArray());
            ossUtil.uploadFile(fileName,bio);

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            ba.flush();
            ba.close();
        }
    }


    /**
     * 设备条码生成Excel文件的方法write
     */
    public void writeExcel(String fileName, List<Object> tableHeaders,List<List<Object>> rows) throws IOException {
        // 初始一个workbook
        XSSFWorkbook workbook = new XSSFWorkbook();
        // 创建单个sheet
        XSSFSheet sheet = workbook.createSheet("sheet1");
        // 创建第一行，设置列名
        XSSFRow row0 = sheet.createRow(0);
        row0.setHeight((short) 400);             // 设置行高         // Excel的列
        XSSFFont font = workbook.createFont();// 设置字体
        font.setColor(HSSFFont.COLOR_NORMAL);           // 设置单元格字体的颜色
        XSSFCellStyle style = workbook.createCellStyle();// 样式
        // 设置边框颜色
        style.setTopBorderColor(IndexedColors.BLACK.getIndex());
        style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
        style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
        style.setRightBorderColor(IndexedColors.BLACK.getIndex());
        // 设置文本格式
        XSSFDataFormat format = workbook.createDataFormat();
        style.setDataFormat(format.getFormat("@"));

        short cellNumber = (short) tableHeaders.size();  // 表的列数
        for (int k = 0; k < cellNumber; k++) {
            short b = 5000;
            XSSFCell cell = row0.createCell(k);          // 创建第0行第k列
            cell.setCellValue((String)tableHeaders.get(k));  // 设置第0行第k列的值
            sheet.setColumnWidth(k, b);         // 设置列的宽度
            style.setFont(font);                // 设置字体风格
            cell.setCellStyle(style);
        }

        XSSFCellStyle styleContext = workbook.createCellStyle();
        styleContext.setWrapText(true);
        // 设置边框颜色
        styleContext.setTopBorderColor(IndexedColors.BLACK.getIndex());
        styleContext.setBottomBorderColor(IndexedColors.BLACK.getIndex());
        styleContext.setLeftBorderColor(IndexedColors.BLACK.getIndex());
        styleContext.setRightBorderColor(IndexedColors.BLACK.getIndex());
        // 设置文本格式
        styleContext.setDataFormat(format.getFormat("@"));

        if (rows.size() > 0) {
            // 创建剩余行
            for (int rowIndex = 0; rowIndex < rows.size(); rowIndex++) {
                XSSFRow row = sheet.createRow(rowIndex+1);
                List<Object> values = rows.get(rowIndex);
                // 创建多列
                for (int cellIndex = 0; cellIndex < values.size(); cellIndex++) {
                    XSSFCell cell = row.createCell(cellIndex);
                    cell.setCellStyle(styleContext);               // 设置风格
                    cell.setCellValue(values.get(cellIndex).toString());
                }
            }
        }
        ByteArrayOutputStream ba = new ByteArrayOutputStream();
        try {

            workbook.write(ba);
            ByteArrayInputStream bio = new ByteArrayInputStream(ba.toByteArray());
            ossUtil.uploadFile(fileName,bio);

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            ba.flush();
            ba.close();
        }
    }

}
