package com.leromro.core.service.impl;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.Update;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leromro.common.core.domain.AjaxResult;
import com.leromro.common.utils.SecurityUtils;
import com.leromro.core.domain.*;
import com.leromro.core.domain.vo.OrderRefundVO;
import com.leromro.core.domain.vo.WebOrderRefundVO;
import com.leromro.core.mapper.*;
import com.leromro.core.utils.DateTimeUtil;
import org.apache.commons.math3.stat.inference.OneWayAnova;
import org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent.FutureOrPresentValidatorForReadableInstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.leromro.core.service.IOrderRefundService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 订单取消/退款Service业务层处理
 *
 * @author ruoyi
 * @date 2025-04-21
 */

@Service
public class OrderRefundServiceImpl extends ServiceImpl<OrderRefundMapper, OrderRefund> implements IOrderRefundService {
    @Autowired
    private OrderRefundMapper lOrderRefundMapper;
    @Autowired
    private SecondOrdersMapper secondOrdersMapper;
    @Autowired
    private PlatformFinanceMapper platformFinanceMapper;
    @Autowired
    private ClientAccountMapper clientAccountMapper;
    @Autowired
    private VolunteerReservationTimeMapper reservationTimeMapper;
    @Autowired
    private VolunteerWorkDateMapper workDateMapper;
    @Autowired
    private MainOrdersMapper mainOrdersMapper;

    /**
     * 查询订单取消/退款
     *
     * @param orderRefundId 订单取消/退款主键
     * @return 订单取消/退款
     */
    @Override
    public OrderRefund selectLOrderRefundByOrderRefundId(Long orderRefundId) {
        return lOrderRefundMapper.selectLOrderRefundByOrderRefundId(orderRefundId);
    }

    /**
     * 查询订单取消/退款列表
     *
     * @param orderRefund 订单取消/退款
     * @return 订单取消/退款
     */
    @Override
    public List<OrderRefund> selectLOrderRefundList(OrderRefund orderRefund) {
        return lOrderRefundMapper.selectLOrderRefundList(orderRefund);
    }

    /**
     * 新增订单取消/退款
     *
     * @param orderRefund 订单取消/退款
     * @return 结果
     */
    @Override
    @Transactional
    public AjaxResult insertLOrderRefund(OrderRefund orderRefund) {
        //如果订单，一次都没完成，那就直接不用审批，直接退。
        Long mainOrderId = orderRefund.getMainOrderId();
        //先查订单
        QueryWrapper<MainOrders> mainOrdersQueryWrapper = new QueryWrapper<MainOrders>().eq("main_order_id", mainOrderId);
        MainOrders mainOrders = mainOrdersMapper.selectOne(mainOrdersQueryWrapper);
        BigDecimal totalPrice = mainOrders.getServiceTotalPrice();
        orderRefund.setUserId(SecurityUtils.getUserId());
        orderRefund.setVolunteerId(mainOrders.getVolunteerId());
        //如果这个订单状态为1 (已支付) 未开始  可以直接退款
        if (mainOrders.getOrderStatus().equals("1")) {
            //查询小订单表
            QueryWrapper<SecondOrder> secondOrderQueryWrapper = new QueryWrapper<SecondOrder>().eq("main_order_id", mainOrderId);
            List<SecondOrder> secondOrderList = secondOrdersMapper.selectList(secondOrderQueryWrapper);
            //修改志愿者工作时间表
            List<VolunteerReservationTime> volunteerReservationTimeList = secondOrderList.stream().map(secondOrder -> {
                new VolunteerReservationTime();
                return VolunteerReservationTime.builder().volunteerId(secondOrder.getVolunteerId()).reservationDate(secondOrder.getWorkDate()).reservationTime(secondOrder.getWorkStartTime()).build();
            }).collect(Collectors.toList());
            reservationTimeMapper.deleteVolunteerReservationTimeList(volunteerReservationTimeList);
            //修改状态已取消，用主订单Id
            UpdateWrapper<MainOrders> mainOrderUpdateWrapper = new UpdateWrapper<MainOrders>().eq("main_order_id", mainOrderId).set("order_status", 6);
            mainOrdersMapper.update(null, mainOrderUpdateWrapper);
            //修改，用户账户表 把钱数加上
            UpdateWrapper<ClientAccount> clientAccountUpdateWrapper = new UpdateWrapper<ClientAccount>().eq("user_id", mainOrders.getUserId()).setSql("balance = balance + " + totalPrice);
            clientAccountMapper.update(null,clientAccountUpdateWrapper);
            //平台资金流水表,扣减调总价。
            List<PlatformFinance> platformFinanceList = secondOrderList.stream().map(secondOrder -> {
                new PlatformFinance();
                return PlatformFinance.builder()
                        .changeMoney(secondOrder.getServiceOnePrice()).changeType(0).moneyType(1).sourceType(2).secondOrderId(secondOrder.getSecondOrderId()).volunteerId(secondOrder.getVolunteerId())
                        .build();
            }).collect(Collectors.toList());
            platformFinanceMapper.insertPlatformFinanceList(platformFinanceList);
            //修改，小订单表
            UpdateWrapper<SecondOrder> secondOrderUpdateWrapper = new UpdateWrapper<SecondOrder>().eq("main_order_id", mainOrderId).set("order_status", 2);
            secondOrdersMapper.update(null,secondOrderUpdateWrapper);
            //志愿者预约时间表 还有 修改志愿者工作日的预约状态。
            //先把志愿者预约状态全部设置为0
            UpdateWrapper<VolunteerWorkDate> volunteerWorkDateUpdateWrapper1 = new UpdateWrapper<VolunteerWorkDate>().eq("volunteer_id", mainOrders.getVolunteerId()).set("has_reservation", 0);
            workDateMapper.update(null, volunteerWorkDateUpdateWrapper1);
            //然后在查哪一天有预约，然后再把有的设置为1
            QueryWrapper<VolunteerReservationTime> reservationTimeQueryWrapper = new QueryWrapper<VolunteerReservationTime>().eq("volunteer_id", mainOrders.getVolunteerId());
            List<VolunteerReservationTime> reservationTimes = reservationTimeMapper.selectList(reservationTimeQueryWrapper);
            if (!reservationTimes.isEmpty()){
                List<LocalDate> reservationDate = reservationTimes.stream().map(VolunteerReservationTime::getReservationDate).collect(Collectors.toList());
                UpdateWrapper<VolunteerWorkDate> volunteerWorkDateUpdateWrapper12 = new UpdateWrapper<VolunteerWorkDate>().eq("volunteer_id", mainOrders.getVolunteerId()).in("work_date", reservationDate).set("has_reservation", 1);
                workDateMapper.update(null, volunteerWorkDateUpdateWrapper12);
            }
            //在退款记录标中生成数据，状态为 已退款
            orderRefund.setStatus("2");
            orderRefund.setRefundAmount(totalPrice);
            this.save(orderRefund);
            return AjaxResult.success("钱款将在三个工作日内返回到您的钱包中");
        } else if (mainOrders.getOrderStatus().equals("3")) {
            //订单已开始或者订单已完成
            orderRefund.setStatus("0");
            orderRefund.setRefundAmount(mainOrders.getServiceOnePrice().multiply(new BigDecimal(mainOrders.getTotalTimes() - mainOrders.getFinishTimes())));
            this.save(orderRefund);
            UpdateWrapper<MainOrders> mainOrderUpdateWrapper = new UpdateWrapper<MainOrders>().eq("main_order_id", mainOrderId).set("order_status", 5);
            mainOrdersMapper.update(null, mainOrderUpdateWrapper);
            return AjaxResult.success("已提交申请");
        } else if (mainOrders.getOrderStatus().equals("4") || mainOrders.getOrderStatus().equals("8")) {
            return AjaxResult.success("订单已全部完成，不可退款");
        }else if (mainOrders.getOrderStatus().equals("5")) {
            return AjaxResult.success("订单退款申请正在审核中");
        }else if (mainOrders.getOrderStatus().equals("6") || mainOrders.getOrderStatus().equals("7")) {
            return AjaxResult.success("订单已退款或部分退款，不可重复退款");
        }else if (mainOrders.getOrderStatus().equals("0") || mainOrders.getOrderStatus().equals("2")) {
            return AjaxResult.success("订单未支付或支付失败，不可取消");
        }else{
            return AjaxResult.success("请联系管理员或检查订单状态");
        }

    }

    /**
     * 修改订单取消/退款
     *
     * @param orderRefund 订单取消/退款
     * @return 结果
     */
    @Override
    public Boolean updateLOrderRefund(OrderRefund orderRefund) {
        return this.updateById(orderRefund);
    }

    /**
     * 批量删除订单取消/退款
     *
     * @param orderRefundIds 需要删除的订单取消/退款主键
     * @return 结果
     */
    @Override
    public int deleteLOrderRefundByOrderRefundIds(Long[] orderRefundIds) {
        return lOrderRefundMapper.deleteLOrderRefundByOrderRefundIds(orderRefundIds);
    }

    /**
     * 删除订单取消/退款信息
     *
     * @param orderRefundId 订单取消/退款主键
     * @return 结果
     */
    @Override
    public int deleteLOrderRefundByOrderRefundId(Long orderRefundId) {
        return lOrderRefundMapper.deleteLOrderRefundByOrderRefundId(orderRefundId);
    }

    /**
     * 用户点击退款回显
     *
     * @param mainOrderId
     * @return
     */
    @Override
    public OrderRefundVO selectOrderRefundByMainOrderId(Long mainOrderId) {
        //根据mainID 取出
        OrderRefundVO refundVO = lOrderRefundMapper.selectOrderRefundInfoByMainOrderId(mainOrderId);
        refundVO.setRefundAmount(refundVO.getServiceOnePrice().multiply(new BigDecimal(refundVO.getTotalTimes() - refundVO.getFinishTimes())));

        QueryWrapper<SecondOrder> secondOrderQueryWrapper = new QueryWrapper<SecondOrder>().eq("main_order_id", mainOrderId).eq("order_status", 1);
        List<SecondOrder> secondOrderList = secondOrdersMapper.selectList(secondOrderQueryWrapper);
        refundVO.setSecondOrder(secondOrderList);
        return refundVO;
    }

    /**
     * @param
     */
    @Override
    @Transactional
    public void checkOrderRefund(OrderRefund orderRefund1) {
        //传状态status ,主订单id，同意退款金额
        //只能单独审核
        //先查订单
        OrderRefund orderRefund = lOrderRefundMapper.selectById(orderRefund1.getOrderRefundId());
        //orderRefund.setStatus(orderRefund1.getStatus());

        Long mainOrderId = orderRefund.getMainOrderId();
        QueryWrapper<MainOrders> mainOrdersQueryWrapper = new QueryWrapper<MainOrders>().eq("main_order_id", mainOrderId);
        MainOrders mainOrders = mainOrdersMapper.selectOne(mainOrdersQueryWrapper);
        if (orderRefund.getStatus().equals("2")){
        //更改状态 更改更新时间，更改审批状态、退款钱数、原因、图片。
            orderRefund.setUpdateTime(DateTimeUtil.getNowTime());
        lOrderRefundMapper.updateLOrderRefund(orderRefund);
        //小订单修改状态，并且
        QueryWrapper<SecondOrder> secondOrderQueryWrapper = new QueryWrapper<SecondOrder>().eq("main_order_id", mainOrderId).eq("order_status", 1);
        List<SecondOrder> secondOrderList = secondOrdersMapper.selectList(secondOrderQueryWrapper);
        List<Long> secondOrderIdList = secondOrderList.stream().map(SecondOrder::getSecondOrderId).collect(Collectors.toList());
        UpdateWrapper<SecondOrder> secondOrderUpdateWrapper = new UpdateWrapper<SecondOrder>().in("second_order_id", secondOrderIdList).eq("order_status", 1).set("order_status", 6);
        secondOrdersMapper.update(null, secondOrderUpdateWrapper);
        //根据小订单，删除志愿者预约时间表
        List<VolunteerReservationTime> volunteerReservationTimeList = secondOrderList.stream().map(secondOrder -> {
            new VolunteerReservationTime();
            return VolunteerReservationTime.builder().volunteerId(secondOrder.getVolunteerId()).reservationDate(secondOrder.getWorkDate()).reservationTime(secondOrder.getWorkStartTime()).build();
        }).collect(Collectors.toList());
        reservationTimeMapper.deleteVolunteerReservationTimeList(volunteerReservationTimeList);
        //修改志愿者工作日的预约状态。 1先把志愿者预约状态全部设置为0 然后在查哪一天有预约，然后再把有的设置为1
        UpdateWrapper<VolunteerWorkDate> volunteerWorkDateUpdateWrapper = new UpdateWrapper<VolunteerWorkDate>().eq("volunteer_id", mainOrders.getVolunteerId()).set("has_reservation", 0);
        workDateMapper.update(null, volunteerWorkDateUpdateWrapper);
        QueryWrapper<VolunteerReservationTime> reservationTimeQueryWrapper = new QueryWrapper<VolunteerReservationTime>().eq("volunteer_id", mainOrders.getVolunteerId());
        List<VolunteerReservationTime> reservationTimes = reservationTimeMapper.selectList(reservationTimeQueryWrapper);
        if (!reservationTimes.isEmpty()){
            List<LocalDate> reservationDate = reservationTimes.stream().map(VolunteerReservationTime::getReservationDate).collect(Collectors.toList());
            UpdateWrapper<VolunteerWorkDate> volunteerWorkDateUpdateWrapper1 = new UpdateWrapper<VolunteerWorkDate>().eq("volunteer_id", mainOrders.getVolunteerId()).in("work_date", reservationDate).set("has_reservation", 0);
            workDateMapper.update(null, volunteerWorkDateUpdateWrapper1);
        }
        //向平台流水表更改，减少其中的流水;
        List<PlatformFinance> platformFinanceList = secondOrderList.stream().map(secondOrder -> {
            new PlatformFinance();
            return PlatformFinance.builder()
                    .changeMoney(secondOrder.getServiceOnePrice()).changeType(0).moneyType(1).sourceType(2).secondOrderId(secondOrder.getSecondOrderId()).volunteerId(secondOrder.getVolunteerId())
                    .build();
        }).collect(Collectors.toList());
        platformFinanceMapper.insertPlatformFinanceList(platformFinanceList);
        //恢复用户余额,用户账户表增加钱数
        UpdateWrapper<ClientAccount> clientAccountUpdateWrapper = new UpdateWrapper<ClientAccount>().eq("user_id", mainOrders.getUserId()).setSql("balance = balance + " + orderRefund.getRefundAmount());
        clientAccountMapper.update(null, clientAccountUpdateWrapper);
        //主订单修改状态
        UpdateWrapper<MainOrders> mainOrdersMapperUpdateWrapper = new UpdateWrapper<MainOrders>().eq("main_order_id", mainOrderId).set("order_status", 7);
        mainOrdersMapper.update(null, mainOrdersMapperUpdateWrapper);
        }else if (orderRefund.getStatus().equals("3")){
            orderRefund.setRefundAmount(BigDecimal.valueOf(0));
            orderRefund.setUpdateTime(DateTimeUtil.getNowTime());
            //主订单修改状态 返回之前的状态
            if(mainOrders.getTotalTimes()==mainOrders.getFinishTimes()){
                UpdateWrapper<MainOrders> mainOrdersMapperUpdateWrapper = new UpdateWrapper<MainOrders>().eq("main_order_id", mainOrderId).set("order_status", 4);
                mainOrdersMapper.update(null, mainOrdersMapperUpdateWrapper);
            }else {
                UpdateWrapper<MainOrders> mainOrdersMapperUpdateWrapper = new UpdateWrapper<MainOrders>().eq("main_order_id", mainOrderId).set("order_status", 3);
                mainOrdersMapper.update(null, mainOrdersMapperUpdateWrapper);
            }
            lOrderRefundMapper.updateLOrderRefund(orderRefund);
        }

    }

    /**
     * @param mainOrders
     * @return
     */
    @Override
    public List<WebOrderRefundVO> selectWebOrderRefundList(MainOrders mainOrders) {
        return  lOrderRefundMapper.selectWebOrderRefundList(mainOrders);
    }
}
