package com.haha.service.payment.payscore.impl;

import com.haha.common.constant.OrderConstants;
import com.haha.entity.Order;
import com.haha.service.OrderService;
import com.haha.service.payment.config.WxPayConfig;
import com.haha.service.payment.payscore.*;
import com.haha.service.payment.payscore.PayScoreCreateRequest.PostPayment;
import com.haha.service.payment.payscore.PayScoreCompleteRequest.PostDiscount;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * 支付分业务服务实现
 * 封装支付分相关的业务逻辑，协调订单服务和支付分策略
 */
@Slf4j
@Service
public class PayScoreServiceImpl implements PayScoreService {

    @Autowired(required = false)
    private PayScoreStrategy payScoreStrategy;

    @Autowired
    private OrderService orderService;

    @Autowired(required = false)
    private WxPayConfig wxPayConfig;

    private static final BigDecimal DEFAULT_RISK_FUND_AMOUNT = new BigDecimal("99.00");
    private static final String DEFAULT_RISK_FUND_NAME = "DEPOSIT";

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PayScoreResult createPayScoreOrder(Long orderId, String openId) {
        return createPayScoreOrder(orderId, openId, DEFAULT_RISK_FUND_AMOUNT, DEFAULT_RISK_FUND_NAME);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PayScoreResult createPayScoreOrder(Long orderId, String openId, 
            BigDecimal riskFundAmount, String riskFundName) {
        log.info("[支付分服务] 创建服务订单 - orderId: {}, openId: {}, riskFund: {}元", 
                orderId, openId, riskFundAmount);

        PayScoreResult checkResult = checkServiceAvailable();
        if (checkResult != null) {
            return checkResult;
        }

        Order order = validateAndGetOrder(orderId);

        if (order.getPayScoreOrderId() != null && !"REVOKED".equals(order.getPayScoreState())) {
            log.warn("[支付分服务] 订单已存在支付分订单 - orderId: {}, payScoreState: {}", 
                    orderId, order.getPayScoreState());
            return PayScoreResult.fail("ORDER_EXISTS", "该订单已创建支付分服务订单");
        }

        PayScoreCreateRequest request = new PayScoreCreateRequest();
        request.setOutOrderNo(generateOutOrderNo(orderId));
        request.setServiceIntroduction("充电服务");
        request.setOpenId(openId);
        request.setRiskFundName(riskFundName != null ? riskFundName : DEFAULT_RISK_FUND_NAME);
        request.setRiskFundAmount(riskFundAmount != null ? riskFundAmount : DEFAULT_RISK_FUND_AMOUNT);
        request.setStartTime("OnAccept");
        request.setStartDeviceId(order.getDeviceId());

        if (order.getTotalAmount() != null && order.getTotalAmount().compareTo(BigDecimal.ZERO) > 0) {
            PostPayment payment = new PostPayment();
            payment.setName("充电费用");
            payment.setAmount(order.getTotalAmount());
            payment.setDescription("预估费用");
            request.setPostPayments(Collections.singletonList(payment));
        }

        PayScoreResult result = payScoreStrategy.createServiceOrder(request);

        if (result.isSuccess()) {
            order.setPayScoreOrderId(result.getOutOrderNo());
            order.setPayScoreState(result.getState());
            if (wxPayConfig != null) {
                order.setServiceId(wxPayConfig.getServiceId());
            }
            order.setServiceStartTime(LocalDateTime.now());
            order.setPayChannel("wechat_payscore");
            order.setPayType("微信支付分");
            orderService.updateById(order);

            log.info("[支付分服务] 创建服务订单成功 - orderId: {}, outOrderNo: {}, state: {}", 
                    orderId, result.getOutOrderNo(), result.getState());
        } else {
            log.error("[支付分服务] 创建服务订单失败 - orderId: {}, errorCode: {}, errorMsg: {}", 
                    orderId, result.getErrorCode(), result.getErrorMsg());
        }

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PayScoreResult completePayScoreOrder(Long orderId, BigDecimal totalAmount, 
            List<PostPayment> payments) {
        return completePayScoreOrder(orderId, totalAmount, payments, null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PayScoreResult completePayScoreOrder(Long orderId, BigDecimal totalAmount, 
            List<PostPayment> payments, List<PostDiscount> discounts) {
        log.info("[支付分服务] 完结服务订单 - orderId: {}, totalAmount: {}元", orderId, totalAmount);

        PayScoreResult checkResult = checkServiceAvailable();
        if (checkResult != null) {
            return checkResult;
        }

        Order order = validateAndGetOrder(orderId);

        if (order.getPayScoreOrderId() == null) {
            log.error("[支付分服务] 订单未创建支付分服务订单 - orderId: {}", orderId);
            return PayScoreResult.fail("ORDER_NOT_CREATED", "该订单未创建支付分服务订单");
        }

        if ("DONE".equals(order.getPayScoreState()) || "REVOKED".equals(order.getPayScoreState())) {
            log.warn("[支付分服务] 订单已完结或已取消 - orderId: {}, payScoreState: {}", 
                    orderId, order.getPayScoreState());
            return PayScoreResult.fail("ORDER_COMPLETED", "该订单已完结或已取消");
        }

        PayScoreCompleteRequest request = new PayScoreCompleteRequest();
        request.setOutOrderNo(order.getPayScoreOrderId());
        request.setTotalAmount(totalAmount);
        request.setPostPayments(payments);
        request.setPostDiscounts(discounts);
        request.setEndTime(formatDateTime(LocalDateTime.now()));
        request.setStartDeviceId(order.getDeviceId());

        PayScoreResult result = payScoreStrategy.completeServiceOrder(request);

        if (result.isSuccess()) {
            order.setPayScoreState(result.getState() != null ? result.getState() : "USER_PAYING");
            order.setServiceEndTime(LocalDateTime.now());
            order.setTotalAmount(totalAmount);
            orderService.updateById(order);

            log.info("[支付分服务] 完结服务订单成功 - orderId: {}, state: {}", 
                    orderId, result.getState());
        } else {
            log.error("[支付分服务] 完结服务订单失败 - orderId: {}, errorCode: {}, errorMsg: {}", 
                    orderId, result.getErrorCode(), result.getErrorMsg());
        }

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PayScoreResult cancelPayScoreOrder(Long orderId, String reason) {
        log.info("[支付分服务] 取消服务订单 - orderId: {}, reason: {}", orderId, reason);

        PayScoreResult checkResult = checkServiceAvailable();
        if (checkResult != null) {
            return checkResult;
        }

        Order order = validateAndGetOrder(orderId);

        if (order.getPayScoreOrderId() == null) {
            log.error("[支付分服务] 订单未创建支付分服务订单 - orderId: {}", orderId);
            return PayScoreResult.fail("ORDER_NOT_CREATED", "该订单未创建支付分服务订单");
        }

        if ("DONE".equals(order.getPayScoreState()) || "REVOKED".equals(order.getPayScoreState())) {
            log.warn("[支付分服务] 订单已完结或已取消 - orderId: {}, payScoreState: {}", 
                    orderId, order.getPayScoreState());
            return PayScoreResult.fail("ORDER_COMPLETED", "该订单已完结或已取消");
        }

        PayScoreCancelRequest request = new PayScoreCancelRequest();
        request.setOutOrderNo(order.getPayScoreOrderId());
        request.setReason(reason != null ? reason : "用户取消");

        PayScoreResult result = payScoreStrategy.cancelServiceOrder(request);

        if (result.isSuccess()) {
            order.setPayScoreState("REVOKED");
            order.setStatus(OrderConstants.STATUS_CANCELLED);
            orderService.updateById(order);

            log.info("[支付分服务] 取消服务订单成功 - orderId: {}", orderId);
        } else {
            log.error("[支付分服务] 取消服务订单失败 - orderId: {}, errorCode: {}, errorMsg: {}", 
                    orderId, result.getErrorCode(), result.getErrorMsg());
        }

        return result;
    }

    @Override
    public PayScoreResult queryPayScoreOrder(String outOrderNo) {
        log.info("[支付分服务] 查询服务订单 - outOrderNo: {}", outOrderNo);
        
        PayScoreResult checkResult = checkServiceAvailable();
        if (checkResult != null) {
            return checkResult;
        }
        
        return payScoreStrategy.queryServiceOrder(outOrderNo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PayScoreCallbackResult handlePayScoreCallback(Map<String, Object> params) {
        log.info("[支付分服务] 处理回调通知");

        if (payScoreStrategy == null) {
            log.error("[支付分服务] 支付分策略未初始化，请检查微信支付配置");
            return PayScoreCallbackResult.fail("支付分服务未配置");
        }

        PayScoreCallbackResult result = payScoreStrategy.parseCallback(params);

        if (!result.isSuccess()) {
            log.error("[支付分服务] 回调解析失败 - errorMsg: {}", result.getErrorMsg());
            return result;
        }

        String outOrderNo = result.getOutOrderNo();
        String eventType = result.getEventType();
        String state = result.getState();

        log.info("[支付分服务] 回调解析成功 - outOrderNo: {}, eventType: {}, state: {}", 
                outOrderNo, eventType, state);

        Order order = orderService.lambdaQuery()
                .eq(Order::getPayScoreOrderId, outOrderNo)
                .one();

        if (order == null) {
            log.error("[支付分服务] 未找到对应订单 - payScoreOrderId: {}", outOrderNo);
            return result;
        }

        if ("PAYSCORE.USER_CONFIRMED".equals(eventType)) {
            order.setPayScoreState("DOING");
            log.info("[支付分服务] 用户确认使用服务 - orderId: {}", order.getId());
        } else if ("PAYSCORE.USER_PAID".equals(eventType)) {
            order.setPayScoreState("DONE");
            order.setPayStatus(OrderConstants.PAY_STATUS_PAID);
            order.setStatus(OrderConstants.STATUS_COMPLETED);
            order.setPayTime(result.getPayTime() != null ? result.getPayTime() : LocalDateTime.now());
            if (result.getTotalAmount() != null) {
                order.setTotalAmount(result.getTotalAmount());
            }
            log.info("[支付分服务] 用户完成支付 - orderId: {}, amount: {}元", 
                    order.getId(), result.getTotalAmount());
        }

        orderService.updateById(order);

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean syncPayScoreStatus(Long orderId) {
        log.info("[支付分服务] 同步订单状态 - orderId: {}", orderId);

        PayScoreResult checkResult = checkServiceAvailable();
        if (checkResult != null) {
            return false;
        }

        Order order = validateAndGetOrder(orderId);

        if (order.getPayScoreOrderId() == null) {
            log.warn("[支付分服务] 订单未创建支付分服务订单，无法同步 - orderId: {}", orderId);
            return false;
        }

        PayScoreResult result = payScoreStrategy.queryServiceOrder(order.getPayScoreOrderId());

        if (!result.isSuccess()) {
            log.error("[支付分服务] 查询服务订单失败 - orderId: {}, errorCode: {}", 
                    orderId, result.getErrorCode());
            return false;
        }

        String newState = result.getState();
        String oldState = order.getPayScoreState();

        if (newState != null && !newState.equals(oldState)) {
            order.setPayScoreState(newState);

            if ("DONE".equals(newState)) {
                order.setPayStatus(OrderConstants.PAY_STATUS_PAID);
                order.setStatus(OrderConstants.STATUS_COMPLETED);
                if (result.getTotalAmount() != null) {
                    order.setTotalAmount(result.getTotalAmount());
                }
            } else if ("REVOKED".equals(newState)) {
                order.setStatus(OrderConstants.STATUS_CANCELLED);
            }

            orderService.updateById(order);
            log.info("[支付分服务] 订单状态已更新 - orderId: {}, oldState: {}, newState: {}", 
                    orderId, oldState, newState);
        }

        return true;
    }

    private PayScoreResult checkServiceAvailable() {
        if (payScoreStrategy == null) {
            log.error("[支付分服务] 支付分策略未初始化，请检查微信支付配置");
            return PayScoreResult.fail("SERVICE_UNAVAILABLE", "支付分服务未配置");
        }
        return null;
    }

    private Order validateAndGetOrder(Long orderId) {
        if (orderId == null) {
            throw new IllegalArgumentException("订单ID不能为空");
        }

        Order order = orderService.getById(orderId);
        if (order == null) {
            throw new IllegalArgumentException("订单不存在: " + orderId);
        }

        return order;
    }

    private String generateOutOrderNo(Long orderId) {
        return "PS" + System.currentTimeMillis() + orderId;
    }

    private String formatDateTime(LocalDateTime dateTime) {
        return dateTime.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
    }
}
