package cn.reghao.tnb.user.app.service;

import cn.reghao.jutil.jdk.serializer.JsonConverter;
import cn.reghao.tnb.user.api.dto.UserInfo;
import cn.reghao.tnb.user.app.controller.UserControllerHystrix;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.hystrix.contrib.javanica.conf.HystrixPropertiesManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * @author reghao
 * @date 2025-07-21 13:51:11
 */
@Slf4j
@Service
public class UserServiceHystrix {
    private final UserProfileService userProfileService;

    public UserServiceHystrix(UserProfileService userProfileService) {
        this.userProfileService = userProfileService;
    }

    @HystrixCommand
    /*@HystrixCommand(
            commandProperties = {
                    @HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE")
            }
    )*/
    public String hello() {
        log.info("user -> {}", UserControllerHystrix.UserHolder.getUser());
        return null;
    }

    public String helloFallback() {
        log.info("user -> {}", UserControllerHystrix.UserHolder.getUser());
        return null;
    }

    @HystrixCommand(
            fallbackMethod = "getUserInfoFallback",
            commandProperties = {
                    @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ENABLED, value = "false"),
                    // 5 秒内, 请求达到 4 个以上, 失败率达到 50% 以上, 则开启熔断, 此时会直接使用 fallback, 不会再调用业务方法
                    // 熔断 3 秒后有请求到来, 则会再执行一次业务方法, 执行失败则继续保持熔断, 执行成功则取消熔断
                    @HystrixProperty(name="metrics.rollingStats.timeInMilliseconds", value="5000"),
                    @HystrixProperty(name="circuitBreaker.requestVolumeThreshold", value="4"),
                    @HystrixProperty(name="circuitBreaker.errorThresholdPercentage", value="50"),
                    @HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds", value="3000")
            })
    public String getUserInfo(Long userId) {
        if (userId % 3 == 0) {
            try {
                log.info("{} 模拟耗时, 休眠 10s", userId);
                Thread.sleep(10_000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        UserInfo userInfo = userProfileService.getUserInfo(userId);
        log.info("{} -> {}", userInfo.getUserId(), userInfo.getScreenName());
        return JsonConverter.objectToJson(userInfo);
    }

    public UserInfo getUserInfo1(Long userId) {
        if (userId % 3 == 0) {
            try {
                log.info("{} 模拟耗时, 休眠 10s", userId);
                Thread.sleep(10_000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        UserInfo userInfo = userProfileService.getUserInfo(userId);
        return userInfo;
    }

    public String getUserInfoFallback(Long userId) {
        log.info("hystrix fallback with userId {}", userId);
        Map<String, String> map = new HashMap<>();
        map.put("code", "0");
        map.put("msg", "hystrix fallback");
        return JsonConverter.objectToJson(map);
    }

    public String getResult() {
        /*UserVO userVO = RequestContextHolder.get();
        log.info("I am  hystrix pool thread,try to get threadlocal:{}", userVO);
        return userVO.toString();*/
        return null;
    }
}
