package com.ycwl.basic.integration.profitshare.service;

import com.ycwl.basic.integration.common.exception.IntegrationException;
import com.ycwl.basic.integration.common.response.CommonResponse;
import com.ycwl.basic.integration.common.response.PageResponse;
import com.ycwl.basic.integration.common.service.IntegrationFallbackService;
import com.ycwl.basic.integration.profitshare.client.ProfitShareClient;
import com.ycwl.basic.integration.profitshare.dto.CalculateResultVO;
import com.ycwl.basic.integration.profitshare.dto.CalculateShareRequest;
import com.ycwl.basic.integration.profitshare.dto.ManualShareRequest;
import com.ycwl.basic.integration.profitshare.dto.TypesVO;
import com.ycwl.basic.integration.profitshare.dto.record.RecordDetailVO;
import com.ycwl.basic.integration.profitshare.dto.record.RecordVO;
import com.ycwl.basic.integration.profitshare.dto.rule.CreateRuleRequest;
import com.ycwl.basic.integration.profitshare.dto.rule.RuleVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * 分账集成服务
 *
 * @author Claude Code
 * @date 2025-01-11
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ProfitShareIntegrationService {

    private final ProfitShareClient profitShareClient;
    private final IntegrationFallbackService fallbackService;

    private static final String SERVICE_NAME = "zt-profitshare";

    // ==================== 规则管理 ====================

    /**
     * 创建分账规则（直接操作，无fallback）
     */
    public RuleVO createRule(CreateRuleRequest request) {
        log.debug("创建分账规则, scenicId: {}, ruleName: {}", request.getScenicId(), request.getRuleName());
        CommonResponse<RuleVO> response = profitShareClient.createRule(request);
        return handleResponse(response, "创建分账规则失败");
    }

    /**
     * 查询分账规则列表（带fallback）
     */
    public PageResponse<RuleVO> listRules(Long scenicId, String status, String ruleType, Integer page, Integer pageSize) {
        log.debug("查询分账规则列表, scenicId: {}, status: {}, ruleType: {}, page: {}, pageSize: {}",
                scenicId, status, ruleType, page, pageSize);
        return fallbackService.executeWithFallback(
                SERVICE_NAME,
                String.format("rules:list:%s:%s:%s:%d:%d", scenicId, status, ruleType, page, pageSize),
                () -> {
                    CommonResponse<PageResponse<RuleVO>> response = profitShareClient.listRules(scenicId, status, ruleType, page, pageSize);
                    return handleResponse(response, "查询分账规则列表失败");
                },
                PageResponse.class
        );
    }

    /**
     * 获取分账规则详情（带fallback）
     */
    public RuleVO getRule(Long ruleId) {
        log.debug("获取分账规则详情, ruleId: {}", ruleId);
        return fallbackService.executeWithFallback(
                SERVICE_NAME,
                "rule:" + ruleId,
                () -> {
                    CommonResponse<RuleVO> response = profitShareClient.getRule(ruleId);
                    return handleResponse(response, "获取分账规则详情失败");
                },
                RuleVO.class
        );
    }

    /**
     * 更新分账规则（直接操作，无fallback）
     */
    public RuleVO updateRule(Long ruleId, CreateRuleRequest request) {
        log.debug("更新分账规则, ruleId: {}", ruleId);
        CommonResponse<RuleVO> response = profitShareClient.updateRule(ruleId, request);
        RuleVO result = handleResponse(response, "更新分账规则失败");
        // 清理规则缓存
        clearRuleCache(ruleId);
        return result;
    }

    /**
     * 删除分账规则（直接操作，无fallback）
     */
    public void deleteRule(Long ruleId) {
        log.debug("删除分账规则, ruleId: {}", ruleId);
        CommonResponse<Void> response = profitShareClient.deleteRule(ruleId);
        handleResponse(response, "删除分账规则失败");
        // 清理规则缓存
        clearRuleCache(ruleId);
    }

    /**
     * 启用规则（直接操作，无fallback）
     */
    public void enableRule(Long ruleId) {
        log.debug("启用分账规则, ruleId: {}", ruleId);
        CommonResponse<Void> response = profitShareClient.enableRule(ruleId);
        handleResponse(response, "启用分账规则失败");
        // 清理规则缓存
        clearRuleCache(ruleId);
    }

    /**
     * 禁用规则（直接操作，无fallback）
     */
    public void disableRule(Long ruleId) {
        log.debug("禁用分账规则, ruleId: {}", ruleId);
        CommonResponse<Void> response = profitShareClient.disableRule(ruleId);
        handleResponse(response, "禁用分账规则失败");
        // 清理规则缓存
        clearRuleCache(ruleId);
    }

    // ==================== 分账记录查询 ====================

    /**
     * 查询景区分账记录（带fallback）
     */
    public PageResponse<RecordVO> getRecordsByScenic(Long scenicId, Integer page, Integer pageSize) {
        log.debug("查询景区分账记录, scenicId: {}, page: {}, pageSize: {}", scenicId, page, pageSize);
        return fallbackService.executeWithFallback(
                SERVICE_NAME,
                String.format("records:scenic:%d:%d:%d", scenicId, page, pageSize),
                () -> {
                    CommonResponse<PageResponse<RecordVO>> response = profitShareClient.getRecordsByScenic(scenicId, page, pageSize);
                    return handleResponse(response, "查询景区分账记录失败");
                },
                PageResponse.class
        );
    }

    /**
     * 查询分账记录详情（带fallback）
     */
    public RecordDetailVO getRecordById(Long recordId) {
        log.debug("查询分账记录详情, recordId: {}", recordId);
        return fallbackService.executeWithFallback(
                SERVICE_NAME,
                "record:" + recordId,
                () -> {
                    CommonResponse<RecordDetailVO> response = profitShareClient.getRecordById(recordId);
                    return handleResponse(response, "查询分账记录详情失败");
                },
                RecordDetailVO.class
        );
    }

    /**
     * 按订单ID查询分账记录（带fallback）
     */
    public RecordDetailVO getRecordByOrderId(String orderId) {
        log.debug("按订单ID查询分账记录, orderId: {}", orderId);
        return fallbackService.executeWithFallback(
                SERVICE_NAME,
                "record:order:" + orderId,
                () -> {
                    CommonResponse<RecordDetailVO> response = profitShareClient.getRecordByOrderId(orderId);
                    return handleResponse(response, "按订单ID查询分账记录失败");
                },
                RecordDetailVO.class
        );
    }

    // ==================== 分账操作 ====================

    /**
     * 手动触发分账（直接操作，无fallback）
     */
    public void manualShare(String orderId) {
        log.debug("手动触发分账, orderId: {}", orderId);
        ManualShareRequest request = ManualShareRequest.builder()
                .orderId(orderId)
                .build();
        CommonResponse<Void> response = profitShareClient.manualShare(request);
        handleResponse(response, "手动触发分账失败");
    }

    /**
     * 计算分账金额（不执行）（带fallback）
     */
    public CalculateResultVO calculateShare(CalculateShareRequest request) {
        log.debug("计算分账金额, scenicId: {}, totalAmount: {}", request.getScenicId(), request.getTotalAmount());
        return fallbackService.executeWithFallback(
                SERVICE_NAME,
                String.format("calculate:%d:%.2f", request.getScenicId(), request.getTotalAmount()),
                () -> {
                    CommonResponse<CalculateResultVO> response = profitShareClient.calculateShare(request);
                    return handleResponse(response, "计算分账金额失败");
                },
                CalculateResultVO.class
        );
    }

    /**
     * 获取支持的类型（带fallback）
     */
    public TypesVO getSupportedTypes() {
        log.debug("获取支持的类型");
        return fallbackService.executeWithFallback(
                SERVICE_NAME,
                "types",
                () -> {
                    CommonResponse<TypesVO> response = profitShareClient.getSupportedTypes();
                    return handleResponse(response, "获取支持的类型失败");
                },
                TypesVO.class
        );
    }

    // ==================== 私有方法 ====================

    /**
     * 清理规则相关缓存
     */
    private void clearRuleCache(Long ruleId) {
        fallbackService.clearFallbackCache(SERVICE_NAME, "rule:" + ruleId);
    }

    private <T> T handleResponse(CommonResponse<T> response, String errorMessage) {
        if (response == null || !response.isSuccess()) {
            String msg = response != null && response.getMessage() != null
                    ? response.getMessage()
                    : errorMessage;
            Integer code = response != null ? response.getCode() : 5000;
            throw new IntegrationException(code, msg, SERVICE_NAME);
        }
        return response.getData();
    }
}
