package com.copy.trade.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.bizzan.bitrade.entity.transform.AuthMember;
import com.copy.trade.constant.DogeApi;
import com.copy.trade.consumer.MarketListener;
import com.copy.trade.entity.po.Customer;
import com.copy.trade.service.ICustomerService;
import com.copy.trade.util.HttpUtils;
import com.copy.trade.util.WebAssert;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;

@Slf4j
@Component
public class AuthenticationInterceptor implements HandlerInterceptor {

    String[] excludePathPatterns = {"/customer/open-account", "//customer/open-account", "/customer/", "//customer/", "/customer/top-trader-list"};

    @Autowired
    private ICustomerService customerServiceImpl;

    @Autowired
    private MarketListener marketListener;

    @Value("${doge.host}")
    private String dogeHost;

    @Value("${app.version.check.enabled:false}")
    private boolean appVersionCheckEnabled;

    /** 按平台分别缓存最低版本号，5 分钟 TTL（0=Android, 1=iOS） */
    private static volatile String cachedLowestVersionAndroid = null;
    private static volatile String cachedLowestVersionIos = null;
    private static volatile long lastRefreshTimeAndroid = 0L;
    private static volatile long lastRefreshTimeIos = 0L;
    private static final long CACHE_TTL_MS = 5 * 60 * 1000L;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 非controller请求直接跳过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        // ── 版本检查：从 doge 版本接口取 lowestVersion，与强制更新逻辑一致 ──
        if (appVersionCheckEnabled) {
            String appVersion = request.getHeader("x-app-version");
            // 没有app版本信息的视为web端，不需要版本拦截
            if (appVersion != null && !appVersion.isEmpty()) {
                boolean isIos = "1".equals(request.getHeader("x-app-platform"));
                String lowestVersion = getLowestVersion(isIos);
                if (lowestVersion != null && !lowestVersion.isEmpty()) {
                    if (isVersionLessThan(appVersion, lowestVersion)) {
                        ajaxReturn(response, 4099, getVersionOutdatedMessage(request));
                        return false;
                    }
                }
            }
        }

        log.info("获取sessionID>>>>>>>>>>>>>{}",request.getSession().getId());
        //验证登陆
        AuthMember authMember = (AuthMember) request.getSession().getAttribute(DogeApi.SESSION_MEMBER);
        WebAssert.isNotNull(authMember, "4001");
        String requestURI = request.getRequestURI();
        log.info("requestURI={}", requestURI);
        if(!Arrays.asList(excludePathPatterns).contains(requestURI)){
            Customer customer = customerServiceImpl.getByMemberId(authMember.getId());
            log.info("customer={}", customer);
            WebAssert.isNotNull(customer,"chk.copy-trade.null");
        }
        return true;
    }

    /** 调用 doge /ancillary/system/app/version/{platform} 获取最低版本，5 分钟缓存 */
    private String getLowestVersion(boolean isIos) {
        long now = System.currentTimeMillis();
        long lastRefresh = isIos ? lastRefreshTimeIos : lastRefreshTimeAndroid;
        String cached = isIos ? cachedLowestVersionIos : cachedLowestVersionAndroid;
        if (cached == null || now - lastRefresh > CACHE_TTL_MS) {
            try {
                int platform = isIos ? 1 : 0;
                String url = dogeHost + "/ancillary/system/app/version/" + platform;
                String resp = HttpUtils.get(url);
                if (resp != null) {
                    JSONObject json = JSONObject.parseObject(resp);
                    if (json != null && Integer.valueOf(0).equals(json.getInteger("code"))) {
                        JSONObject data = json.getJSONObject("data");
                        if (data != null) {
                            String lowest = data.getString("lowestVersion");
                            if (lowest != null && !lowest.isEmpty()) {
                                cached = lowest;
                                if (isIos) { cachedLowestVersionIos = cached; lastRefreshTimeIos = now; }
                                else       { cachedLowestVersionAndroid = cached; lastRefreshTimeAndroid = now; }
                            }
                        }
                    }
                }
            } catch (Exception e) {
                log.error("Failed to get app lowest version from doge, platform={}", isIos ? "iOS" : "Android", e);
            }
        }
        return cached;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }

    /** 版本比较：a < b 返回 true（与 Flutter AppVersion.isForceUpdate 逻辑一致） */
    private static boolean isVersionLessThan(String a, String b) {
        String[] partsA = a.split("\\.");
        String[] partsB = b.split("\\.");
        int maxLen = Math.max(partsA.length, partsB.length);
        for (int i = 0; i < maxLen; i++) {
            int va = i < partsA.length ? safeParseInt(partsA[i]) : 0;
            int vb = i < partsB.length ? safeParseInt(partsB[i]) : 0;
            if (va != vb) return va < vb;
        }
        return false;
    }

    private static int safeParseInt(String s) {
        try { return Integer.parseInt(s.trim()); } catch (NumberFormatException e) { return 0; }
    }

    private static String getVersionOutdatedMessage(HttpServletRequest request) {
        String lang = request.getHeader("lang");
        if ("en_US".equals(lang)) return "Please update to the latest version of the App";
        if ("zh_HK".equals(lang)) return "請更新至最新版本的App";
        if ("ja_JP".equals(lang)) return "最新バージョンのアプリに更新してください";
        if ("ko_KR".equals(lang)) return "최신 버전의 앱으로 업데이트해 주세요";
        return "请更新至最新版本的App";
    }

    private static void ajaxReturn(HttpServletResponse response, int code, String msg) throws IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/json; charset=UTF-8");
        PrintWriter out = response.getWriter();
        JSONObject json = new JSONObject();
        json.put("code", code);
        json.put("message", msg);
        out.print(json.toJSONString());
        out.flush();
        out.close();
    }

}
