package com.fjhx.victoriatourist.service.order.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.area.utils.CustomizeAreaUtil;
import com.fjhx.common.utils.Assert;
import com.fjhx.customer.entity.customer.po.Customer;
import com.fjhx.customer.service.customer.CustomerService;
import com.fjhx.item.service.product.ProductInfoService;
import com.fjhx.victoriatourist.entity.logistics.po.LogisticsDetails;
import com.fjhx.victoriatourist.entity.logistics.po.LogisticsInfos;
import com.fjhx.victoriatourist.entity.order.dto.OrderInfoDto;
import com.fjhx.victoriatourist.entity.order.dto.OrderInfoSelectDto;
import com.fjhx.victoriatourist.entity.order.po.OrderDetails;
import com.fjhx.victoriatourist.entity.order.po.OrderInfo;
import com.fjhx.victoriatourist.entity.order.vo.OrderDetailsVo;
import com.fjhx.victoriatourist.entity.order.vo.OrderInfoVo;
import com.fjhx.victoriatourist.mapper.order.OrderInfoMapper;
import com.fjhx.victoriatourist.service.logistics.LogisticsDetailsService;
import com.fjhx.victoriatourist.service.logistics.LogisticsInfosService;
import com.fjhx.victoriatourist.service.order.OrderDetailsService;
import com.fjhx.victoriatourist.service.order.OrderInfoService;
import com.fjhx.victoriatourist.utils.CodeEnum;
import com.fjhx.wms.entity.stock.dto.StockWaitDetailsDto;
import com.fjhx.wms.entity.stock.dto.StockWaitDto;
import com.fjhx.wms.entity.stock.emums.StockWaitType;
import com.fjhx.wms.entity.stock.po.StockWait;
import com.fjhx.wms.entity.stock.po.StockWaitDetails;
import com.fjhx.wms.service.stock.StockWaitDetailsService;
import com.fjhx.wms.service.stock.StockWaitService;
import com.ruoyi.common.utils.wrapper.IWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * <p>
 * 订单 服务实现类
 * </p>
 *
 * @author
 * @since 2023-04-17
 */
@Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {
    @Autowired
    private CustomerService customerService;
    @Autowired
    private OrderDetailsService orderDetailsService;
    @Autowired
    private ProductInfoService productInfoService;
    @Autowired
    private StockWaitService stockWaitService;
    @Autowired
    private StockWaitDetailsService stockWaitDetailsService;

    @Autowired
    private LogisticsInfosService logisticsInfosService;
    @Autowired
    private LogisticsDetailsService logisticsDetailsService;

    @Override
    public Page<OrderInfoVo> getPage(OrderInfoSelectDto dto) {
        IWrapper<OrderInfo> wrapper = getWrapper();
        wrapper.like(OrderInfo::getCode, dto.getKeyword());
        wrapper.eq("oi", OrderInfo::getType, dto.getType());
        wrapper.eq("oi", OrderInfo::getStatus, dto.getStatus());//根据状态过滤
        wrapper.orderByDesc("oi", OrderInfo::getId);
        Page<OrderInfoVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
        List<OrderInfoVo> records = page.getRecords();
        if (ObjectUtil.isEmpty(records)) {
            return page;
        }
        //赋值客户名称
        customerService.attributeAssign(records, OrderInfoVo::getCustomerInfoId, (item, customerInfo) -> {
            item.setCustomerName(customerInfo.getName());
        });
        //赋值赋值国省市
        CustomizeAreaUtil.setAreaName(records);
        return page;
    }

    @Override
    public OrderInfoVo detail(Long id) {
        OrderInfo OrderInfo = this.getById(id);
        OrderInfoVo result = BeanUtil.toBean(OrderInfo, OrderInfoVo.class);
        //赋值客户名称
        Customer customer = customerService.getById(result.getCustomerInfoId());
        if (ObjectUtil.isNotEmpty(customer)) {
            result.setCustomerName(customer.getName());
        }
        //赋值赋值国省市
        CustomizeAreaUtil.setAreaName(result);
        //赋值明细
        List<OrderDetails> list = orderDetailsService.list(q -> q.eq(OrderDetails::getOrderId, result.getId()));
        List<OrderDetailsVo> orderDetailsVoList = BeanUtil.copyToList(list, OrderDetailsVo.class);
        //给明细赋值产品信息
        productInfoService.attributeAssign(orderDetailsVoList, OrderDetails::getProductId, (item, productInfo) -> {
            item.setProductCode(productInfo.getCode());
            item.setProductName(productInfo.getName());
            item.setProductUnit(productInfo.getUnit());
        });
        result.setOrderDetailsList(orderDetailsVoList);
        return result;
    }

    @DSTransactional
    @Override
    public void add(OrderInfoDto orderInfoDto) {
        // 订单明细
        List<OrderDetails> orderDetailsList = orderInfoDto.getOrderDetailsList();
        Assert.notEmpty(orderDetailsList, "订单明细不能为空");

        // 订单时间
        orderInfoDto.setOrderTime(ObjectUtil.defaultIfNull(orderInfoDto.getOrderTime(), new Date()));

        // 统计订单金额
        BigDecimal amountMoney = orderDetailsList.stream()
                .map(item -> item.getPrice().multiply(item.getQuantity())).reduce(BigDecimal.ZERO, BigDecimal::add);
        orderInfoDto.setAmountMoney(amountMoney);

        orderInfoDto.setStatus(1);
        orderInfoDto.setIssueStatus(1);

        synchronized (this) {
//            if (type == 3) {
//                orderInfoDto.setCode(CodeEnum.ORDER_JD.getCode(orderInfoDto.getCode()));
//            } else {
            orderInfoDto.setCode(CodeEnum.ORDER_SALES.getCode(orderInfoDto.getCode()));
//            }
            this.save(orderInfoDto);
        }


        // 添加订单明细
        for (OrderDetails orderDetails : orderDetailsList) {
            orderDetails.setOrderId(orderInfoDto.getId());
            orderDetails.setNotIssuedQuantity(orderDetails.getQuantity());
        }
        orderDetailsService.saveBatch(orderDetailsList);


        //添加待出库记录
        StockWait stockWait = new StockWait();
        stockWait.setType(2);//待出库
        stockWait.setBusinessType(StockWaitType.SALE_ORDER_OUT.getDetailType());
        stockWait.setBusinessId(orderInfoDto.getId());
        stockWait.setBusinessCode(orderInfoDto.getCode());
        stockWait.setStatus(0);//待出库
        stockWaitService.save(stockWait);
        //创建待出库明细
        List<StockWaitDetails> stockWaitDetailsList = new ArrayList<>();
        for (OrderDetails orderDetails : orderDetailsList) {
            StockWaitDetails stockWaitDetails = new StockWaitDetails();
            stockWaitDetails.setStockWaitId(stockWait.getId());
            stockWaitDetails.setBusinessDetailsId(orderDetails.getId());
            stockWaitDetails.setProductId(orderDetails.getProductId());
            stockWaitDetails.setQuantity(orderDetails.getQuantity());
            stockWaitDetails.setReceiptQuantity(BigDecimal.ZERO);
            stockWaitDetailsList.add(stockWaitDetails);
        }
        stockWaitDetailsService.saveBatch(stockWaitDetailsList);

        CustomizeAreaUtil.setAreaId(orderInfoDto);
    }

    @DSTransactional
    @Override
    public void edit(OrderInfoDto orderInfoDto) {
        this.updateById(orderInfoDto);
        if (orderInfoDto.getStatus() == 3 || orderInfoDto.getStatus() == 2) {
            List<StockWait> list = stockWaitService.list(q -> q.eq(StockWait::getBusinessId, orderInfoDto.getId()));
            for (StockWait stockWait : list) {
                stockWait.setStatus(2);
            }
            stockWaitService.updateBatchById(list);
        }


        CustomizeAreaUtil.setAreaId(orderInfoDto);
    }

    @Override
    public void delete(Long id) {
        this.removeById(id);
    }

    /**
     * 销售订单待出库出库
     */
    @DSTransactional
    @Override
    public void outbound(StockWaitDetailsDto stockWaitDetailsDto) {
        //操作销售订单
        StockWaitDetails stockWaitDetails = stockWaitDetailsService.getById(stockWaitDetailsDto.getId());
        OrderDetails orderDetails = orderDetailsService.getById(stockWaitDetails.getBusinessDetailsId());
        //减少未出库数量
        orderDetails.setNotIssuedQuantity(orderDetails.getNotIssuedQuantity().subtract(stockWaitDetailsDto.getQuantity()));
        orderDetailsService.updateById(orderDetails);
        //修改销售订单状态
        int statusFlag = 0;
        List<OrderDetails> orderDetailsList = orderDetailsService.list(q -> q.eq(OrderDetails::getOrderId, orderDetails.getOrderId()));
        for (OrderDetails details : orderDetailsList) {
            //统计已经完全出库的条数
            if (details.getNotIssuedQuantity().compareTo(BigDecimal.ZERO) <= 0) {
                statusFlag++;
            }
        }
        OrderInfo orderInfo = getById(orderDetails.getOrderId());
        if (statusFlag == orderDetailsList.size()) {
            //完全出库
            orderInfo.setStatus(2);//订单状态 1进行中 2已完成 3已取消
            orderInfo.setIssueStatus(3);//出库状态 1未出库 2进行中 3已出库
        } else {
            //部分出库
            orderInfo.setStatus(1);//订单状态 1进行中 2已完成 3已取消
            orderInfo.setIssueStatus(2);//出库状态 1未出库 2进行中 3已出库
        }
        updateById(orderInfo);

        //创建物流数据
        LogisticsInfos logisticsInfos = new LogisticsInfos();
        logisticsInfos.setBusinessId(orderInfo.getId());
        logisticsInfos.setBusinessCode(orderInfo.getCode());
        logisticsInfos.setBusinessType(3);//销售订单出库
        logisticsInfos.setLogisticsCompanyCode(stockWaitDetailsDto.getLogisticsCompanyCode());
        logisticsInfos.setCode(stockWaitDetailsDto.getLogisticsCode());
        logisticsInfos.setWarehouseId(stockWaitDetailsDto.getWarehouseId());
        logisticsInfos.setIsKd100(0);
        logisticsInfosService.save(logisticsInfos);

        LogisticsDetails logisticsDetails = new LogisticsDetails();
        logisticsDetails.setLogisticsInfoId(logisticsInfos.getId());
        logisticsDetails.setLogisticsInfoCode(logisticsInfos.getCode());
        logisticsDetails.setBusinessDetailsId(orderDetails.getId());
        logisticsDetails.setReceiptQuantity(orderDetails.getQuantity());
        logisticsDetailsService.save(logisticsDetails);
    }

    @DSTransactional
    @Override
    public void outbounds(StockWaitDto stockWaitDto) {
        Assert.notEmpty(stockWaitDto.getId(), "待出库id不能为空");
        StockWait stockWait = stockWaitService.getById(stockWaitDto.getId());

        //创建物流数据
        LogisticsInfos logisticsInfos = new LogisticsInfos();
        logisticsInfos.setBusinessId(stockWait.getBusinessId());
        logisticsInfos.setBusinessCode(stockWait.getBusinessCode());
        logisticsInfos.setBusinessType(3);//销售订单出库
        logisticsInfos.setLogisticsCompanyCode(stockWaitDto.getLogisticsCompanyCode());
        logisticsInfos.setCode(stockWaitDto.getLogisticsCode());
        logisticsInfos.setWarehouseId(stockWaitDto.getWarehouseId());
        logisticsInfos.setIsKd100(0);
        logisticsInfosService.save(logisticsInfos);

        List<StockWaitDetails> stockWaitDetailsList = stockWaitDto.getStockWaitDetailsList();


        List<LogisticsDetails> logisticsDetailsList = new ArrayList<>();

        for (StockWaitDetails stockWaitDetailsDto : stockWaitDetailsList) {
            Assert.notEmpty(stockWaitDetailsDto.getId(), "待出库明细id不能为空");
            //操作销售订单
            StockWaitDetails stockWaitDetails = stockWaitDetailsService.getById(stockWaitDetailsDto.getId());
            OrderDetails orderDetails = orderDetailsService.getById(stockWaitDetails.getBusinessDetailsId());
            //减少未出库数量
            orderDetails.setNotIssuedQuantity(orderDetails.getNotIssuedQuantity().subtract(stockWaitDetailsDto.getQuantity()));
            orderDetailsService.updateById(orderDetails);

            LogisticsDetails logisticsDetails = new LogisticsDetails();
            logisticsDetails.setLogisticsInfoId(logisticsInfos.getId());
            logisticsDetails.setLogisticsInfoCode(logisticsInfos.getCode());
            logisticsDetails.setBusinessDetailsId(orderDetails.getId());
            logisticsDetails.setReceiptQuantity(orderDetails.getQuantity());
            logisticsDetailsList.add(logisticsDetails);
        }
        logisticsDetailsService.saveBatch(logisticsDetailsList);

        //修改销售订单状态
        OrderInfo orderInfo = getById(stockWaitDto.getBusinessId());
        Assert.notEmpty(orderInfo, "查询不到订单信息");
        int statusFlag = 0;
        List<OrderDetails> orderDetailsList = orderDetailsService.list(q -> q.eq(OrderDetails::getOrderId, orderInfo.getId()));
        for (OrderDetails details : orderDetailsList) {
            //统计已经完全出库的条数
            if (details.getNotIssuedQuantity().compareTo(BigDecimal.ZERO) <= 0) {
                statusFlag++;
            }
        }
        if (statusFlag == orderDetailsList.size()) {
            //完全出库
            orderInfo.setStatus(2);//订单状态 1进行中 2已完成 3已取消
            orderInfo.setIssueStatus(3);//出库状态 1未出库 2进行中 3已出库
        } else {
            //部分出库
            orderInfo.setStatus(1);//订单状态 1进行中 2已完成 3已取消
            orderInfo.setIssueStatus(2);//出库状态 1未出库 2进行中 3已出库
        }
        updateById(orderInfo);
    }


}
