package com.order.controller.business;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSONArray;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.common.security.SessionObject;
import com.hfkj.common.security.UserCenter;
import com.hfkj.common.utils.DateUtil;
import com.hfkj.common.utils.ResponseMsgUtil;
import com.hfkj.config.CommonSysConst;
import com.hfkj.entity.*;
import com.hfkj.model.ResponseData;
import com.hfkj.model.SecUserSessionObject;
import com.hfkj.model.order.orderExport.OrderGoodsExportModel;
import com.hfkj.service.file.FileRecordsService;
import com.hfkj.service.goods.BsOrderGoodsService;
import com.hfkj.service.goods.GoodsUserAddressService;
import com.hfkj.service.order.BsOrderService;
import com.hfkj.sysenum.SecUserObjectTypeEnum;
import com.hfkj.sysenum.fileRecords.FileRecordsEnum;
import com.hfkj.sysenum.order.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Controller
@RequestMapping(value="/orderGoods")
@Api(value="实物订单管理")
public class BsOrderGoodsController {

    private static final Logger log = LoggerFactory.getLogger(BsOrderGoodsController.class);

    @Resource
    private BsOrderGoodsService bsOrderGoodsService;

    @Resource
    private UserCenter userCenter;

    @Resource
    private BsOrderService orderService;

    @Resource
    private FileRecordsService fileRecordsService;

    @Resource
    private GoodsUserAddressService addressService;

    @Resource
    private BsOrderGoodsService orderGoodsService;


    @RequestMapping(value="/getListGoods",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "查询列表")
    public ResponseData getListGoods(@RequestParam(value = "logisticsNo" , required = false) String logisticsNo,
                                     @RequestParam(value = "goodsType" , required = false) Long goodsType,
                                     @RequestParam(value = "goodsBrand" , required = false) Long goodsBrand,
                                     @RequestParam(value = "orderNo" , required = false) String orderNo,
                                     @RequestParam(value = "childOrderNo" , required = false) String childOrderNo,
                                     @RequestParam(value = "userPhone" , required = false) String userPhone,
                                     @RequestParam(value = "goodsSpecsName" , required = false) String goodsSpecsName,
                                     @RequestParam(value = "goodsName" , required = false) String goodsName,
                                     @RequestParam(value = "logisticsStatus" , required = false) String logisticsStatus,
                                     @RequestParam(value = "payType" , required = false) Integer payType,
                                     @RequestParam(value = "status" , required = false) Integer status,
                                     @RequestParam(value = "merId" , required = false) Long merId,
                                     @RequestParam(value = "createTimeS" , required = false) Long createTimeS,
                                     @RequestParam(value = "createTimeE" , required = false) Long createTimeE,
                                     @RequestParam(value = "pageNum" , required = true) Integer pageNum,
                                     @RequestParam(value = "pageSize" , required = true) Integer pageSize, HttpServletRequest request) {
        try {

            SessionObject sessionObject = userCenter.getSessionObject(request);
            SecUserSessionObject userModel = (SecUserSessionObject) sessionObject.getObject();

            Map<String , Object> map = new HashMap<>();
            if (userModel.getAccount().getObjectType().equals(SecUserObjectTypeEnum.type1.getCode())) {
                map.put("merId", merId);
            }
            if (userModel.getAccount().getObjectType().equals(SecUserObjectTypeEnum.type2.getCode())) {
                map.put("merId", userModel.getAccount().getObjectId());
            }
            if (userModel.getAccount().getPlatformCode() != null) {
                map.put("platformCode", userModel.getAccount().getPlatformCode());
            }

            map.put("logisticsNo", logisticsNo);
            map.put("goodsType", goodsType);
            map.put("goodsBrand", goodsBrand);
            map.put("orderNo", orderNo);
            map.put("childOrderNo", childOrderNo);
            map.put("userPhone", userPhone);
            map.put("logisticsStatus", logisticsStatus);
            map.put("goodsSpecsName", goodsSpecsName);
            map.put("goodsName", goodsName);
            map.put("payType", payType);
            map.put("createTimeS", createTimeS);
            map.put("createTimeE", createTimeE);
            map.put("status", status);

            PageHelper.startPage(pageNum, pageSize);
            return ResponseMsgUtil.success(new PageInfo<>(bsOrderGoodsService.getList(map)));

        } catch (Exception e) {
            log.error("error!",e);
            return ResponseMsgUtil.exception(e);
        }
    }


    @RequestMapping(value="/exportGoodsOrder",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "导出商品订单")
    public ResponseData exportGoodsOrder(@RequestParam(value = "logisticsNo" , required = false) String logisticsNo,
                                     @RequestParam(value = "goodsType" , required = false) Long goodsType,
                                     @RequestParam(value = "goodsBrand" , required = false) Long goodsBrand,
                                     @RequestParam(value = "orderNo" , required = false) String orderNo,
                                     @RequestParam(value = "childOrderNo" , required = false) String childOrderNo,
                                     @RequestParam(value = "userPhone" , required = false) String userPhone,
                                     @RequestParam(value = "goodsSpecsName" , required = false) String goodsSpecsName,
                                     @RequestParam(value = "goodsName" , required = false) String goodsName,
                                     @RequestParam(value = "logisticsStatus" , required = false) String logisticsStatus,
                                     @RequestParam(value = "payType" , required = false) Integer payType,
                                     @RequestParam(value = "status" , required = false) Integer status,
                                     @RequestParam(value = "merId" , required = false) Long merId,
                                     @RequestParam(value = "createTimeS" , required = false) Long createTimeS,
                                     @RequestParam(value = "createTimeE" , required = false) Long createTimeE, HttpServletRequest request) {
        // 插入下载记录
        FileRecords fileRecords = new FileRecords();



        try {

            SessionObject sessionObject = userCenter.getSessionObject(request);
            SecUserSessionObject userModel = (SecUserSessionObject) sessionObject.getObject();


            Map<String , Object> map = new HashMap<>();
            if (userModel.getAccount().getObjectType().equals(SecUserObjectTypeEnum.type1.getCode())) {
                map.put("merId", merId);
            }
            if (userModel.getAccount().getObjectType().equals(SecUserObjectTypeEnum.type2.getCode())) {
                map.put("merId", userModel.getAccount().getObjectId());
            }

            if (userModel.getAccount().getPlatformCode() != null) {
                map.put("platformCode", userModel.getAccount().getPlatformCode());
            }

            map.put("logisticsNo", logisticsNo);
            map.put("goodsType", goodsType);
            map.put("goodsBrand", goodsBrand);
            map.put("orderNo", orderNo);
            map.put("childOrderNo", childOrderNo);
            map.put("userPhone", userPhone);
            map.put("logisticsStatus", logisticsStatus);
            map.put("goodsSpecsName", goodsSpecsName);
            map.put("goodsName", goodsName);
            map.put("payType", payType);
            map.put("createTimeS", createTimeS);
            map.put("createTimeE", createTimeE);
            map.put("status", status);

            String dataSting = "";
            if (createTimeE != null) {
                dataSting = DateUtil.date2String(DateUtil.long2Date(createTimeS) , DateUtil.YMDHMS) + "-" + DateUtil.date2String(DateUtil.long2Date(createTimeE) , DateUtil.YMDHMS);
            } else {
                dataSting = DateUtil.date2String(new Date(), DateUtil.YMDHMS);
            }

            String fileUrl = CommonSysConst.getSysConfig().getFileUrl();
            String filePath = "/temporary/" + userModel.getAccount().getId() + "/" ;
            String pathName =  filePath + FileRecordsEnum.status1.getName() +  "交易数据导出"  + dataSting +".xlsx";

            if (fileRecordsService.findExported(map.toString() , userModel.getAccount().getId())) {
                throw ErrorHelp.genException(SysCode.System , ErrorCode.COMMON_ERROR , "相同导出内容请勿重复点击！");
            }

            fileRecords.setCreateTime(new Date());
            fileRecords.setBusinessType(FileRecordsEnum.status1.getCode());
            fileRecords.setDownloadConditions(map.toString());
            fileRecords.setOpId(userModel.getAccount().getId());
            fileRecords.setOpName(userModel.getAccount().getUserName());
            fileRecords.setStatus(2);
            fileRecords.setDownloadStatus(2);
            fileRecords.setFileUrl(CommonSysConst.getSysConfig().getDomainName() + "/filesystem" + pathName);
            fileRecords.setType("2");
            fileRecords.setTitle(FileRecordsEnum.status1.getName() +  "交易数据导出" + dataSting  + ".xls");
            fileRecordsService.create(fileRecords);

            // 创建线程
            ThreadPoolExecutor executor = new ThreadPoolExecutor(
                    2, // 核心线程数
                    5, // 最大线程数
                    1, // 线程空闲时间
                    TimeUnit.MINUTES, // 时间单位
                    new ArrayBlockingQueue<>(5), // 任务队列
                    new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
            );

            // 提交任务给线程池
            executor.execute(() -> {

                try {
                    List<BsOrderGoods> list = bsOrderGoodsService.getList(map);
                    List<OrderGoodsExportModel> goodsExportModels = new ArrayList<>();

                    for (BsOrderGoods bsOrderGoods : list) {
                        OrderGoodsExportModel orderGoodsExportModel = new OrderGoodsExportModel();

                        BeanUtils.copyProperties(orderGoodsExportModel, bsOrderGoods);
                        if (bsOrderGoods.getIntegralDiscountPrice() != null) {
                            orderGoodsExportModel.setIntegralDiscountPrice(BigDecimal.valueOf(bsOrderGoods.getIntegralDiscountPrice()).divide(new BigDecimal(100)));
                        }
                        if (bsOrderGoods.getPayChannel() != null) {
                            orderGoodsExportModel.setPayChannel(OrderPayChannelEnum.getData(bsOrderGoods.getPayChannel()).getName());
                        }
                        if (bsOrderGoods.getPayType() != null) {
                            orderGoodsExportModel.setPayType(OrderPayTypeEnum.getData(bsOrderGoods.getPayType()).getName());
                        }
                        if (bsOrderGoods.getStatus() != null) {
                            orderGoodsExportModel.setTradeStatus(OrderChildStatusEnum.getData(bsOrderGoods.getStatus()).getName());
                        }
                        goodsExportModels.add(orderGoodsExportModel);
                    }

                    File file = new File(fileUrl + filePath);
                    if (!file.exists()) {
                        file.mkdirs();
                    }

                    EasyExcel.write(fileUrl+pathName)
                            .head(OrderGoodsExportModel.class)
                            .sheet(fileRecords.getTitle())
                            .doWrite(goodsExportModels);

                    fileRecords.setStatus(1);
                    fileRecords.setUpdateTime(new Date());
                    fileRecordsService.update(fileRecords);
                } catch (Exception e) {
                    fileRecords.setStatus(3);
                    fileRecords.setUpdateTime(new Date());
                    fileRecords.setExt1(e.toString());
                    fileRecordsService.update(fileRecords);
                    log.error("error!",e);
                }
            });

            // 关闭线程池
            executor.shutdown();
            return ResponseMsgUtil.success(fileRecords);

        } catch (Exception e) {
            fileRecords.setStatus(3);
            fileRecords.setUpdateTime(new Date());
            fileRecordsService.update(fileRecords);
            log.error("error!",e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="/updateLogisticsNo",method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "更新物流订单号")
    public ResponseData updateLogisticsNo(@RequestBody BsOrderGoods body
    ) {
        try {

            if (body == null
                    || body.getId() == null
                    || StringUtils.isBlank(body.getLogisticsNo())
            ) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
            }

            BsOrderGoods goodsOrder = bsOrderGoodsService.queryDetail(body.getId());

            if (goodsOrder == null) {
                throw ErrorHelp.genException(SysCode.System , ErrorCode.COMMON_ERROR , "信息错误！");
            }

            String logisticsNo = body.getLogisticsNo().replaceAll("\\s+", "");

            goodsOrder.setLogisticsNo(logisticsNo);
            goodsOrder.setUpdateTime(new Date());

            // 删除缓存
            orderService.cacheDelete(goodsOrder.getOrderNo());
            bsOrderGoodsService.update(goodsOrder);
            getLogisticsMsg(goodsOrder.getId());
            return ResponseMsgUtil.success("更新成功！");

        } catch (Exception e) {
            log.error("OrderExtController -> getGasOrderDetail() error!",e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="/getLogisticsMsg",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "查询物流")
    public ResponseData getLogisticsMsg(@RequestParam(value = "id" , required = false) Long id) {
        try {
            Map<String, Object> map = new HashMap<>();

            BsOrderGoods orderGoods = bsOrderGoodsService.queryDetail(id);

            if (orderGoods == null) {
                throw ErrorHelp.genException(SysCode.System , ErrorCode.COMMON_ERROR , "暂无物流信息！");
            }

            GoodsUserAddress userAddress = addressService.queryDetail(orderGoods.getDeliveryAddressId());

            if (userAddress == null) {
                throw ErrorHelp.genException(SysCode.System , ErrorCode.COMMON_ERROR , "暂无物流信息！");
            }

            GoodsLogistics logistics = (GoodsLogistics) bsOrderGoodsService.getLogisticsMsg(orderGoods.getLogisticsNo() , userAddress.getPhone());

            if (logistics.getLogisticsStatus() != null) {
                orderGoods.setLogisticsStatus(logistics.getLogisticsStatus());
                orderGoods.setLogisticsStatusDesc(logistics.getLogisticsStatusDesc());
            } else {
                orderGoods.setLogisticsStatus(OrderLogisticsStatusEnum.statusWAIT_ACCEPT.getCode());
                orderGoods.setLogisticsStatusDesc(OrderLogisticsStatusEnum.statusWAIT_ACCEPT.getName());
            }

            bsOrderGoodsService.update(orderGoods);
            map.put("logistics", logistics);
            JSONArray object = JSONArray.parseArray(logistics.getLogisticsTraceDetails());
            map.put("logisticsTraceDetails",  object);

            return ResponseMsgUtil.success(map);

        } catch (Exception e) {
            log.error("error!",e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="/confirmReceipt",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "确认收货")
    public ResponseData confirmReceipt(@RequestParam(value = "id" , required = false) Long id) {
        try {
            bsOrderGoodsService.confirmReceipt(id);

            return ResponseMsgUtil.success("成功");

        } catch (Exception e) {
            log.error("error!",e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="/updateShippingAddress",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "更新收货地址")
    public ResponseData updateShippingAddress(@RequestParam(value = "orderNo" , required = true) String orderNo,
                                              @RequestParam(value = "addressId" , required = true) Long addressId) {
        try {

            GoodsUserAddress deliveryAddress = addressService.queryDetail(addressId);

            if (deliveryAddress == null) {
                log.error("GoodsDetailController -> findGoodsDetailById() error!");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到相信息");
            }

            BsOrderGoods orderGoods = orderGoodsService.findGoodsOrder(orderNo);

            if (orderGoods == null) {
                throw ErrorHelp.genException(SysCode.System , ErrorCode.COMMON_ERROR , "未找到相信息");
            }

            orderGoods.setDeliveryAddressId(deliveryAddress.getId());
            orderGoods.setUpdateTime(new Date());
            orderGoods.setDeliveryAddress(deliveryAddress.getAddress());

            orderGoodsService.update(orderGoods);

            return ResponseMsgUtil.success("成功");

        } catch (Exception e) {
            log.error("error!",e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="/goodsOrderCount",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "待收货数量")
    public ResponseData goodsOrderCount(HttpServletRequest request) {
        try {
            SessionObject sessionObject = userCenter.getSessionObject(request);
            SecUserSessionObject userModel = (SecUserSessionObject) sessionObject.getObject();

            Map<String , Object> map = new HashMap<>();

            if (userModel.getAccount().getObjectType().equals(SecUserObjectTypeEnum.type2.getCode())) {
                map.put("merId", userModel.getAccount().getObjectId());
            }

            map.put("logisticsStatus", "待发货");
            map.put("status", 2);


            return ResponseMsgUtil.success(bsOrderGoodsService.getList(map).size());

        } catch (Exception e) {
            log.error("error!",e);
            return ResponseMsgUtil.exception(e);
        }
    }

}
