package com.hfkj.service.gas.impl;

import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.dao.BsGasOrderReceiptMapper;
import com.hfkj.entity.BsGasOrder;
import com.hfkj.entity.BsGasOrderReceipt;
import com.hfkj.entity.BsGasOrderReceiptExample;
import com.hfkj.entity.BsUserReceipt;
import com.hfkj.service.gas.BsGasOrderReceiptService;
import com.hfkj.service.gas.BsGasOrderService;
import com.hfkj.service.user.BsUserReceiptService;
import com.hfkj.sysenum.gas.GasOrderReceiptStatusEnum;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @className: BsGasOrderReceiptServiceImpl
 * @author: HuRui
 * @date: 2024/7/24
 **/
@Service("gasOrderReceiptServiceImpl")
public class BsGasOrderReceiptServiceImpl implements BsGasOrderReceiptService {
    @Resource
    private BsGasOrderReceiptMapper gasOrderReceiptMapper;
    @Resource
    private BsUserReceiptService userReceiptService;
    @Resource
    private BsGasOrderService gasOrderService;

    @Override
    public void editData(BsGasOrderReceipt data) {
        data.setUpdateTime(new Date());
        if (data.getId() == null) {
            data.setCreateTime(new Date());
            gasOrderReceiptMapper.insert(data);
        } else {
            gasOrderReceiptMapper.updateByPrimaryKeySelective(data);
        }
    }

    @Override
    public void batchUpdate(List<BsGasOrderReceipt> data) {
        gasOrderReceiptMapper.batchUpdate(data);
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW,rollbackFor= {RuntimeException.class})
    public void applyReceipt(Long userReceiptId, List<String> orderNos) {
        // 查询收据
        BsUserReceipt receipt = userReceiptService.getDetail(userReceiptId);
        if (receipt == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的收据");
        }
        for (Object orderNo : orderNos) {
            // 查询订单
            BsGasOrder gasOrder = gasOrderService.getDetailByOrderNo(orderNo.toString());
            if (gasOrder == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, orderNo+"未知的订单");
            }
            if (!GasOrderReceiptStatusEnum.status0.getStatus().equals(gasOrder.getReceiptStatus())
                && !GasOrderReceiptStatusEnum.status3.getStatus().equals(gasOrder.getReceiptStatus())) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, gasOrder.getOrderNo()+"订单未处于未开票状态");
            }
            gasOrder.setReceiptStatus(GasOrderReceiptStatusEnum.status1.getStatus());
            gasOrder.setReceiptFailRemark(null);
            gasOrderService.updateGasOrder(gasOrder);

            BsGasOrderReceipt gasOrderReceipt = new BsGasOrderReceipt();
            gasOrderReceipt.setApplyNo(System.currentTimeMillis()+"");
            gasOrderReceipt.setUserReceiptId(receipt.getUserId());
            gasOrderReceipt.setCompanyName(receipt.getCompanyName());
            gasOrderReceipt.setTaxNo(receipt.getTaxNo());
            gasOrderReceipt.setContactsPhone(receipt.getContactsPhone());
            gasOrderReceipt.setEmail(receipt.getEmail());
            gasOrderReceipt.setAgentId(gasOrder.getAgentId());
            gasOrderReceipt.setAgentName(gasOrder.getAgentName());
            gasOrderReceipt.setAgentStaffId(gasOrder.getGasStaffId());
            gasOrderReceipt.setAgentStaffName(gasOrderReceipt.getAgentStaffName());
            gasOrderReceipt.setMerNo(gasOrder.getMerNo());
            gasOrderReceipt.setMerName(gasOrder.getMerName());
            gasOrderReceipt.setOrderNo(gasOrder.getOrderNo());
            gasOrderReceipt.setOrderChildNo(gasOrder.getOrderChildNo());
            gasOrderReceipt.setOilNo(gasOrder.getGasOilNo());
            gasOrderReceipt.setAmount(gasOrder.getActualPayPrice());
            gasOrderReceipt.setStatus(GasOrderReceiptStatusEnum.status1.getStatus());
            editData(gasOrderReceipt);
        }
    }

    @Override
    public void success(String applyNo) {
        // 查询详情
        BsGasOrderReceipt orderReceipt = getDetail(applyNo);
        if (orderReceipt == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的申请");
        }
        if (!GasOrderReceiptStatusEnum.status1.getStatus().equals(orderReceipt.getStatus())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "申请状态错误");
        }
        orderReceipt.setStatus(GasOrderReceiptStatusEnum.status2.getStatus());
        editData(orderReceipt);

        // 查询订单
        BsGasOrder gasOrder = gasOrderService.getDetailByOrderNo(orderReceipt.getOrderNo());
        if (gasOrder != null) {
            gasOrder.setReceiptStatus(GasOrderReceiptStatusEnum.status2.getStatus());
            gasOrder.setReceiptFailRemark(null);
            gasOrderService.updateGasOrder(gasOrder);
        }
    }

    @Override
    public void fail(String applyNo, String remark) {
        // 查询详情
        BsGasOrderReceipt orderReceipt = getDetail(applyNo);
        if (orderReceipt == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的申请");
        }
        if (!GasOrderReceiptStatusEnum.status1.getStatus().equals(orderReceipt.getStatus())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "申请状态错误");
        }
        orderReceipt.setStatus(GasOrderReceiptStatusEnum.status3.getStatus());
        orderReceipt.setFailRemark(remark);
        editData(orderReceipt);

        // 查询订单
        BsGasOrder gasOrder = gasOrderService.getDetailByOrderNo(orderReceipt.getOrderNo());
        if (gasOrder != null) {
            gasOrder.setReceiptStatus(GasOrderReceiptStatusEnum.status3.getStatus());
            gasOrder.setReceiptFailRemark(remark);
            gasOrderService.updateGasOrder(gasOrder);
        }
    }

    @Override
    public BsGasOrderReceipt getDetail(String applyNo) {
        BsGasOrderReceiptExample example = new BsGasOrderReceiptExample();
        example.createCriteria().andApplyNoEqualTo(applyNo);
        List<BsGasOrderReceipt> list = gasOrderReceiptMapper.selectByExample(example);
        if (!list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public BsGasOrderReceipt getDetailByOrderNo(String orderNo, GasOrderReceiptStatusEnum status) {
        BsGasOrderReceiptExample example = new BsGasOrderReceiptExample();
        BsGasOrderReceiptExample.Criteria criteria = example.createCriteria().andOrderNoEqualTo(orderNo);
        if (status != null) {
            criteria.andStatusEqualTo(status.getStatus());
        }
        example.setOrderByClause("create_time desc");
        List<BsGasOrderReceipt> list = gasOrderReceiptMapper.selectByExample(example);
        if (!list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public BsGasOrderReceipt getDetail(Long orderReceiptId) {
        return gasOrderReceiptMapper.selectByPrimaryKey(orderReceiptId);
    }

    @Override
    public List<BsGasOrderReceipt> getList(Map<String, Object> param) {
        BsGasOrderReceiptExample example = new BsGasOrderReceiptExample();
        BsGasOrderReceiptExample.Criteria criteria = example.createCriteria()
                .andStatusNotEqualTo(GasOrderReceiptStatusEnum.status99.getStatus());

        if (StringUtils.isNotBlank(MapUtils.getString(param, "orderNo"))) {
            criteria.andOrderNoLike("%"+MapUtils.getString(param, "orderNo")+"%");
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "contactsPhone"))) {
            criteria.andContactsPhoneLike("%"+MapUtils.getString(param, "contactsPhone")+"%");
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "merNo"))) {
            criteria.andMerNoEqualTo(MapUtils.getString(param, "merNo"));
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "merName"))) {
            criteria.andMerNameLike("%"+MapUtils.getString(param, "merName")+"%");
        }

        if (MapUtils.getLong(param, "agentId") != null) {
            criteria.andAgentIdEqualTo(MapUtils.getLong(param, "agentId"));
        }

        if (MapUtils.getLong(param, "agentStaffId") != null) {
            criteria.andAgentStaffIdEqualTo(MapUtils.getLong(param, "agentStaffId"));
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "status"))) {
            List<Integer> status = Arrays.stream(MapUtils.getString(param, "status").split(","))
                    .flatMapToInt(num -> IntStream.of(Integer.parseInt(num))).boxed()
                    .collect(Collectors.toList());
            criteria.andStatusIn(status);
        }

        if (MapUtils.getLong(param, "createTimeS") != null) {
            criteria.andCreateTimeGreaterThanOrEqualTo(new Date(MapUtils.getLong(param, "createTimeS")));
        }

        if (MapUtils.getLong(param, "createTimeE") != null) {
            criteria.andCreateTimeLessThanOrEqualTo(new Date(MapUtils.getLong(param, "createTimeE")));
        }

        example.setOrderByClause("create_time desc");
        return gasOrderReceiptMapper.selectByExample(example);
    }
}
