package com.liquidnet.service.platform.service.impl.goblin;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.goblin.dto.MallOrdertDao;
import com.liquidnet.service.goblin.mapper.GoblinStoreOrderMapper;
import com.liquidnet.service.goblin.service.IGoblinExportService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;

@Service
@Slf4j
public class GoblinExportServiceImpl implements IGoblinExportService {

    @Autowired
    GoblinStoreOrderMapper goblinStoreOrderMapper;

    @Override
    public ResponseDto<String> exportMallOrder(HttpServletResponse response, String beginTime, String endTime, String state, Integer mailType, String storeId) {
        if (!timeIsNotNull(beginTime, endTime)) {
            return ResponseDto.failure("起始和结束时间不能为空！");
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date beginDate = sdf.parse(beginTime);
            Date endDate = sdf.parse(endTime);
            List<String> states = null;
            if (StringUtils.isNotBlank(state)) {
                states = Arrays.asList(state.split(","));
            }
            List<MallOrdertDao> voList = goblinStoreOrderMapper.exportMallOrder(beginDate, endDate, states, mailType, storeId);
            Map<String, List<String>> map = CollectionUtil.mapStringList();
            int max = 0;
            //将数据保存到list中
            if (voList != null && voList.size() > 0) {
                for (MallOrdertDao te : voList) {
                    String orderCode = te.getOrderCode();
                    if (map.get(orderCode) == null) {
                        List<String> list = new ArrayList<>();
                        list.add(te.getOrderId());
                        list.add(te.getOrderCode());
                        list.add(te.getUserMobile());
                        list.add(te.getPriceExpress());
                        list.add(te.getPriceCoupon());
                        list.add(te.getStorePriceCoupon());
                        list.add(te.getExpressContacts());
                        list.add(te.getExpressPhone());
                        list.add(te.getExpressDetailAddress());
                        list.add(te.getPayType());
                        list.add(te.getPayTime());
                        list.add(te.getCreatedAt());
                        list.add(te.getLogisticsCompany());
                        list.add(te.getMailNo());
                        list.add(te.getSpuId());
                        list.add(te.getName());
                        list.add(te.getCate1Name());
                        list.add(te.getCate2Name());
                        list.add(te.getSkuName());
                        list.add(te.getNum());
                        list.add(te.getSkuPrice());
                        list.add(te.getSkuPriceActual());
                        list.add(te.getOrderSkuId());
                        max = Math.max(max, list.size());
                        map.put(orderCode, list);
                        continue;
                    }
                    if (map.get(orderCode) != null) {
                        List<String> list = map.get(orderCode);
                        list.add(te.getSpuId());
                        list.add(te.getName());
                        list.add(te.getCate1Name());
                        list.add(te.getCate2Name());
                        list.add(te.getSkuName());
                        list.add(te.getNum());
                        list.add(te.getSkuPrice());
                        list.add(te.getSkuPriceActual());
                        list.add(te.getOrderSkuId());
                        max = Math.max(max, list.size());
                        map.put(orderCode, list);
                    }
                }
                List<String> cells = new ArrayList<>();
                cells.add("订单id");
                cells.add("订单编号");
                cells.add("购买人手机号");
                cells.add("快递费");
                cells.add("平台券优惠券金额");
                cells.add("店铺券优惠金额");
                cells.add("收货人");
                cells.add("收货人电话");
                cells.add("快递地址");
                cells.add("支付方式");
                cells.add("支付时间");
                cells.add("下单时间");
                cells.add("快递公司");
                cells.add("物流单号");
                int j = (max - 14) / 9;
                for (int i = 1; i <= j; i++) {
                    cells.add("商品id" + i);
                    cells.add("商品名" + i);
                    cells.add("一级分类" + i);
                    cells.add("二级分类" + i);
                    cells.add("款式" + i);
                    cells.add("数量" + i);
                    cells.add("单价" + i);
                    cells.add("价格" + i);
                    cells.add("订单skuId" + i);
                }
                String[] header = cells.toArray(new String[cells.size()]);

                List<Object> objectList = new ArrayList<>();
                map.entrySet().stream().forEach(ms -> {
                    objectList.add(ms.getValue());
                });
                String fileName = "商城订单信息";
                // 标题样式
                WriteCellStyle headWriteCellStyle = getHeadStyle();
                // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
                HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                        new HorizontalCellStyleStrategy(headWriteCellStyle, new WriteCellStyle());
                EasyExcel.write(getOutputStream(fileName, response))
                        //设置默认样式及写入头信息开始的行数
//                .useDefaultStyle(true).relativeHeadRowIndex(0)
                        // 表头、内容样式设置
                        .registerWriteHandler(horizontalCellStyleStrategy)
                        // 统一列宽,如需设置自动列宽则new LongestMatchColumnWidthStyleStrategy()
                        .registerWriteHandler(new SimpleColumnWidthStyleStrategy(25))
                        .sheet(fileName)
                        // 这里放入动态头
                        .head(head(header))
                        // 当然这里数据也可以用 List<List<String>> 去传入
                        .doWrite(objectList);
            }else{
                return ResponseDto.failure("无数据");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("导出Excel失败，请联系网站管理员！");
        }
        return ResponseDto.success();
    }

    private boolean timeIsNotNull(String beginTime, String endTime) {
        return StringUtils.isNotBlank(beginTime) && StringUtils.isNotBlank(endTime) ? true : false;
    }

    /*动态头传入*/
    private static List<List<String>> head(String[] header) {
        List<String> head0 = null;
        List<List<String>> list = new LinkedList<List<String>>();
        for (String h : header) {
            head0 = new LinkedList<>();
//                head0.add(bigTitle);
            head0.add(h);
            list.add(head0);
        }
        return list;
    }

    private static WriteCellStyle getHeadStyle() {
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景颜色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        headWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        // 字体
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontName("黑体");//设置字体名字
        headWriteFont.setFontHeightInPoints((short) 15);//设置字体大小
        headWriteFont.setBold(true);//字体加粗
        headWriteCellStyle.setWriteFont(headWriteFont); //在样式用应用设置的字体;
        // 样式
        headWriteCellStyle.setBorderBottom(BorderStyle.THIN);//设置底边框;
        headWriteCellStyle.setBottomBorderColor((short) 0);//设置底边框颜色;
        headWriteCellStyle.setBorderLeft(BorderStyle.THIN);  //设置左边框;
        headWriteCellStyle.setLeftBorderColor((short) 0);//设置左边框颜色;
        headWriteCellStyle.setBorderRight(BorderStyle.THIN);//设置右边框;
        headWriteCellStyle.setRightBorderColor((short) 0);//设置右边框颜色;
        headWriteCellStyle.setBorderTop(BorderStyle.THIN);//设置顶边框;
        headWriteCellStyle.setTopBorderColor((short) 0); //设置顶边框颜色;
        headWriteCellStyle.setWrapped(true);  //设置自动换行;
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);//设置水平对齐的样式为居中对齐;
        headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);  //设置垂直对齐的样式为居中对齐;
        //        headWriteCellStyle.setShrinkToFit(true);//设置文本收缩至合适
        return headWriteCellStyle;
    }

    private static OutputStream getOutputStream(String fileName, HttpServletResponse response) throws Exception {
        fileName = URLEncoder.encode(fileName, "UTF-8");
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + "-" + LocalDate.now() + ".xlsx");
        return response.getOutputStream();
    }
}
