package com.haha.service.payment.payscore;

import com.haha.service.payment.payscore.PayScoreCreateRequest.PostPayment;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * 支付分业务服务接口
 * 封装支付分相关的业务逻辑，协调订单服务和支付分策略
 */
public interface PayScoreService {

    /**
     * 创建支付分服务订单
     * 
     * @param orderId 本地订单ID
     * @param openId 用户微信openId
     * @return 支付分结果（含小程序调起支付分所需的package参数）
     */
    PayScoreResult createPayScoreOrder(Long orderId, String openId);

    /**
     * 创建支付分服务订单（带风险金配置）
     * 
     * @param orderId 本地订单ID
     * @param openId 用户微信openId
     * @param riskFundAmount 风险金额
     * @param riskFundName 风险金名称（DEPOSIT/ADVANCE/CASH_DEPOSIT）
     * @return 支付分结果
     */
    PayScoreResult createPayScoreOrder(Long orderId, String openId, 
            BigDecimal riskFundAmount, String riskFundName);

    /**
     * 完结支付分服务订单（触发自动扣款）
     * 
     * @param orderId 本地订单ID
     * @param totalAmount 实际扣款总金额
     * @param payments 后付费项目列表
     * @return 支付分结果
     */
    PayScoreResult completePayScoreOrder(Long orderId, BigDecimal totalAmount, 
            List<PostPayment> payments);

    /**
     * 完结支付分服务订单（带优惠）
     * 
     * @param orderId 本地订单ID
     * @param totalAmount 实际扣款总金额
     * @param payments 后付费项目列表
     * @param discounts 商户优惠列表
     * @return 支付分结果
     */
    PayScoreResult completePayScoreOrder(Long orderId, BigDecimal totalAmount, 
            List<PostPayment> payments, List<PayScoreCompleteRequest.PostDiscount> discounts);

    /**
     * 取消支付分服务订单
     * 
     * @param orderId 本地订单ID
     * @param reason 取消原因
     * @return 支付分结果
     */
    PayScoreResult cancelPayScoreOrder(Long orderId, String reason);

    /**
     * 查询支付分服务订单状态
     * 
     * @param outOrderNo 商户服务订单号
     * @return 支付分结果
     */
    PayScoreResult queryPayScoreOrder(String outOrderNo);

    /**
     * 处理支付分回调通知
     * 
     * @param params 回调参数（含请求头和请求体）
     * @return 回调处理结果
     */
    PayScoreCallbackResult handlePayScoreCallback(Map<String, Object> params);

    /**
     * 同步订单支付分状态
     * 从微信侧查询最新状态并更新本地订单
     *
     * @param orderId 本地订单ID
     * @return 同步结果（含最新状态信息）
     */
    PayScoreResult syncPayScoreStatus(Long orderId);

    /**
     * 发起支付扣款（调用微信支付分 /pay 接口）
     * 在服务完结后调用，触发实际扣款，成功后退款接口才可用
     *
     * @param orderId 本地订单ID
     * @return 支付扣款结果
     */
    PayScoreResult payPayScoreOrder(Long orderId);

    /**
     * 创建支付分服务订单（含权限校验）
     *
     * @param userId 用户ID
     * @param orderId 订单ID
     * @param openId 用户微信openId
     * @param riskFundAmount 风险金额（可选）
     * @param riskFundName 风险金名称（可选）
     * @return 包含 outOrderNo、state、package 的Map
     */
    Map<String, Object> createUserPayScoreOrder(Long userId, Long orderId, String openId,
                                                  BigDecimal riskFundAmount, String riskFundName);

    /**
     * 创建支付分服务订单（从Map params提取参数）
     *
     * @param userId 用户ID
     * @param params 包含 orderId、openId 等参数
     * @return 创建结果Map
     */
    Map<String, Object> createUserPayScoreOrder(Long userId, Map<String, Object> params);

    /**
     * 完结支付分服务订单（含权限校验）
     *
     * @param userId 用户ID
     * @param orderId 订单ID
     * @param totalAmount 实际扣款金额
     * @param payments 后付费项目列表（可选）
     * @param discounts 优惠列表（可选）
     * @return 包含 outOrderNo、state 的Map
     */
    Map<String, Object> completeUserPayScoreOrder(Long userId, Long orderId, BigDecimal totalAmount,
                                                    List<PostPayment> payments,
                                                    List<PayScoreCompleteRequest.PostDiscount> discounts);

    /**
     * 完结支付分服务订单（从Map params提取参数）
     *
     * @param userId 用户ID
     * @param params 包含 orderId、totalAmount 等参数
     * @return 完结结果Map
     */
    Map<String, Object> completeUserPayScoreOrder(Long userId, Map<String, Object> params);

    /**
     * 取消支付分服务订单（含权限校验）
     *
     * @param userId 用户ID
     * @param orderId 订单ID
     * @param reason 取消原因
     * @return 包含 outOrderNo、state 的Map
     */
    Map<String, Object> cancelUserPayScoreOrder(Long userId, Long orderId, String reason);

    /**
     * 取消支付分服务订单（从Map params提取orderId和reason）
     *
     * @param userId 用户ID
     * @param params 包含 orderId、reason（可选）
     * @return 取消结果Map
     */
    Map<String, Object> cancelUserPayScoreOrder(Long userId, Map<String, Object> params);

    /**
     * 查询支付分服务订单状态（含权限校验）
     *
     * @param userId 用户ID
     * @param orderId 订单ID
     * @return 包含 outOrderNo、state、totalAmount 的Map
     */
    Map<String, Object> queryUserPayScoreOrder(Long userId, Long orderId);

    /**
     * 同步支付分状态（含权限校验）
     *
     * @param userId 用户ID
     * @param orderId 订单ID
     * @return 是否同步成功
     */
    boolean syncUserPayScoreStatus(Long userId, Long orderId);

    /**
     * 修改支付分订单金额（仅 USER_PAYING 状态可下调）
     *
     * @param orderId 本地订单ID
     * @param totalAmount 新金额
     * @param payments 修改后的后付费项目列表
     * @param reason 修改原因
     * @return 支付分结果
     */
    PayScoreResult modifyPayScoreOrder(Long orderId, BigDecimal totalAmount,
            List<PayScoreModifyRequest.PostPayment> payments, String reason);

    /**
     * 同步订单支付信息（用户已通过其他方式支付时通知微信停止扣款）
     *
     * @param orderId 本地订单ID
     * @param detail 同步说明
     * @return 支付分结果
     */
    PayScoreResult syncOrderPaidInfo(Long orderId, String detail);

    /**
     * 支付分退款
     *
     * @param orderId 本地订单ID
     * @param refundAmount 退款金额
     * @param reason 退款原因
     * @return 支付分结果
     */
    PayScoreResult refundPayScoreOrder(Long orderId, BigDecimal refundAmount, String reason);

    /**
     * 查询支付分退款状态
     *
     * @param orderId 本地订单ID
     * @param outRefundNo 商户退款单号
     * @return 支付分结果
     */
    PayScoreResult queryPayScoreRefund(Long orderId, String outRefundNo);

    /**
     * 预创建支付分服务订单（需确认模式，开门前调用）
     * 创建本地订单记录和微信支付分服务订单，返回 package 供前端拉起确认页
     *
     * @param userId 用户ID
     * @param deviceId 设备ID
     * @param openId 用户微信openId
     * @return 包含 orderId、outOrderNo、package 的 Map
     */
    Map<String, Object> preCreatePayScoreOrder(Long userId, String deviceId, String openId);

    /**
     * 获取微信支付分订单详情签名参数（用于 wx.openBusinessView）
     *
     * @param outTradeNo 商户订单号
     * @return 包含 mchId、serviceId、outOrderNo、timestamp、nonceStr、signType、sign 的 Map
     */
    Map<String, Object> getPayscoreDetailSign(String outTradeNo);

    /**
     * 从 Redis 追踪数据中尝试恢复丢失的 payScoreOrderId
     *
     * @param userId   用户ID
     * @param deviceId 设备ID
     * @return 恢复的 payScoreOrderId，未找到返回 null
     */
    String tryRecoverPayScoreOrderId(Long userId, String deviceId);

    /**
     * 获取支付分服务ID（从微信支付配置中读取）
     *
     * @return 服务ID，未配置返回 null
     */
    String getServiceId();

    /**
     * 获取预授权信息（从 Redis 读取，只读不删）
     *
     * @param deviceId 设备 ID
     * @param userId   用户 ID
     * @return Map 包含 payScoreOrderId, payScoreState, serviceId，不存在返回 null
     */
    Map<String, String> getPreAuthInfo(String deviceId, Long userId);
}
