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

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.liquidnet.commons.lang.util.StringUtil;
import com.liquidnet.service.goblin.dto.vo.GoblinNftExActivityVo;
import com.liquidnet.service.goblin.dto.vo.GoblinNftExCodeVo;
import com.liquidnet.service.goblin.entity.GoblinGoodsSku;
import com.liquidnet.service.goblin.entity.GoblinNftExCode;
import com.liquidnet.service.goblin.entity.GoblinNftExSku;
import com.liquidnet.service.goblin.mapper.GoblinGoodsSkuMapper;
import com.liquidnet.service.goblin.mapper.GoblinNftExCodeMapper;
import com.liquidnet.service.goblin.mapper.GoblinNftExSkuMapper;
import com.liquidnet.service.goblin.param.GoblinNftExCodeParam;
import com.liquidnet.service.goblin.service.IGoblinNftExCodeService;
import com.liquidnet.service.platform.utils.GoblinRedisUtils;
import com.liquidnet.service.platform.utils.ObjectUtil;
import com.sun.org.apache.xpath.internal.operations.Bool;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
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.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: wll
 * @Description:
 * @Date:Create：in 2022/4/20 5:36 下午
 */
@Service
@Slf4j
public class GoblinNftExCodeServiceImpl implements IGoblinNftExCodeService {

    @Autowired
    private GoblinGoodsSkuMapper goblinGoodsSkuMapper;
    @Autowired
    private GoblinNftExCodeMapper goblinNftExCodeMapper;
    @Autowired
    private GoblinNftExSkuMapper goblinNftExSkuMapper;
    @Autowired
    private GoblinRedisUtils goblinRedisUtils;

    @Override
    public PageInfo<GoblinNftExCodeVo> selectCodePageList(GoblinNftExCodeParam goblinNftExCodeParam) {

        // 入参
        GoblinNftExCode goblinNftExCode = GoblinNftExCode.getNew();
        goblinNftExCode.setCode(goblinNftExCodeParam.getCode());
        goblinNftExCode.setActivityId(goblinNftExCodeParam.getActivityId());
        goblinNftExCode.setState(goblinNftExCodeParam.getState());
        goblinNftExCode.setRedeemUid(goblinNftExCodeParam.getUserId());
        goblinNftExCode.setIsDrivi(goblinNftExCodeParam.getIsDrivi());
        if (StringUtil.isNotBlank(goblinNftExCodeParam.getSkuName())) {
            // 根据藏品名称获取 skuIds
            String skuName = goblinNftExCodeParam.getSkuName();
            List<GoblinGoodsSku> goblinGoodsSkus = goblinGoodsSkuMapper.selectSkuLikeName(skuName);
            if (goblinGoodsSkus.size() <= 0) {
                return new PageInfo<>();
            }
            StringBuffer skuIds = new StringBuffer();
            for (GoblinGoodsSku goblinGoodsSku : goblinGoodsSkus) {
                skuIds.append(goblinGoodsSku.getSkuId()).append(",");
            }
            goblinNftExCode.setSkuId(skuIds.deleteCharAt(skuIds.length() - 1).toString());
        }


        PageHelper.startPage(goblinNftExCodeParam.getPageNum(), 20, true);
        List<GoblinNftExCode> goblinNftExCodes = goblinNftExCodeMapper.selectGoblinNftCode(goblinNftExCode);
        StringBuffer skuIds = new StringBuffer();
        StringBuffer acticityIds = new StringBuffer();
        for (GoblinNftExCode gnc : goblinNftExCodes) {
            skuIds.append(gnc.getSkuId()).append(",");
            acticityIds.append(gnc.getActivityId()).append(",");
        }

        // 获取返回对象实例
        ArrayList<GoblinNftExCodeVo> goblinNftExCodeArrayList = ObjectUtil.getGoblinNftExCodeArrayList();


        if (StringUtil.isNotBlank(skuIds)) {
            // 批量查询
            List<GoblinGoodsSku> goblinGoodsSkus = goblinGoodsSkuMapper.selectBySkuIds(skuIds.toString());
            for (GoblinNftExCode gnc : goblinNftExCodes) {
                for (GoblinGoodsSku goblinGoodsSku : goblinGoodsSkus) {
                    if (gnc.getSkuId().equals(goblinGoodsSku.getSkuId())) {
                        GoblinNftExCodeVo goblinNftExCodeVo = GoblinNftExCodeVo.getNew().copy(gnc);
                        goblinNftExCodeVo.setSkuName(goblinGoodsSku.getName());
                        goblinNftExCodeArrayList.add(goblinNftExCodeVo);
                        break;
                    }
                }
            }
        }


        // 根据活动ids 获取兑换活动和sku的关联
        List<GoblinNftExSku> goblinNftExSkus = goblinNftExSkuMapper.selectGoblinNftExSkuByActivityIds(acticityIds.toString());

        Map<String, List<GoblinNftExSku>> map = new HashMap<>();
        for (GoblinNftExSku goblinNftExSku : goblinNftExSkus) {
            if (map.get(goblinNftExSku.getActivityId()) == null) {
                map.put(goblinNftExSku.getActivityId(), new ArrayList<>());
            }
            map.get(goblinNftExSku.getActivityId()).add(goblinNftExSku);
        }


        for (GoblinNftExCodeVo gnc : goblinNftExCodeArrayList) {
            List<GoblinNftExSku> goblinNftExSkuList = map.get(gnc.getActivityId());
            for (GoblinNftExSku goblinNftExSku : goblinNftExSkuList) {
                if (gnc.getSkuId().equals(goblinNftExSku.getSkuId())) {
                    gnc.setExStartTime(goblinNftExSku.getExStartTime());
                    gnc.setExStopTime(goblinNftExSku.getExStopTime());
                    break;
                }
            }
        }


        PageInfo<GoblinNftExCodeVo> pageInfo = new PageInfo<>(goblinNftExCodeArrayList);

        return pageInfo;
    }

    @Override
    public Boolean defDrivLoseCode(String codeIds) {

        LocalDateTime now = LocalDateTime.now();

        // 获取兑换码
        List<GoblinNftExCode> goblinNftExCodes = goblinNftExCodeMapper.selectByIds(codeIds);

        List<String> codes = new ArrayList<>();
        Map<String, Integer> skuMap = new HashMap<>();

        for (GoblinNftExCode goblinNftExCode : goblinNftExCodes) {
            // redis 主动失效
            codes.add(goblinNftExCode.getCode());
            goblinNftExCode.setState(3);
            goblinNftExCode.setUpdatedAt(now);

            String skuId = "";
            if (StringUtil.isNotBlank(goblinNftExCode.getSkuId())) {
                skuId = goblinNftExCode.getSkuId();
            } else if (StringUtil.isNotBlank(goblinNftExCode.getBoxSkuId())) {
                skuId = goblinNftExCode.getBoxSkuId();
            }

            if (StringUtil.isNotBlank(skuId)) {
                if (skuMap.get(skuId) == null) {
                    skuMap.put(skuId, 0);
                }

                Integer number = skuMap.get(skuId);
                skuMap.put(skuId, number + 1);
            }
            goblinRedisUtils.removeCode(goblinNftExCode.getCode());

        }

        if (skuMap.size() > 0) {
            for (String key : skuMap.keySet()) {
                goblinRedisUtils.incrSkuStock(null, key, skuMap.get(key));
            }
        }


        // 批量修改
        goblinNftExCodeMapper.updateCodes(goblinNftExCodes);
        return true;
    }

    @Override
    public Boolean addAirdrop(GoblinNftExCodeParam goblinNftExCodeParam) {
        String code = goblinNftExCodeParam.getCode();
        String phone = goblinNftExCodeParam.getPhone();
        // 根据兑换code查询兑换码信息
        GoblinNftExCode goblinNftExCode = goblinNftExCodeMapper.selectGoblinNftCodeByCode(code);


        return null;
    }

    @Override
    public void excel(HttpServletResponse httpServletResponse, GoblinNftExCodeParam goblinNftExCodeParam) {
        // 入参
        GoblinNftExCode goblinNftExCode = GoblinNftExCode.getNew();
        goblinNftExCode.setCode(goblinNftExCodeParam.getCode());
        goblinNftExCode.setActivityId(goblinNftExCodeParam.getActivityId());
        goblinNftExCode.setState(goblinNftExCodeParam.getState());
        goblinNftExCode.setRedeemUid(goblinNftExCodeParam.getUserId());
        goblinNftExCode.setIsDrivi(goblinNftExCodeParam.getIsDrivi());
        if (StringUtil.isNotBlank(goblinNftExCodeParam.getSkuName())) {
            // 根据藏品名称获取 skuIds
            String skuName = goblinNftExCodeParam.getSkuName();
            List<GoblinGoodsSku> goblinGoodsSkus = goblinGoodsSkuMapper.selectSkuLikeName(skuName);
            if (goblinGoodsSkus.size() <= 0) {
                return;
            }
            StringBuffer skuIds = new StringBuffer();
            for (GoblinGoodsSku goblinGoodsSku : goblinGoodsSkus) {
                skuIds.append(goblinGoodsSku.getSkuId()).append(",");
            }
            goblinNftExCode.setSkuId(skuIds.deleteCharAt(skuIds.length() - 1).toString());
        }


        PageHelper.startPage(goblinNftExCodeParam.getPageNum(), 20, true);
        List<GoblinNftExCode> goblinNftExCodes = goblinNftExCodeMapper.selectGoblinNftCode(goblinNftExCode);
        StringBuffer skuIds = new StringBuffer();
        StringBuffer acticityIds = new StringBuffer();
        for (GoblinNftExCode gnc : goblinNftExCodes) {
            if (gnc.getState().equals(2)) {
                skuIds.append(gnc.getSkuId()).append(",");
            }
            acticityIds.append(gnc.getActivityId()).append(",");
        }

        // 获取返回对象实例
        ArrayList<GoblinNftExCodeVo> goblinNftExCodeArrayList = ObjectUtil.getGoblinNftExCodeArrayList();


        if (StringUtil.isNotBlank(skuIds)) {
            // 批量查询
            List<GoblinGoodsSku> goblinGoodsSkus = goblinGoodsSkuMapper.selectBySkuIds(skuIds.toString());
            for (GoblinNftExCode gnc : goblinNftExCodes) {
                for (GoblinGoodsSku goblinGoodsSku : goblinGoodsSkus) {
                    if (gnc.getSkuId().equals(goblinGoodsSku.getSkuId())) {
                        GoblinNftExCodeVo goblinNftExCodeVo = GoblinNftExCodeVo.getNew().copy(gnc);
                        goblinNftExCodeVo.setSkuName(goblinGoodsSku.getName());
                        goblinNftExCodeArrayList.add(goblinNftExCodeVo);
                        break;
                    }
                }
            }
        }


        // 根据活动ids 获取兑换活动和sku的关联
        List<GoblinNftExSku> goblinNftExSkus = goblinNftExSkuMapper.selectGoblinNftExSkuByActivityIds(acticityIds.toString());

        Map<String, List<GoblinNftExSku>> map = new HashMap<>();
        for (GoblinNftExSku goblinNftExSku : goblinNftExSkus) {
            if (map.get(goblinNftExSku.getActivityId()) == null) {
                map.put(goblinNftExSku.getActivityId(), new ArrayList<>());
            }
            map.get(goblinNftExSku.getActivityId()).add(goblinNftExSku);
        }


        for (GoblinNftExCodeVo gnc : goblinNftExCodeArrayList) {
            List<GoblinNftExSku> goblinNftExSkuList = map.get(gnc.getActivityId());
            for (GoblinNftExSku goblinNftExSku : goblinNftExSkuList) {
                if (gnc.getSkuId().equals(goblinNftExSku.getSkuId())) {
                    gnc.setExStartTime(goblinNftExSku.getExStartTime());
                    gnc.setExStopTime(goblinNftExSku.getExStopTime());
                    break;
                }
            }
        }


        try {
            writeExcel(httpServletResponse, goblinNftExCodeArrayList, "活动excel", "sheet1", GoblinNftExCodeVo.class);
        } catch (Exception e) {
            log.error("导出excel失败！");
        }

    }


    /**
     * 导出
     *
     * @param response
     * @param data
     * @param fileName
     * @param sheetName
     * @param clazz
     * @throws Exception
     */
    public static void writeExcel(HttpServletResponse response, List<? extends Object> data, String fileName,
                                  String sheetName, Class clazz) throws Exception {
        // 表头样式
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 设置表头居中对齐
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // 内容样式
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // 设置内容靠左对齐
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
        EasyExcel.write(getOutputStream(fileName, response), clazz).excelType(ExcelTypeEnum.XLSX).sheet(sheetName)
                .registerWriteHandler(horizontalCellStyleStrategy).doWrite(data);

    }

    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();
    }


}
