package com.leromro.core.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leromro.common.constant.CommonConstants;
import com.leromro.common.core.domain.AjaxResult;
import com.leromro.common.core.domain.ListPermission;
import com.leromro.common.enums.AreaSettlementStatusEnum;
import com.leromro.common.enums.ServiceCentreSettlementStatusEnum;
import com.leromro.common.utils.DateUtils;
import com.leromro.common.utils.PageUtils;
import com.leromro.common.utils.SecurityUtils;
import com.leromro.core.domain.*;
import com.leromro.core.domain.dto.*;
import com.leromro.core.domain.vo.*;
import com.leromro.core.mapper.*;
import com.leromro.core.service.ISecondOrderService;
import com.leromro.core.utils.DateTimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
public class SecondOrdersServiceImpl extends ServiceImpl<SecondOrdersMapper, SecondOrder> implements ISecondOrderService {
    @Autowired
    private SecondOrdersMapper secondOrdersMapper;
    @Autowired
    private OrderFrozenFundsMapper orderFrozenFundsMapper;
    @Autowired
    private VolunteerAccountMapper volunteerAccountMapper;
    @Autowired
    private MainOrdersMapper mainOrdersMapper;
    @Autowired
    private VolunteerInfoMapper volunteerInfoMapper;

    /**
     * @param orderStatus
     * @return
     */
    @Override
    public List<VolunteerOrdersVO> selectOrderList(Long userId,Long orderStatus) {
        return secondOrdersMapper.selectVolunteerOrder( userId,orderStatus);
    }

    /**
     * @return
     */
    @Override
    public AjaxResult volunteerFinishWork(SecondOrder secondOrder) {
        secondOrder.setVolunteerId(SecurityUtils.getUserId());
        Long secondOrderId = secondOrder.getSecondOrderId();
        QueryWrapper<SecondOrder> SecondOrderWrapper = new QueryWrapper<SecondOrder>().eq("second_order_id", secondOrderId);
        SecondOrder secondOrderInfo = secondOrdersMapper.selectList(SecondOrderWrapper).get(0);
       // SecondOrder secondOrderInfo = secondOrdersMapper.selectById(secondOrderId);
        //BigDecimal onePrice = secondOrderInfo.getServiceOnePrice();
        BigDecimal oneServiceTotalPrice = secondOrderInfo.getServiceTotalPrice();
        //默认平台佣金以及志愿者到手钱数
        BigDecimal volunteerMoney = oneServiceTotalPrice.multiply(new BigDecimal("0.85"));
        BigDecimal platformBrokerage = oneServiceTotalPrice.subtract(volunteerMoney);
        //计算结束冻结时间 默认开始时间+3天
        DateTime frozenStartTime = DateTimeUtil.getNowTime1();
        Date frozenEndTime = DateUtils.addDays(frozenStartTime, 3);
        OrderFrozenFunds orderFrozenFunds = OrderFrozenFunds.builder().volunteerMoney(volunteerMoney)
                .platformBrokerage(platformBrokerage).scoreMoney(BigDecimal.valueOf(0.00)).secondOrderMoney(oneServiceTotalPrice)
                .status(0).secondOrderId(secondOrder.getSecondOrderId()).volunteerId(secondOrder.getVolunteerId())
                .frozenStartTime(frozenStartTime).frozenEndTime(frozenEndTime).build();
        //插入冻结资金表
        orderFrozenFundsMapper.insert(orderFrozenFunds);
        //更新secondOrder 表 不可以重复完成一个订单
        if (secondOrderInfo.getOrderStatus().equals("4")){
            throw new RuntimeException("订单已完成，请勿重复完成");
        }
        UpdateWrapper<SecondOrder> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("second_order_id",secondOrder.getSecondOrderId()).set("order_status",4)
                .set("volunteer_review",secondOrder.getVolunteerReview()).set("volunteer_picture",secondOrder.getVolunteerPicture()).set("update_time",DateTimeUtil.getNowTime()).set("service_end_time",DateTimeUtil.getNowTime());
        secondOrdersMapper.update(null,updateWrapper);
        //更新志愿者账户中的冻结资金 =  之前的余额 + 志愿者 （先按照默认的比例，把默认的钱数，放入冻结资金表中）
        QueryWrapper<VolunteerAccount> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("volunteer_id",secondOrder.getVolunteerId());
        VolunteerAccount volunteerAccount = volunteerAccountMapper.selectOne(queryWrapper);
        BigDecimal oldOrderFrozenBalance = volunteerAccount.getOrderFrozenBalance();
        BigDecimal newVolunteerFrozenBalance = oldOrderFrozenBalance.add(volunteerMoney);
        volunteerAccount.setOrderFrozenBalance(newVolunteerFrozenBalance);
        volunteerAccount.setUpdateTime(DateTimeUtil.getNowTime());
        volunteerAccountMapper.updateById(volunteerAccount);
        //判断是否完单
        Long mainOrderId = secondOrderInfo.getMainOrderId();
        QueryWrapper<MainOrders> mainOrdersQueryWrapper = new QueryWrapper<MainOrders>().eq("main_order_id", mainOrderId);
        Long totalTimes = mainOrdersMapper.selectList(mainOrdersQueryWrapper).get(0).getTotalTimes();
        UpdateWrapper<MainOrders> mainOrdersUpdateWrapper = new UpdateWrapper<MainOrders>().eq("main_order_id", mainOrderId).setSql("finish_times = finish_times + 1");
        if (secondOrderInfo.getWorkNumber().equals(totalTimes)){
            mainOrdersUpdateWrapper.set("order_status", 4);
            mainOrdersMapper.update(null,mainOrdersUpdateWrapper);
        }else {
            mainOrdersMapper.update(null,mainOrdersUpdateWrapper);
        }
        return AjaxResult.success();
    }

    /**
     * @param reviewDTO
     */
    @Override
    @Transactional
    public void userFinish(UserOrderReviewDTO reviewDTO) {
        //根据用户传来的评分 来设置需要计算的钱数
        //获取一次服务的钱数（！！   这一版先不改钱数的获取方式   ！！）
        //BigDecimal serviceOnePrice = reviewDTO.getServiceOnePrice();
        //更新后的第二版，钱数要从
        Long volunteerInfoId = reviewDTO.getVolunteerInfoId();
        VolunteerInfo volunteerInfo = volunteerInfoMapper.selectOne(new LambdaQueryWrapper<VolunteerInfo>().eq(VolunteerInfo::getVolunteerInfoId, volunteerInfoId));
        BigDecimal serviceOnePrice = volunteerInfo.getBusinessPrice();
        BigDecimal volunteerMoney = serviceOnePrice.multiply(new BigDecimal("0.85"));
        BigDecimal scoreMoney = BigDecimal.valueOf(0);
        BigDecimal platformBrokerage = BigDecimal.valueOf(0);
        Integer protocolScore = reviewDTO.getProtocolScore();
        Integer clothingScore = reviewDTO.getClothingScore();
        Integer abilityScore = reviewDTO.getAbilityScore();
        Integer qualityScore = reviewDTO.getQualityScore();
        double averageScore = (double) (protocolScore + clothingScore + abilityScore + qualityScore) /4;
        Integer score =(int)Math.round(averageScore);
        if  ( score.equals(1) ){
            //  1星85%
            scoreMoney = serviceOnePrice.multiply(new BigDecimal("0.85")).subtract(volunteerMoney);
            platformBrokerage = serviceOnePrice.subtract(volunteerMoney).subtract(scoreMoney);
        }
        else if ( score.equals(2) ){
            //  2星89%
            scoreMoney = serviceOnePrice.multiply(new BigDecimal("0.89")).subtract(volunteerMoney);
            platformBrokerage = serviceOnePrice.subtract(volunteerMoney).subtract(scoreMoney);
        } else if (score.equals(3)) {
            //  3星91%
            scoreMoney = serviceOnePrice.multiply(new BigDecimal("0.91")).subtract(volunteerMoney);
            platformBrokerage = serviceOnePrice.subtract(volunteerMoney).subtract(scoreMoney);
        } else if (score.equals(4)) {
            //  4星93%
            scoreMoney = serviceOnePrice.multiply(new BigDecimal("0.93")).subtract(volunteerMoney);
            platformBrokerage = serviceOnePrice.subtract(volunteerMoney).subtract(scoreMoney);
        } else if (score.equals(5)) {
            //  5星95%
            scoreMoney = serviceOnePrice.multiply(new BigDecimal("0.95")).subtract(volunteerMoney);
            platformBrokerage = serviceOnePrice.subtract(volunteerMoney).subtract(scoreMoney);
        }
        //修改冻结表：
        UpdateWrapper<OrderFrozenFunds> orderFrozenFundsUpdateWrapper = new UpdateWrapper<OrderFrozenFunds>().eq("second_order_id", reviewDTO.getSecondOrderId()).set("platform_brokerage", platformBrokerage).set("score_money", scoreMoney).set("update_time", DateTimeUtil.getNowTime());
        orderFrozenFundsMapper.update(null,orderFrozenFundsUpdateWrapper);
        //修改志愿者账户表，向其中添加内容
        UpdateWrapper<VolunteerAccount> volunteerAccountUpdateWrapper = new UpdateWrapper<VolunteerAccount>().eq("volunteer_id", volunteerInfo.getVolunteerId()).setSql("order_frozen_balance = order_frozen_balance + " + scoreMoney);
        volunteerAccountMapper.update(null,volunteerAccountUpdateWrapper);
        //更改订单状态：
        UpdateWrapper<SecondOrder> updateWrapper = new UpdateWrapper<SecondOrder>().eq("second_order_id", reviewDTO.getSecondOrderId())
                .set("score",score).set("user_review",reviewDTO.getUserReview()).set("user_picture",reviewDTO.getUserPicture()).set("protocol_score",protocolScore).set("clothing_score",clothingScore).set("ability_score",abilityScore).set("quality_score",qualityScore).set("update_time",DateTimeUtil.getNowTime());
        secondOrdersMapper.update(null,updateWrapper);
    }

    @Override
    public List<SecondOrder> getCurrentOrgSecondOrderList(HomePageDTO dto) {
        return baseMapper.getCurrentOrgSecondOrderList(new ListPermission(SecondOrder.class, CommonConstants.CHECK_PROVINCE_CITY_DISTRICT),dto);
    }

    @Override
    public List<SecondOrder> getTodayAllOrderList(HomePageDTO dto) {
        return baseMapper.getTodayAllOrderList(dto);
    }

    @Override
    public List<SettlementOrderListVO> selectSettlementOrderList(SettlementOrderListDTO settlementOrderListDTO) {
        // 获取当前用户部门id
        Long deptId = SecurityUtils.getDeptId();
        // 获取当前用户部门类型
        String areaType = SecurityUtils.getAreaType();
        // 查询参数拷贝
        AuthSettlementOrderListDTO orderAuthSettlementOrderListDTO = BeanUtil.copyProperties(settlementOrderListDTO, AuthSettlementOrderListDTO.class);
        // 根据部门类型做数据权限控制
        if("3".equals(areaType)){
            // 仅查询区域公司自己的订单
            orderAuthSettlementOrderListDTO.setAreaDistributionId(deptId);
        }else if("4".equals(areaType)){
            // 仅查询区域公司公司自己的订单
            orderAuthSettlementOrderListDTO.setServiceDistributionId(deptId);
        }
        PageUtils.startPage();
        PageUtils.orderBy("a.create_time desc");
        List<SettlementOrderListVO> list = secondOrdersMapper.selectSettlementOrderList(orderAuthSettlementOrderListDTO);
        return list;
    }

    @Override
    public void areaSettlement(SettlementOrderDTO settlementOrderDTO) {
        // 获取当前用户id
        Long userId = SecurityUtils.getUserId();

        // 修改订单结算结算信息
        this.update(new LambdaUpdateWrapper<SecondOrder>()
                .set(SecondOrder::getAreaSettlementStatus, AreaSettlementStatusEnum.SETTLED.getCode())
                .set(SecondOrder::getAreaSettlementTime, DateTimeUtil.getNowTime())
                .set(SecondOrder::getAreaSettlementUserId, userId)
                .set(SecondOrder::getAreaPayerMethod, settlementOrderDTO.getPayerMethod())
                .set(SecondOrder::getAreaPayerAccount, settlementOrderDTO.getPayerAccount())
                .set(SecondOrder::getAreaPayerAccountBankName, settlementOrderDTO.getPayerBankName())
                .in(SecondOrder::getSecondOrderId, settlementOrderDTO.getSecondOrderIds())
        );
    }


    @Override
    public void serviceCentreSettlement(SettlementOrderDTO settlementOrderDTO) {
        // 获取当前用户id
        Long userId = SecurityUtils.getUserId();

        // 修改订单结算结算信息
        this.update(new LambdaUpdateWrapper<SecondOrder>()
                .set(SecondOrder::getServiceCentreSettlementStatus, ServiceCentreSettlementStatusEnum.SETTLED.getCode())
                .set(SecondOrder::getServiceCentreSettlementTime, DateTimeUtil.getNowTime())
                .set(SecondOrder::getServiceCentreSettlementUserId, userId)
                .set(SecondOrder::getServiceCentrePayerMethod, settlementOrderDTO.getPayerMethod())
                .set(SecondOrder::getServiceCentrePayerAccount, settlementOrderDTO.getPayerAccount())
                .set(SecondOrder::getServiceCentrePayerBankName, settlementOrderDTO.getPayerBankName())
                .in(SecondOrder::getSecondOrderId, settlementOrderDTO.getSecondOrderIds())
        );
    }

    @Override
    @Transactional
    public void updateAreaSettlementStatus(List<Long> secondOrderIds, String status) {
        this.update(new LambdaUpdateWrapper<SecondOrder>()
                .set(SecondOrder::getAreaSettlementStatus, status)
                .in(SecondOrder::getSecondOrderId, secondOrderIds));
    }

    @Override
    @Transactional
    public void updateAreaSettlementInfo(SettlementOrderApplyDTO settlementOrderApplyDTO) {
        this.update(new LambdaUpdateWrapper<SecondOrder>()
                .set(SecondOrder::getAreaSettlementStatus,  AreaSettlementStatusEnum.PENDING_AUDIT.getCode())
                .set(SecondOrder::getAreaPayeeMethod, settlementOrderApplyDTO.getPayeeMethod())
                .set(SecondOrder::getAreaPayeeAccount, settlementOrderApplyDTO.getPayeeAccount())
                .set(SecondOrder::getAreaPayeeBankName, settlementOrderApplyDTO.getPayeeBankName())
                .set(SecondOrder::getAreaPayeeName, settlementOrderApplyDTO.getPayeeName())
                .in(SecondOrder::getSecondOrderId, settlementOrderApplyDTO.getSecondOrderIds())
        );
    }

    @Override
    public void updateServiceCentreSettlementInfo(SettlementOrderApplyDTO settlementOrderApplyDTO) {
        this.update(new LambdaUpdateWrapper<SecondOrder>()
                .set(SecondOrder::getServiceCentreSettlementStatus,  ServiceCentreSettlementStatusEnum.PENDING_AUDIT.getCode())
                .set(SecondOrder::getServiceCentrePayeeMethod, settlementOrderApplyDTO.getPayeeMethod())
                .set(SecondOrder::getServiceCentrePayeeAccount, settlementOrderApplyDTO.getPayeeAccount())
                .set(SecondOrder::getServiceCentrePayeeBankName, settlementOrderApplyDTO.getPayeeBankName())
                .set(SecondOrder::getServiceCentrePayeeName, settlementOrderApplyDTO.getPayeeName())
                .in(SecondOrder::getSecondOrderId, settlementOrderApplyDTO.getSecondOrderIds())
        );
    }

    @Override
    @Transactional
    public void updateServiceCentreSettlementStatus(List<Long> secondOrderIds, String status) {
        this.update(new LambdaUpdateWrapper<SecondOrder>()
                .set(SecondOrder::getServiceCentreSettlementStatus, status)
                .in(SecondOrder::getSecondOrderId, secondOrderIds));
    }

    /**
     * @param mainOrderId
     * @return
     */
    @Override
    public List<SecondOrderInfoVO> selectSecondOrderInfoVO(Long mainOrderId) {
        return secondOrdersMapper.selectSecondOrderInfoVO(mainOrderId);
    }

    /**
     * @param secondOrderId
     * @return
     */
    @Override
    public AppSecoundOrderInfoVO selectAppSecondOrderInfo(Long secondOrderId) {
       return secondOrdersMapper.selectAppSecondOrderInfo(secondOrderId);
    }

    /**
     * @param secondOrderId
     * @return
     */
    @Override
    public WebSecondOrderInfoVO selectWebAppSecondOrderInfo(Long secondOrderId) {

        WebSecondOrderInfoVO webSecondOrderInfo = secondOrdersMapper.selectWebSecondOrderInfo(secondOrderId);
        return webSecondOrderInfo;
    }

    @Override
    public SettlementOrderDetailVO getSettlementOrderDetail(Long secondOrderId) {
        return secondOrdersMapper.getSettlementOrderDetail(secondOrderId);
    }
}
