package com.yonge.cooleshow.admin.service.impl;

import com.github.pagehelper.PageHelper;
import com.yonge.cooleshow.admin.dao.OmsOrderDao;
import com.yonge.cooleshow.admin.dao.OmsOrderOperateHistoryDao;
import com.yonge.cooleshow.admin.dto.*;
import com.yonge.cooleshow.admin.dto.search.OrderStatisticalSearch;
import com.yonge.cooleshow.admin.dto.search.UserStatisticalSearch;
import com.yonge.cooleshow.admin.service.OmsOrderReturnApplyService;
import com.yonge.cooleshow.admin.service.PmsProductService;
import com.yonge.cooleshow.mbg.mapper.OmsOrderMapper;
import com.yonge.cooleshow.mbg.mapper.OmsOrderOperateHistoryMapper;
import com.yonge.cooleshow.mbg.model.OmsOrder;
import com.yonge.cooleshow.mbg.model.OmsOrderExample;
import com.yonge.cooleshow.mbg.model.OmsOrderOperateHistory;
import com.yonge.cooleshow.admin.service.OmsOrderService;
import com.yonge.toolset.base.exception.BizException;
import com.yonge.toolset.utils.date.DateUtil;
import com.yonge.cooleshow.admin.enums.OrderStatisticalEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.WeekFields;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 订单管理Service实现类
 * Created by macro on 2018/10/11.
 */
@Service
public class OmsOrderServiceImpl implements OmsOrderService {
    @Autowired
    private OmsOrderMapper orderMapper;
    @Autowired
    private OmsOrderDao orderDao;
    @Autowired
    private OmsOrderOperateHistoryDao orderOperateHistoryDao;
    @Autowired
    private OmsOrderOperateHistoryMapper orderOperateHistoryMapper;

    @Autowired
    private OmsOrderReturnApplyService orderReturnApplyService;

    @Autowired
    private PmsProductService productService;

    @Override
    public List<OrderVo> list(OmsOrderQueryParam queryParam, Integer pageSize, Integer pageNum) {
        PageHelper.startPage(pageNum, pageSize);
        return orderDao.getList(queryParam);
    }

    @Override
    public int delivery(List<OmsOrderDeliveryParam> deliveryParamList) {
        //批量发货
        int count = orderDao.delivery(deliveryParamList);
        //添加操作记录
        List<OmsOrderOperateHistory> operateHistoryList = deliveryParamList.stream()
                .map(omsOrderDeliveryParam -> {
                    OmsOrderOperateHistory history = new OmsOrderOperateHistory();
                    history.setOrderId(omsOrderDeliveryParam.getOrderId());
                    history.setCreateTime(new Date());
                    history.setOperateMan("后台管理员");
                    history.setOrderStatus(2);
                    history.setNote("完成发货");
                    return history;
                }).collect(Collectors.toList());
        orderOperateHistoryDao.insertList(operateHistoryList);
        return count;
    }

    @Override
    public int close(List<Long> ids, String note) {
        OmsOrder record = new OmsOrder();
        record.setStatus(4);
        OmsOrderExample example = new OmsOrderExample();
        example.createCriteria().andDeleteStatusEqualTo(0).andIdIn(ids);

        List<OmsOrder> omsOrders = orderMapper.selectByExample(example);
        long count1 = omsOrders.stream()
                               .filter(omsOrder -> omsOrder.getStatus() != 0 && omsOrder.getStatus() != 6)
                               .count();
        if (count1 != 0) {
            throw new BizException("订单不处于待支付状态，不能关闭");
        }
        int count = orderMapper.updateByExampleSelective(record, example);
        List<OmsOrderOperateHistory> historyList = ids.stream().map(orderId -> {
            OmsOrderOperateHistory history = new OmsOrderOperateHistory();
            history.setOrderId(orderId);
            history.setCreateTime(new Date());
            history.setOperateMan("后台管理员");
            history.setOrderStatus(4);
            history.setNote("订单关闭:"+note);
            return history;
        }).collect(Collectors.toList());
        orderOperateHistoryDao.insertList(historyList);
        return count;
    }

    @Override
    public int delete(List<Long> ids) {
        OmsOrder record = new OmsOrder();
        record.setDeleteStatus(1);
        OmsOrderExample example = new OmsOrderExample();
        example.createCriteria().andDeleteStatusEqualTo(0).andIdIn(ids);
        return orderMapper.updateByExampleSelective(record, example);
    }

    @Override
    public OmsOrderDetail detail(Long id) {
        return orderDao.getDetail(id);
    }

    @Override
    public int updateReceiverInfo(OmsReceiverInfoParam receiverInfoParam) {
        OmsOrder order = new OmsOrder();
        order.setId(receiverInfoParam.getOrderId());
        order.setReceiverName(receiverInfoParam.getReceiverName());
        order.setReceiverPhone(receiverInfoParam.getReceiverPhone());
        order.setReceiverPostCode(receiverInfoParam.getReceiverPostCode());
        order.setReceiverDetailAddress(receiverInfoParam.getReceiverDetailAddress());
        order.setReceiverProvince(receiverInfoParam.getReceiverProvince());
        order.setReceiverCity(receiverInfoParam.getReceiverCity());
        order.setReceiverRegion(receiverInfoParam.getReceiverRegion());
        order.setModifyTime(new Date());
        int count = orderMapper.updateByPrimaryKeySelective(order);
        //插入操作记录
        OmsOrderOperateHistory history = new OmsOrderOperateHistory();
        history.setOrderId(receiverInfoParam.getOrderId());
        history.setCreateTime(new Date());
        history.setOperateMan("后台管理员");
        history.setOrderStatus(receiverInfoParam.getStatus());
        history.setNote("修改收货人信息");
        orderOperateHistoryMapper.insert(history);
        return count;
    }

    @Override
    public int updateMoneyInfo(OmsMoneyInfoParam moneyInfoParam) {
        OmsOrder order = new OmsOrder();
        order.setId(moneyInfoParam.getOrderId());
        order.setFreightAmount(moneyInfoParam.getFreightAmount());
        order.setDiscountAmount(moneyInfoParam.getDiscountAmount());
        order.setModifyTime(new Date());
        int count = orderMapper.updateByPrimaryKeySelective(order);
        //插入操作记录
        OmsOrderOperateHistory history = new OmsOrderOperateHistory();
        history.setOrderId(moneyInfoParam.getOrderId());
        history.setCreateTime(new Date());
        history.setOperateMan("后台管理员");
        history.setOrderStatus(moneyInfoParam.getStatus());
        history.setNote("修改费用信息");
        orderOperateHistoryMapper.insert(history);
        return count;
    }

    @Override
    public int updateNote(Long id, String note, Integer status) {
        OmsOrder order = new OmsOrder();
        order.setId(id);
        order.setNote(note);
        order.setModifyTime(new Date());
        int count = orderMapper.updateByPrimaryKeySelective(order);
        OmsOrderOperateHistory history = new OmsOrderOperateHistory();
        history.setOrderId(id);
        history.setCreateTime(new Date());
        history.setOperateMan("后台管理员");
        history.setOrderStatus(status);
        history.setNote("修改备注信息："+note);
        orderOperateHistoryMapper.insert(history);
        return count;
    }

    @Override
    public void userStatistical(UserStatisticalSearch search) {
        // orderDao.userStatistical(search);
    }

    @Override
    public List<Map<String,Object>> userOrderInfoList(Map<String, Object> param) {
        return orderDao.getUserOrderInfoList(param);
    }

    @Override
    public HomeStatistical countStatistical() {
        // 订单状态
        HomeStatistical homeStatistical = orderDao.selectOrderStatusNum();
        if (homeStatistical == null) {
            homeStatistical = new HomeStatistical();
        }

        // 缺货登记   库存紧张
        HomeStatistical stock = productService.countLowStockCount();
        if (stock == null) {
            stock = new HomeStatistical();
        }

        homeStatistical.setOutStock(stock.getOutStock());
        homeStatistical.setOutStockProduct(stock.getOutStockProduct());

        // 待处理退款申请  待处理退货订单
        HomeStatistical returnInfo = orderReturnApplyService.countReturnStatus();
        if (returnInfo == null) {
            returnInfo = new HomeStatistical();
        }

        homeStatistical.setWaitDisposeRefund(returnInfo.getWaitDisposeRefund());
        homeStatistical.setWaitDisposeRefundOrder(returnInfo.getWaitDisposeRefundOrder());

        // 已下架 已上架 全部商品
        HomeStatistical product = productService.countProductShowStatus();

        if (product == null) {
            product = new HomeStatistical();
        }

        homeStatistical.setShelves(product.getShelves());
        homeStatistical.setDelisted(product.getDelisted());
        homeStatistical.setProductNum(product.getProductNum());

        Date endTime = Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());
        LocalDateTime localDateTime = LocalDateTime.now().plusDays(-1);
        LocalDate localDate = localDateTime.toLocalDate();
        Date startTime = Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());

        // 今日、昨日 订单总数和销售总额
        List<OrderStatistical> orderStatistical = orderDao
                .selectOrderCountAndAmount(startTime, endTime, OrderStatisticalEnum.DAY.name());

        Map<String, List<OrderStatistical>> collect = orderStatistical.stream()
                              .collect(Collectors.groupingBy(OrderStatistical::getDate));
        OrderStatistical statistical = getOrderStatistical(collect, DateUtil.format(startTime, "yyyy-MM-dd"));
        homeStatistical.setYesterdayOrderNum(statistical.getOrderNum());
        homeStatistical.setYesterdayOrderAmount(statistical.getOrderAmount());

        statistical = getOrderStatistical(collect, DateUtil.format(endTime, "yyyy-MM-dd"));
        homeStatistical.setTodayOrderNum(statistical.getOrderNum());
        homeStatistical.setTodayOrderAmount(statistical.getOrderAmount());

        return homeStatistical;
    }

    @Override
    public HomeOrderStatistical orderStatistical(OrderStatisticalSearch search) {

        HomeOrderStatistical homeOrderStatistical = new HomeOrderStatistical();

        // 整理出时间数据
        LocalDate start = LocalDate.parse(search.getStartDate());
        Date startTime = Date.from(start.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
        LocalDate end = LocalDate.parse(search.getEndDate());
        LocalDateTime localDateTime = end.plusDays(1).atStartOfDay();
        Date endTime = Date.from( localDateTime.plusSeconds(-1).atZone(ZoneId.systemDefault()).toInstant());

        // 查询每天的订单数据
        List<OrderStatistical> orderStatistical = orderDao
                .selectOrderCountAndAmount(startTime, endTime, OrderStatisticalEnum.DAY.name());

        Map<String, List<OrderStatistical>> map = orderStatistical.stream()
                                      .collect(Collectors.groupingBy(OrderStatistical::getDate));

        // 整理统计数据
        List<OrderStatistical> statisticalList = new ArrayList<>();
        while (start.compareTo(end) <=0) {
            String date = start.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            OrderStatistical statisticalInfo = getOrderStatistical(map, date);
            statisticalList.add(statisticalInfo);
            start = start.plusDays(1);
        }
        homeOrderStatistical.setOrderStatisticalList(statisticalList);

        // 本月订单

        LocalDate now = LocalDate.now();
        endTime =  Date.from( now.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
        startTime = Date.from( now.plusMonths(-1).atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
        // 查询统计数据
        orderStatistical = orderDao.selectOrderCountAndAmount(startTime, endTime, OrderStatisticalEnum.MONTH.name());

        map = orderStatistical.stream().collect(Collectors.groupingBy(OrderStatistical::getDate));

        // 本月订单统计数据
        String date = DateUtil.format(endTime, "yyyy-MM");
        OrderStatistical statistical = getOrderStatistical(map, date);
        homeOrderStatistical.setMonthOrderAmount(statistical.getOrderAmount());
        homeOrderStatistical.setMonthOrderCount(statistical.getOrderNum());

        // 上月订单统计数据
        date = DateUtil.format(startTime, "yyyy-MM");
        statistical = getOrderStatistical(map, date);

        // 月 同比 金额
        homeOrderStatistical.setMonthOrderAmountProportion(getProportion(homeOrderStatistical.getMonthOrderAmount(),
                                                                         statistical.getOrderAmount()));
        // 月同比 数量
        homeOrderStatistical.setMonthOrderCountProportion(getProportion(new BigDecimal(homeOrderStatistical.getMonthOrderCount()),
                                                          new BigDecimal(statistical.getOrderNum())));

        // 周数据
        startTime = Date.from( now.plusDays(-7).atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());

        // 查询统计数据
        orderStatistical = orderDao.selectOrderCountAndAmount(startTime, endTime, OrderStatisticalEnum.WEEK.name());

        map = orderStatistical.stream().collect(Collectors.groupingBy(obj -> obj.getDate().substring(4)));

        // 本周订单统计数据
        WeekFields weekFields = WeekFields.ISO;
        int i = now.get(weekFields.weekOfWeekBasedYear());
        if (i <10) {
            date =  "0" + i;
        } else {
            date =  "" + i;
        }
        statistical = getOrderStatistical(map, date);
        homeOrderStatistical.setWeekOrderAmount(statistical.getOrderAmount());
        homeOrderStatistical.setWeekOrderCount(statistical.getOrderNum());

        // 上周订单统计数据
        i = now.plusDays(-7).get(weekFields.weekOfWeekBasedYear());
        if (i <10) {
            date =  "0" + i;
        } else {
            date =  "" + i;
        }
        statistical = getOrderStatistical(map, date);

        // 月 同比 金额
        homeOrderStatistical.setWeekOrderAmountProportion(getProportion(homeOrderStatistical.getWeekOrderAmount(),
                                                                         statistical.getOrderAmount()));
        // 月同比 数量
        homeOrderStatistical.setWeekOrderCountProportion(getProportion(new BigDecimal(homeOrderStatistical.getWeekOrderCount()),
                                                                        new BigDecimal(statistical.getOrderNum())));
        return homeOrderStatistical;

    }

    private Integer getProportion(BigDecimal now, BigDecimal last) {
        if (now.compareTo(BigDecimal.ZERO) == 0) {
            if(last.compareTo(BigDecimal.ZERO) == 0) {
                return 0;
            }  else {
                return -100;
            }
        } else {
            if(last.compareTo(BigDecimal.ZERO) == 0) {
                return 100;
            }  else {
                double monthAmount = now.doubleValue();
                double lastMonthAmount =last.doubleValue();
                double v = 100 * (monthAmount / lastMonthAmount - 1);
                return Double.valueOf(v).intValue();
            }
        }
    }

    private OrderStatistical getOrderStatistical(Map<String, List<OrderStatistical>> map, String date) {
        OrderStatistical statisticalInfo = new OrderStatistical();
        statisticalInfo.setDate(date);
        List<OrderStatistical> orderStatisticals = map.get(date);
        if (CollectionUtils.isEmpty(orderStatisticals)) {
            statisticalInfo.setOrderAmount(BigDecimal.ZERO);
            statisticalInfo.setOrderNum(0);
        } else {
            statisticalInfo.setOrderAmount(orderStatisticals.get(0).getOrderAmount());
            statisticalInfo.setOrderNum(orderStatisticals.get(0).getOrderNum());
        }
        return statisticalInfo;
    }
}
