package com.xmomen.module.receipt.service;
// 声明该Java类所在的包路径，com.xmomen.module.receipt.service表示该类位于名为service的包中，
// 这个包是com.xmomen.module.receipt包的子包
import java.math.BigDecimal;
// 导入用于精确的十进制运算的类
import java.util.Date;
// 导入表示日期和时间的类
import java.util.HashMap;
// 导入一种键值对存储的数据结构类
import java.util.List;
// 导入用于表示有序的元素集合的接口
import java.util.Map;
// 导入用于表示键值对的映射关系的接口

import com.xmomen.framework.exception.BusinessException;
// 导入自定义的业务异常类
import com.xmomen.module.base.entity.CdItem;
// 导入基础模块中的商品实体类
import com.xmomen.module.order.entity.*;
// 导入订单模块的所有实体类
import com.xmomen.module.stock.service.StockService;
// 导入库存服务类
import org.apache.shiro.SecurityUtils;
// 导入Apache Shiro框架中用于处理安全相关操作的工具类
import org.springframework.beans.factory.annotation.Autowired;
// 导入Spring框架用于自动装配依赖的注解
import org.springframework.stereotype.Service;
// 导入Spring框架用于标记服务类的注解
import org.springframework.transaction.annotation.Transactional;
// 导入Spring框架用于声明事务的注解

import com.xmomen.framework.mybatis.dao.MybatisDao;
// 导入自定义的MyBatis数据访问对象类
import com.xmomen.framework.mybatis.page.Page;
// 导入用于分页操作的类
import com.xmomen.framework.utils.AssertExt;
// 导入自定义的断言工具类
import com.xmomen.framework.utils.StringUtilsExt;
// 导入自定义的字符串工具类
import com.xmomen.module.base.constant.AppConstants;
// 导入应用程序的常量类
import com.xmomen.module.base.entity.CdExpress;
// 导入基础模块中的快递实体类
import com.xmomen.module.base.service.ItemService;
// 导入商品服务类
import com.xmomen.module.order.mapper.OrderMapper;
// 导入订单模块的Mapper接口
import com.xmomen.module.order.model.ReturnOrder;
// 导入订单模块的退货订单模型类
import com.xmomen.module.receipt.mapper.ReturnOrderMapper;
// 导入退货订单模块的Mapper接口
import com.xmomen.module.receipt.model.ReturnOrderModel;
// 导入退货订单模块的模型类
import com.xmomen.module.receipt.model.ReturnOrderQuery;
// 导入退货订单模块的查询条件类
import com.xmomen.module.wx.model.AjaxResult;
// 导入微信模块的Ajax结果模型类

@Service
// 使用@Service注解将ReturnOrderService类标记为一个Spring服务类
public class ReturnOrderService {

    @Autowired
    // 使用@Autowired注解自动装配MybatisDao类型的对象
    MybatisDao mybatisDao;

    @Autowired
    // 使用@Autowired注解自动装配ItemService类型的对象
    ItemService itemService;

    @Autowired
    // 使用@Autowired注解自动装配StockService类型的对象
    StockService stockService;

    // 获取退货订单列表
    public Page<ReturnOrderModel> getReturnOrderList(
            ReturnOrderQuery orderQuery, Integer limit, Integer offset) {
        // 该方法用于获取退货订单列表并进行分页，接受查询条件对象orderQuery以及分页参数limit和offset
        return (Page<ReturnOrderModel>) mybatisDao.selectPage(
                ReturnOrderMapper.RETURN_ORDER_MAPPER_NAMESPACE
                        + "getReturnOrderList", orderQuery, limit, offset);
        // 调用mybatisDao的selectPage方法，通过ReturnOrderMapper的命名空间和方法名执行查询，返回分页结果
    }

    // 获取退货订单列表
    public List<ReturnOrderModel> getReturnOrderList(ReturnOrderQuery orderQuery) {
        // 这是一个重载的方法，用于获取退货订单列表（不进行分页），接受查询条件对象orderQuery
        return mybatisDao.getSqlSessionTemplate().selectList(
                ReturnOrderMapper.RETURN_ORDER_MAPPER_NAMESPACE
                        + "getReturnOrderList", orderQuery);
        // 调用mybatisDao的getSqlSessionTemplate方法获取SqlSessionTemplate，
        // 然后通过ReturnOrderMapper的命名空间和方法名执行查询，返回结果列表
    }

    // 拒绝收货
    @Transactional
    // 使用@Transactional注解声明该方法在一个事务中执行
    public AjaxResult noShouhuo(String orderNo, String phone, int expressId) {
        // 该方法用于处理拒绝收货的业务逻辑，接受订单号orderNo、联系电话phone和快递员ID expressId，返回AjaxResult对象
        AjaxResult ajaxResult = new AjaxResult();
        // 创建一个新的AjaxResult对象，用于封装返回给前端的结果信息

        // 判断订单状态
        TbReturnOrderExample tbOrderExample = new TbReturnOrderExample();
        // 创建一个TbReturnOrderExample对象用于构建查询条件
        tbOrderExample.createCriteria().andOrderNoEqualTo(orderNo);
        // 添加订单号等于orderNo的条件
        TbReturnOrder tbReturnOrder = mybatisDao
                .selectOneByExample(tbOrderExample);
        // 调用mybatisDao的selectOneByExample方法查询符合条件的单个TbReturnOrder对象，以判断订单状态

        if (tbReturnOrder != null) {
            ajaxResult.setMessage("订单不能拒绝，请联系客服人员。");
            // 如果订单已存在某种状态，设置ajaxResult的消息
            ajaxResult.setResult(0);
            // 设置ajaxResult的结果码为0
            return ajaxResult;
            // 返回ajaxResult对象
        }
        tbReturnOrder = new TbReturnOrder();
        // 创建一个新的TbReturnOrder对象
        tbReturnOrder.setOrderNo(orderNo);
        // 设置订单号
        // 退货运输中
        tbReturnOrder.setReturnStatus(14);
        // 设置退货状态为“退货运输中”（状态码14）
        tbReturnOrder.setTakeGoodsDate(mybatisDao.getSysdate());
        // 设置取货日期为系统当前日期
        tbReturnOrder.setTakeGoodsPhone(phone);
        // 设置取货联系电话
        tbReturnOrder.setTakeGoodsUserId(expressId);
        // 设置取货的快递员用户ID
        tbReturnOrder.setReturnTime(mybatisDao.getSysdate());
        // 设置退货时间为系统当前日期
        tbReturnOrder = mybatisDao.insertByModel(tbReturnOrder);
        // 调用mybatisDao的insertByModel方法插入新的退货订单记录，并返回插入后的对象

        TbOrderItem orderItemDb = new TbOrderItem();
        // 创建一个TbOrderItem对象
        orderItemDb.setOrderNo(orderNo);
        // 设置订单号
        List<TbOrderItem> returnOrderItems = mybatisDao
                .selectByModel(orderItemDb);
        // 调用mybatisDao的selectByModel方法查询该订单下的所有订单商品项

        BigDecimal returnTotalAmount = BigDecimal.ZERO;
        // 创建一个BigDecimal对象用于记录退货总金额，并初始化为0

        for (TbOrderItem orderItem : returnOrderItems) {
            // 遍历订单商品项列表
            TbReturnOrderItem returnOrderItem = new TbReturnOrderItem();
            // 创建一个新的TbReturnOrderItem对象
            returnOrderItem.setItemCode(orderItem.getItemCode());
            // 设置商品编码
            returnOrderItem.setReturnOrderId(tbReturnOrder.getId());
            // 设置退货订单ID
            returnOrderItem.setItemNumber(orderItem.getItemQty().intValue());
            // 设置商品数量
            returnOrderItem.setItemName(orderItem.getItemName());
            // 设置商品名称
            returnOrderItem.setIsNeed(1);
            // 设置是否需要（这里值为1表示需要）
            mybatisDao.insert(returnOrderItem);
            // 插入退货订单商品项记录

            //金额相加
            returnTotalAmount = returnTotalAmount.add(orderItem.getItemPrice().multiply(orderItem.getItemQty()));
            // 将当前商品项的金额（单价乘以数量）累加到退货总金额中
        }
        //退款金额
        tbReturnOrder.setReturnTotalAmount(returnTotalAmount);
        // 设置退货订单的退款总金额

        // 更新原订单状态
        TbOrderExample orderExample = new TbOrderExample();
        // 创建一个TbOrderExample对象用于构建查询条件
        orderExample.createCriteria().andOrderNoEqualTo(orderNo);
        // 添加订单号等于orderNo的条件
        TbOrder order = new TbOrder();
        // 创建一个新的TbOrder对象
        //是拒绝收货
        order.setIsReject(1);
        // 设置订单为拒绝收货状态（值为1表示拒绝）
        // 退货运输中
        order.setOrderStatus("14");
        // 设置订单状态为“退货运输中”（状态码14）
        mybatisDao.updateOneByExampleSelective(order, orderExample);
        // 调用mybatisDao的updateOneByExampleSelective方法更新原订单的状态

        ajaxResult.setMessage("订单已拒收，请及时送回仓库。");
        // 设置ajaxResult的消息
        ajaxResult.setResult(1);
        // 设置ajaxResult的结果码为1
        return ajaxResult;
        // 返回ajaxResult对象
    }

    @Transactional
    // 使用@Transactional注解声明该方法在一个事务中执行
    public AjaxResult returnOrder(String orderNo, String itemIds) {
        // 该方法用于处理退货申请的业务逻辑，接受订单号orderNo和商品ID字符串itemIds，返回AjaxResult对象
        AjaxResult ajaxResult = new AjaxResult();
        // 创建一个新的AjaxResult对象，用于封装返回给前端的结果信息

        // 判断订单状态
        TbReturnOrderExample tbOrderExample = new TbReturnOrderExample();
        // 创建一个TbReturnOrderExample对象用于构建查询条件
        tbOrderExample.createCriteria().andOrderNoEqualTo(orderNo);
        // 添加订单号等于orderNo的条件
        TbReturnOrder tbReturnOrder = mybatisDao
                .selectOneByExample(tbOrderExample);
        // 调用mybatisDao的selectOneByExample方法查询符合条件的单个TbReturnOrder对象，以判断订单状态

        if (tbReturnOrder != null) {
            ajaxResult.setMessage("订单不能退货，请联系客服人员。");
            // 如果订单已存在某种状态，设置ajaxResult的消息
            ajaxResult.setResult(0);
            // 设置ajaxResult的结果码为0
            return ajaxResult;
            // 返回ajaxResult对象
        }
        tbReturnOrder = new TbReturnOrder();
        // 创建一个新的TbReturnOrder对象
        tbReturnOrder.setOrderNo(orderNo);
        // 设置订单号
        tbReturnOrder.setReturnStatus(10);// 申请退货
        // 设置退货状态为“申请退货”（状态码10）
        tbReturnOrder.setReturnTime(mybatisDao.getSysdate());
        // 设置退货时间为系统当前日期
        tbReturnOrder = mybatisDao.insertByModel(tbReturnOrder);
        // 调用mybatisDao的insertByModel方法插入新的退货订单记录，并返回插入后的对象

        BigDecimal returnTotalAmount = BigDecimal.ZERO;
        // 创建一个BigDecimal对象用于记录退货总金额，并初始化为0

        for (String itemId : itemIds.split(",")) {
            // 遍历商品ID字符串，以逗号分割
            if (StringUtilsExt.isEmpty(itemId)) {
                continue;
                // 如果商品ID为空，跳过本次循环
            }
            TbReturnOrderItem returnOrderItem = new TbReturnOrderItem();
            // 创建一个新的TbReturnOrderItem对象
            TbOrderItem orderItem = this.mybatisDao.selectByPrimaryKey(
                    TbOrderItem.class, Integer.parseInt(itemId));
            // 根据商品ID查询对应的订单商品项

            returnOrderItem.setItemCode(orderItem.getItemCode());
            // 设置商品编码
            returnOrderItem.setReturnOrderId(tbReturnOrder.getId());
            // 设置退货订单ID
            returnOrderItem.setItemNumber(orderItem.getItemQty().intValue());
            // 设置商品数量
            returnOrderItem.setItemName(orderItem.getItemName());
            // 设置商品名称
            returnOrderItem.setIsNeed(1);
            // 设置是否需要（这里值为1表示需要）
            mybatisDao.insert(returnOrderItem);
            // 插入退货订单商品项记录

            //金额相加
            returnTotalAmount = returnTotalAmount.add(orderItem.getItemPrice().multiply(orderItem.getItemQty()));
            // 将当前商品项的金额（单价乘以数量）累加到退货总金额中
        }
        //退款金额
        tbReturnOrder.setReturnTotalAmount(returnTotalAmount);
        // 设置退货订单的退款总金额

        mybatisDao.update(tbReturnOrder);
        // 调用mybatisDao的update方法更新退货订单记录

        // 更新原订单状态
        TbOrderExample orderExample = new TbOrderExample();
        // 创建一个TbOrderExample对象用于构建查询条件
        orderExample.createCriteria().andOrderNoEqualTo(orderNo);
        // 添加订单号等于orderNo的条件
        TbOrder order = new TbOrder();
        // 创建一个新的TbOrder对象
        order.setOrderStatus("10");// 申请退货
        // 设置订单状态为“申请退货”（状态码10）
        mybatisDao.updateOneByExampleSelective(order, orderExample);
        // 调用mybatisDao的updateOneByExampleSelective方法更新原订单的状态

        ajaxResult.setMessage("退货申请提交成功，请等待客服审核。");
        // 设置ajaxResult的消息
        ajaxResult.setResult(1);
        // 设置ajaxResult的结果码为1
        return ajaxResult;
        // 返回ajaxResult对象
    }

    @Transactional
    // 使用@Transactional注解声明该方法在一个事务中执行
    public AjaxResult shouhuoReturn(String orderNo, String phone, int expressId) {
        // 该方法用于处理退货收货的业务逻辑，接受订单号orderNo、联系电话phone和快递员ID expressId，返回AjaxResult对象
        AjaxResult ajaxResult = new AjaxResult();
        // 创建一个新的AjaxResult对象，用于封装返回给前端的结果信息

        // 判断订单状态
        TbReturnOrderExample tbOrderExample = new TbReturnOrderExample();
        // 创建一个TbReturnOrderExample对象用于构建查询条件
        tbOrderExample.createCriteria().andOrderNoEqualTo(orderNo);
        // 添加订单号等于orderNo的条件
        TbReturnOrder tbReturnOrder = mybatisDao
                .selectOneByExample(tbOrderExample);
        // 调用mybatisDao的selectOneByExample方法查询符合条件的单个TbReturnOrder对象，以判断订单状态

        if (tbReturnOrder.getReturnStatus() != 11) {
            ajaxResult.setMessage("订单状态不为退货中，不能收货，请联系客服人员。");
            // 如果订单的退货状态不是“退货中”（状态码11），设置ajaxResult的消息
            ajaxResult.setResult(0);
            // 设置ajaxResult的结果码为0
            return ajaxResult;
            // 返回ajaxResult对象
        }
        tbReturnOrder.setReturnStatus(14);// 退货运输中
        // 设置退货订单的状态为“退货运输中”（状态码14）
        tbReturnOrder.setTakeGoodsDate(mybatisDao.getSysdate());
        // 设置取货日期为系统当前日期
        tbReturnOrder.setTakeGoodsPhone(phone);
        // 设置取货联系电话
        tbReturnOrder.setTakeGoodsUserId(expressId);
        // 设置取货的快递员用户ID
        mybatisDao.update(tbReturnOrder);
        // 调用mybatisDao的update方法更新退货订单记录

        // 更新原订单状态
        TbOrderExample orderExample = new TbOrderExample();
        // 创建一个TbOrderExample对象用于构建查询条件
        orderExample.createCriteria().andOrderNoEqualTo(orderNo);
        // 添加订单号等于orderNo的条件
        TbOrder order = new TbOrder();
        // 创建一个新的TbOrder对象
        order.setOrderStatus("14");// 退货运输中
        // 设置订单状态为“退货运输中”（状态码14）
        mybatisDao.updateOneByExampleSelective(order, orderExample);
        // 调用mybatisDao的updateOneByExampleSelective方法更新原订单的状态

        ajaxResult.setMessage("退货订单收货成功，请尽快送回仓库。");
        // 设置ajaxResult的消息
        ajaxResult.setResult(0);
        // 设置ajaxResult的结果码为0
        return ajaxResult;
        // 返回ajaxResult对象
    }

    @Transactional
    // 使用@Transactional注解声明该方法在一个事务中执行
    public void auditReturnOrder(int id, int statusCd) {
        // 该方法用于审核退货订单，接受退货订单ID id和审核状态码statusCd
        TbReturnOrder returnOrder = this.mybatisDao.selectByPrimaryKey(
                TbReturnOrder.class, id);
        // 根据退货订单ID查询对应的TbReturnOrder对象

        returnOrder.setAuditStatus(statusCd);
        // 设置审核状态
        returnOrder.setAuditDate(mybatisDao.getSysdate());
        // 设置审核日期为系统当前日期

        if (statusCd == 1) {
            // 如果审核状态码为1（表示通过审核）
            // 退货中
            returnOrder.setReturnStatus(11);
            // 设置退货订单的状态为“退货中”（状态码1