package com.ruoyi.ss.transactionBill.service;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.dashboard.domain.vo.BillCountVo;
import com.ruoyi.ss.device.domain.vo.DeviceVO;
import com.ruoyi.ss.payBill.domain.vo.DoPayVO;
import com.ruoyi.ss.transactionBill.domain.TransactionBill;
import com.ruoyi.ss.transactionBill.domain.TransactionBillQuery;
import com.ruoyi.ss.transactionBill.domain.bo.*;
import com.ruoyi.ss.transactionBill.domain.dto.EndUseDTO;
import com.ruoyi.ss.transactionBill.domain.dto.RechargePayBO;
import com.ruoyi.ss.transactionBill.domain.vo.*;
import com.ruoyi.ss.transactionBill.domain.dto.BillRefundDTO;
import com.ruoyi.ss.transactionBill.domain.dto.WithdrawApprovalDTO;
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillStatus;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

/**
 * 充值记录Service接口
 *
 * @author 邱贞招
 * @date 2024-02-21
 */
public interface TransactionBillService
{
    /**
     * 查询充值记录
     *
     * @param billId 充值记录主键
     * @return 充值记录
     */
    public TransactionBillVO selectSmTransactionBillByBillId(Long billId);

    /**
     * 查询充值记录列表
     *
     * @param smTransactionBillQuery 充值记录查询条件
     * @return 充值记录集合
     */
    public List<TransactionBillVO> selectSmTransactionBillList(TransactionBillQuery smTransactionBillQuery);

    /**
     * 新增充值记录
     *
     * @param transactionBill 充值记录
     * @return 结果
     */
    public int insertSmTransactionBill(TransactionBill transactionBill);

    /**
     * 修改充值记录
     *
     * @param transactionBill 充值记录
     * @return 结果
     */
    public int updateSmTransactionBill(TransactionBill transactionBill);

    /**
     * 批量删除充值记录
     *
     * @param billIds 需要删除的充值记录主键集合
     * @return 结果
     */
    public int deleteSmTransactionBillByBillIds(Long[] billIds);

    /**
     * 删除充值记录信息
     *
     * @param billId 充值记录主键
     * @return 结果
     */
    public int deleteSmTransactionBillByBillId(Long billId);

    /**
     * 获取账单统计
     * @param dto
     * @return
     */
    List<BillCountVo> selectCount(TransactionBillQuery dto);

    /**
     * 创建订单
     *
     * @param bo 订单信息
     * @return 新增的数据订单编号
     */
    String addOrder(RechargeBO bo);

    /**
     * 取消充值订单
     * @param billNo 订单编号
     * @param status 取消后的状态
     */
    int cancelRecharge(String billNo, TransactionBillStatus status);

    /**
     * 根据订单编号查询数据
     *
     * @param billNo 订单编号
     */
    TransactionBillVO selectSmTransactionBillByBillNo(String billNo);

    /**
     * 获取未支付的充值订单
     * @return 订单列表
     */
    List<TransactionBillVO> selectNoPayedRecharge();

    /**
     * 提现
     */
    String addWithdraw(WithdrawBO bo);

    /**
     * 提现审核通过
     *
     * @param dto id
     */
    int passWithdraw(WithdrawApprovalDTO dto);

    /**
     * 提现审核拒绝
     *
     * @param dto id
     */
    boolean rejectWithdraw(WithdrawApprovalDTO dto);

    /**
     * 查询商户统计信息
     * @param dto 查询条件
     * @return 统计信息
     */
    List<BillCountVo> selectLandlordCount(TransactionBillQuery dto);

    /**
     * 刷新订单支付结果
     * @param billId
     */
    int refreshPayResult(Long billId);

    /**
     * 手动设备充值
     *
     * @param billId
     */
    boolean rechargeDevice(Long billId);

    /**
     * 查询设备充值失败列表
     * @param userId
     * @return
     */
    List<TransactionBillVO> selectDeviceRechargeFailList(Long userId);

    /**
     * 查询支付结果，直到过期
     *
     * @param bill     订单编号
     * @param delay    延迟时间
     * @param timeUnit 时间单位
     */
    void refreshPayResultBeforeExpire(TransactionBillVO bill, int delay, TimeUnit timeUnit);

    /**
     * 查询数量并映射
     * @param query 查询条件
     * @param keyMapper 映射方法
     */
    <K> Map<K, BillCountVo> selectCountMap(TransactionBillQuery query, Function<? super BillCountVo, ? extends K> keyMapper);

    /**
     * 蓝牙充值成功
     * @param billNo
     * @return
     */
    boolean bluetoothRechargeSuccess(String billNo);

    /**
     * 订单退款
     */
    int refund(BillRefundDTO dto);

    /**
     * 根据条件更新
     * @param data
     * @param query
     */
    int updateByQuery(TransactionBill data, TransactionBillQuery query);

    /**
     * 尝试充值设备
     * @param billId 订单ID
     * @param tryCount 尝试次数
     */
    void tryRechargeDevice(Long billId, int tryCount);

    /**
     * 尝试设置语音
     */
    void trySetVoice(TransactionBillVO bill, int tryCount);

    /**
     * 刷新支付结果
     */
    int refreshPayResult(String billNo);

    int refreshPayResult(List<TransactionBillVO> billList);

    /**
     * 增加订单退款金额
     *
     * @param billId              订单ID
     * @param refundAmount        退款金额
     * @param refundMchAmount     商户退款金额
     * @param refundServiceAmount 退款手续费
     */
    int addRefundAmount(Long billId, BigDecimal refundAmount, BigDecimal refundMchAmount, BigDecimal refundServiceAmount);

    /**
     * 查询用户正在使用中的订单
     */
    List<TransactionBillVO> selectUsingBill(Long userId);

    /**
     * 查询正在使用中的订单
     */
    List<TransactionBillVO> selectUsingBill(TransactionBillQuery query);

    /**
     * 根据设备ID批量结束订单
     */
    int batchCloseBillByDevice(List<TransactionBillVO> billList, boolean withDevice, DeviceVO device, BigDecimal totalEle);

    /**
     * 获取用户提现手续费信息
     */
    UserWithdrawServiceVO getUserWithdrawService(Long userId, Long channelId);

    /**
     * 调起支付
     */
    DoPayVO pay(RechargePayBO bo);

    /**
     * 查询提现列表
     */
    List<TransactionBillVO> selectWithdrawList(TransactionBillQuery query);

    /**
     * 查询提现详情
     */
    TransactionBillVO selectWithdrawById(Long billId);

    /**
     * 简单查询数量
     */
    int selectSimpleCount(TransactionBillQuery query);

    /**
     * 支付押金
     */
    DoPayVO payDeposit(RechargePayDepositBO bo);

    /**
     * 查询未支付的分时段订单
     */
    List<TransactionBillVO> selectUnpaidTimingBill(TransactionBillQuery query);

    /**
     * 计算订单金额
     */
    BigDecimal calcAmount(Long billId, LocalDateTime now, BigDecimal totalEle);

    /**
     * 查询订单总金额
     * @param query
     * @return
     */
    BigDecimal selectSumOfMoney(TransactionBillQuery query);


    /**
     * 结束使用订单
     */
    EndUseVO endUse(EndUseBO bo, boolean withDevice);

    /**
     * 结束使用订单
     */
    EndUseVO endUse(EndUseDTO dto, boolean withDevice);

    /**
     * 查询所有关于金额的总和
     */
    <T> List<TransactionAmountVO<T>> selectCommonSumOfMoney(TransactionBillQuery query, String groupBy);

    TransactionBillVO selectOne(TransactionBillQuery query);

    /**
     * 开启/关闭订单设备
     */
    int switchDevice(TransactionBillVO bill, boolean open);

    /**
     * 查询最后一个
     */
    TransactionBillVO selectLastOne(TransactionBillQuery query);

    /**
     * 修复订单数据
     */
    int fix(Long billId);

    /**
     * 修复所有订单数据
     * @return
     */
    int fixAll();

    /**
     * 收取商户查看用户手机号的价格
     * @param bill
     * @return
     */
    int receiveMchShowMobileAmount(TransactionBillVO bill);

    <T> List<JSONObject> selectCountGroupBy(TransactionBillQuery query, String groupBy);

    /**
     * 查询员工可见列表
     */
    List<TransactionBillVO> selectStaffDeviceList(TransactionBillQuery query);

    /**
     * 查询去除退款金额的订单金额
     */
    BigDecimal selectSumOfMoneyWithoutRefund(TransactionBillQuery query);

    /**
     * 按日查询订单金额
     */
    List<TransactionDailyAmountVO> selectDailyAmount(TransactionBillQuery query);

    /**
     * 更新结束时间
     */
    int batchUpdateSuitEndTime(List<Long> billIds, LocalDateTime time);
}
