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

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.liquidnet.common.exception.LiquidnetServiceException;
import com.liquidnet.commons.lang.constant.LnsRegex;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.CurrentUtil;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.goblin.constant.GoblinStatusConst;
import com.liquidnet.service.goblin.dto.GoblinMarketGoodsExcelDto;
import com.liquidnet.service.goblin.dto.GoblinMarketGoodsUnDateExcelDto;
import com.liquidnet.service.goblin.dto.GoblinZhengzaiMarketOrderExcelDto;
import com.liquidnet.service.goblin.service.IGoblinExportService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.Pattern;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.List;

@Slf4j
@Api(tags = "商城-订单信息导出")
@Controller
@RequestMapping("/tools/export")
@Validated
public class GoblinExportDataController {

    @Autowired
    IGoblinExportService iGoblinExportService;

    /**
     * 导出商城订单信息
     *
     * @param beginTime
     * @param endTime
     * @return
     */
    @GetMapping("/exportMallOrder")
    @ApiOperation(value = "excel订单信息导出")
    @ResponseBody
    @ApiImplicitParams({
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "beginTime", value = "开始时间"),
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "storeId", value = "店铺id"),
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "endTime", value = "结束时间"),
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "state", value = "状态逗号隔开字符串[0-待付款(用户刚下单)|2-代发货(用户付完款 等待商城发货)|3-代收货(商城已经发货 等待用户确认收货)|4-已完成(用户已经确认收货 订单结束)|5-取消订单(用户未付款前取消订单)|6-退款通过(用户已经付款但是商城还未发货，用户发出退款申请，商城同意退款)|7-退货通过(用户已经确认收货后用户发出退货申请，商城同意所有退货申请 ，一个订单可能有多个单品)|61-6的发起状态|71-7的发起状态】"),
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "mailType", value = "快递状态[0-全部|1-未发货|2-已发货]"),
    })
    public ResponseDto<String> exportMallOrder(HttpServletResponse response, @RequestParam("beginTime") String beginTime, @RequestParam("endTime") String endTime,
                                               @RequestParam("state") String state, @RequestParam("mailType") Integer mailType, @RequestParam("storeId") String storeId) {
        return iGoblinExportService.exportMallOrder(response, beginTime, endTime, state, mailType, storeId);
    }

    /**
     * excel正在下单根据日期导出
     *
     * @return
     */
    @GetMapping("/exportMarketGoods")
    @ApiOperation(value = "正在下单-商品根据日期")
    @ResponseBody
    @ApiImplicitParams({
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "storeId", value = "店铺ID"),
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "marketId", value = "活动ID"),
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "bDate", value = "开始时间[yyyy-MM-dd]"),
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "eDate", value = "结束时间[yyyy-MM-dd]"),
    })
    public void exportMarketGoods(@RequestParam(required = true, name = "bDate") @Pattern(regexp = LnsRegex.Valid.DATETIME_YMD, message = "开始日期格式有误") String beginDate,
                                  @RequestParam(required = true, name = "eDate") @Pattern(regexp = LnsRegex.Valid.DATETIME_YMD, message = "结束日期格式有误") String endDate,
                                  @RequestParam String marketId, @RequestParam String storeId, HttpServletResponse response) {
        String currentUid = CurrentUtil.getCurrentUid();
        ServletOutputStream servletOutputStream = null;
        try {
            log.debug("数据导出:正在下单-商品根据日期导出:[uid:{},storeId:{},marketId:{},date:{}~{}]", currentUid, storeId, marketId, beginDate, endDate);
            String fileName = DateUtil.Formatter.yyyyMMddHHmmssTrim.format(LocalDateTime.now())
                    .concat(new String(("正在下单-商品根据日期导出").getBytes("gb2312"), StandardCharsets.ISO_8859_1));
            response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=".concat(fileName).concat(ExcelTypeEnum.XLSX.getValue()));
            response.setContentType(MediaType.MULTIPART_FORM_DATA_VALUE);
            response.setCharacterEncoding(StandardCharsets.UTF_8.name());
            servletOutputStream = response.getOutputStream();

            HashMap<String, Object> paramMap = CollectionUtil.mapStringObject();
            paramMap.put("storeId", storeId);
            paramMap.put("marketId", GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue() + marketId);
            LocalDate beginLocalDate = DateUtil.Formatter.yyyy_MM_dd.parse2LocalDate(beginDate);
            LocalDate endLocalDate = DateUtil.Formatter.yyyy_MM_dd.parse2LocalDate(endDate);
            paramMap.put("beginTime", null == beginLocalDate ? beginLocalDate : LocalDateTime.of(beginLocalDate, LocalTime.MIN));
            paramMap.put("endTime", null == endLocalDate ? endLocalDate : LocalDateTime.of(endLocalDate, LocalTime.MAX));
            if (log.isDebugEnabled()) {
                log.debug("数据导出:正在下单-商品根据日期导出:[uid:{},paramMap:{}]", currentUid, JsonUtils.toJson(paramMap));
            }

            List<GoblinMarketGoodsExcelDto> excelDtos = iGoblinExportService.exportMarketGoods(paramMap);
            if (CollectionUtils.isEmpty(excelDtos)) {
                log.warn("数据导出:正在下单-商品根据日期导出:无数据，请核实:[uid:{},paramMap:{}]", currentUid, JsonUtils.toJson(paramMap));
                return;
            }
            EasyExcel.write(servletOutputStream, GoblinMarketGoodsExcelDto.class).sheet("销售数据").doWrite(excelDtos);
        } catch (IOException e) {
            log.error("数据导出:正在下单-商品根据日期导出:异常[uid:{},storeId:{},marketId:{},date:{}~{},ex.msg={}]",
                    currentUid, storeId, marketId, beginDate, endDate, e.getLocalizedMessage());
            throw new LiquidnetServiceException("-1", "导出失败，请联系网站管理员");
        } finally {
            if (null != servletOutputStream) {
                try {
                    servletOutputStream.close();
                } catch (Exception ignored) {
                }
            }
        }
    }

    /**
     * excel正在下单根据导出
     */
    @GetMapping("/exportMarketGoodsUnDate")
    @ApiOperation(value = "正在下单-商品导出")
    @ResponseBody
    @ApiImplicitParams({
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "storeId", value = "店铺ID"),
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "marketId", value = "活动ID"),
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "bDate", value = "开始时间[yyyy-MM-dd]"),
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "eDate", value = "结束时间[yyyy-MM-dd]"),
    })
    public void exportMarketGoodsUnDate(@RequestParam(required = true, name = "bDate") @Pattern(regexp = LnsRegex.Valid.DATETIME_FULL, message = "开始日期格式有误") String beginDate,
                                        @RequestParam(required = true, name = "eDate") @Pattern(regexp = LnsRegex.Valid.DATETIME_FULL, message = "结束日期格式有误") String endDate,
                                        @RequestParam String marketId, @RequestParam String storeId, HttpServletResponse response) {
        String currentUid = CurrentUtil.getCurrentUid();
        ServletOutputStream servletOutputStream = null;
        try {
            log.debug("数据导出:正在下单-商品导出:[uid:{},storeId:{},marketId:{},date:{}~{}]", currentUid, storeId, marketId, beginDate, endDate);
            String fileName = DateUtil.Formatter.yyyyMMddHHmmssTrim.format(LocalDateTime.now())
                    .concat(new String(("正在下单-商品导出").getBytes("gb2312"), StandardCharsets.ISO_8859_1));
            response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=".concat(fileName).concat(ExcelTypeEnum.XLSX.getValue()));
            response.setContentType(MediaType.MULTIPART_FORM_DATA_VALUE);
            response.setCharacterEncoding(StandardCharsets.UTF_8.name());
            servletOutputStream = response.getOutputStream();

            HashMap<String, Object> paramMap = CollectionUtil.mapStringObject();
            paramMap.put("storeId", storeId);
            paramMap.put("marketId", GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue() + marketId);
            LocalDate beginLocalDate = DateUtil.Formatter.yyyyMMddHHmmss.parse2LocalDate(beginDate);
            LocalDate endLocalDate = DateUtil.Formatter.yyyyMMddHHmmss.parse2LocalDate(endDate);
            paramMap.put("beginTime", null == beginLocalDate ? beginLocalDate : LocalDateTime.of(beginLocalDate, LocalTime.MIN));
            paramMap.put("endTime", null == endLocalDate ? endLocalDate : LocalDateTime.of(endLocalDate, LocalTime.MAX));
            if (log.isDebugEnabled()) {
                log.debug("数据导出:正在下单-商品导出:[uid:{},paramMap:{}]", currentUid, JsonUtils.toJson(paramMap));
            }

            List<GoblinMarketGoodsUnDateExcelDto> excelDtos = iGoblinExportService.exportMarketGoodsUnDate(paramMap);
            if (CollectionUtils.isEmpty(excelDtos)) {
                log.warn("数据导出:正在下单-商品导出:无数据，请核实:[uid:{},paramMap:{}]", currentUid, JsonUtils.toJson(paramMap));
                return;
            }
            EasyExcel.write(servletOutputStream, GoblinMarketGoodsUnDateExcelDto.class).sheet("销售数据").doWrite(excelDtos);
        } catch (IOException e) {
            log.error("数据导出:正在下单-商品导出:异常[uid:{},storeId:{},marketId:{},date:{}~{},ex.msg={}]",
                    currentUid, storeId, marketId, beginDate, endDate, e.getLocalizedMessage());
            throw new LiquidnetServiceException("-1", "导出失败，请联系网站管理员");
        } finally {
            if (null != servletOutputStream) {
                try {
                    servletOutputStream.close();
                } catch (Exception ignored) {
                }
            }
        }
    }

    @GetMapping("zzMarketOrder")
    @ApiOperation(value = "正在下单-销售数据")
    @ResponseBody
    @ApiImplicitParams({
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "storeId", value = "店铺ID"),
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "marketId", value = "活动ID"),
            @ApiImplicitParam(type = "form", required = false, dataType = "String", name = "bDate", value = "开始时间[yyyy-MM-dd]"),
            @ApiImplicitParam(type = "form", required = false, dataType = "String", name = "eDate", value = "结束时间[yyyy-MM-dd]"),
    })
    public void exportZhengzaiMarketOrder(@RequestParam(required = false, name = "bDate") @Pattern(regexp = LnsRegex.Valid.DATETIME_YMD, message = "开始日期格式有误") String beginDate,
                                          @RequestParam(required = false, name = "eDate") @Pattern(regexp = LnsRegex.Valid.DATETIME_YMD, message = "结束日期格式有误") String endDate,
                                          @RequestParam String marketId, @RequestParam String storeId, HttpServletResponse response) {
        String currentUid = CurrentUtil.getCurrentUid();
        ServletOutputStream servletOutputStream = null;
        try {
            log.debug("数据导出:正在下单-销售数据:[uid:{},storeId:{},marketId:{},date:{}~{}]", currentUid, storeId, marketId, beginDate, endDate);
            String fileName = DateUtil.Formatter.yyyyMMddHHmmssTrim.format(LocalDateTime.now())
                    .concat(new String(("正在下单-销售数据").getBytes("gb2312"), StandardCharsets.ISO_8859_1));
            response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=".concat(fileName).concat(ExcelTypeEnum.XLSX.getValue()));
            response.setContentType(MediaType.MULTIPART_FORM_DATA_VALUE);
            response.setCharacterEncoding(StandardCharsets.UTF_8.name());
            servletOutputStream = response.getOutputStream();

            HashMap<String, Object> paramMap = CollectionUtil.mapStringObject();
            paramMap.put("storeId", storeId);
            paramMap.put("marketId", GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue() + marketId);
            LocalDate beginLocalDate = DateUtil.Formatter.yyyy_MM_dd.parse2LocalDate(beginDate);
            LocalDate endLocalDate = DateUtil.Formatter.yyyy_MM_dd.parse2LocalDate(endDate);
            paramMap.put("beginTime", null == beginLocalDate ? beginLocalDate : LocalDateTime.of(beginLocalDate, LocalTime.MIN));
            paramMap.put("endTime", null == endLocalDate ? endLocalDate : LocalDateTime.of(endLocalDate, LocalTime.MAX));
            if (log.isDebugEnabled()) {
                log.debug("数据导出:正在下单-销售数据:[uid:{},paramMap:{}]", currentUid, JsonUtils.toJson(paramMap));
            }

            List<GoblinZhengzaiMarketOrderExcelDto> excelDtos = iGoblinExportService.exportZhengzaiMarketOrder(paramMap);
            if (CollectionUtils.isEmpty(excelDtos)) {
                log.warn("数据导出:正在下单-销售数据:无数据，请核实:[uid:{},paramMap:{}]", currentUid, JsonUtils.toJson(paramMap));
                return;
            }
            EasyExcel.write(servletOutputStream, GoblinZhengzaiMarketOrderExcelDto.class).sheet("销售数据").doWrite(excelDtos);
        } catch (IOException e) {
            log.error("数据导出:正在下单-销售数据:异常[uid:{},storeId:{},marketId:{},date:{}~{},ex.msg={}]",
                    currentUid, storeId, marketId, beginDate, endDate, e.getLocalizedMessage());
            throw new LiquidnetServiceException("-1", "导出失败，请联系网站管理员");
        } finally {
            if (null != servletOutputStream) {
                try {
                    servletOutputStream.close();
                } catch (Exception ignored) {
                }
            }
        }
    }

}
