package server.logic.ws_protocol.JSON.handlers.system;

import server.logic.ws_protocol.JSON.ConnectionContext;
import server.logic.ws_protocol.JSON.entyties.Net_Request;
import server.logic.ws_protocol.JSON.entyties.Net_Response;
import server.logic.ws_protocol.JSON.handlers.JsonMessageHandler;
import server.logic.ws_protocol.JSON.handlers.system.entyties.Net_Ping_Request;
import server.logic.ws_protocol.JSON.handlers.system.entyties.Net_Ping_Response;
import server.logic.ws_protocol.WireCodes;
import utils.config.AppConfig;

import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Ping — keep-alive.
 * В ответ кладём:
 * - ts (текущее время сервера в мс)
 * - uiBuildHash (текущий build hash UI, если удалось определить)
 */
public class Net_Ping_Handler implements JsonMessageHandler {
    private static final AppConfig CONFIG = AppConfig.getInstance();
    private static final String DEFAULT_UI_INDEX_PATH = "/home/user/docker/caddyFile/sites/shine-UI/index.html";
    private static final Pattern UI_HASH_PATTERN = Pattern.compile("window\\.__SHINE_BUILD_HASH__\\s*=\\s*'([^']+)'");
    private static volatile String cachedUiBuildHash = "";
    private static volatile long cachedUiIndexMtimeMs = -1L;

    @Override
    public Net_Response handle(Net_Request baseRequest, ConnectionContext ctx) {
        Net_Ping_Request req = (Net_Ping_Request) baseRequest;

        Net_Ping_Response resp = new Net_Ping_Response();
        resp.setOp(req.getOp());            // "Ping"
        resp.setRequestId(req.getRequestId());
        resp.setStatus(WireCodes.Status.OK);

        // ничего не проверяем, просто отдаём серверное время
        resp.setTs(System.currentTimeMillis());
        resp.setUiBuildHash(resolveUiBuildHash());
        resp.setServerVersion(CONFIG.getStringOrEmpty("server.version"));

        return resp;
    }

    private static String resolveUiBuildHash() {
        String indexPathRaw = CONFIG.getParam("server.ui.indexPath");
        String indexPath = (indexPathRaw == null || indexPathRaw.isBlank())
                ? DEFAULT_UI_INDEX_PATH
                : indexPathRaw.trim();
        try {
            Path path = Path.of(indexPath);
            long mtime = Files.getLastModifiedTime(path).toMillis();
            if (mtime == cachedUiIndexMtimeMs && !cachedUiBuildHash.isBlank()) {
                return cachedUiBuildHash;
            }

            String html = Files.readString(path, StandardCharsets.UTF_8);
            Matcher matcher = UI_HASH_PATTERN.matcher(html);
            String found = matcher.find() ? String.valueOf(matcher.group(1)).trim() : "";

            cachedUiIndexMtimeMs = mtime;
            cachedUiBuildHash = found;
            return found;
        } catch (Exception ignored) {
            String fallback = CONFIG.getParam("server.ui.buildHash");
            return fallback == null ? "" : fallback.trim();
        }
    }
}
