package com.ruoyi.jarvis.service.impl;

import com.alibaba.fastjson2.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 企微「开」+ 手机号：POST 局域网 /v1/forward，将 JSON 中的 {@code reply_text} 作为回显。
 * <p>
 * 可配置 {@code wait_reply} / {@code reply_take_nth}：服务端先发 text，再等 Bot 回 N 次，
 * 将第 N 条内容填入 {@code reply_text}（前几条如「查询中…」由对端丢弃）。
 * </p>
 */
@Service
public class OpenPhoneForwardService {

    private static final Logger log = LoggerFactory.getLogger(OpenPhoneForwardService.class);

    private static final Pattern MOBILE_11 = Pattern.compile("(1\\d{10})");

    @Value("${jarvis.phone-forward.enabled:false}")
    private boolean enabled;

    @Value("${jarvis.phone-forward.base-url:}")
    private String baseUrl;

    @Value("${jarvis.phone-forward.path:/v1/forward}")
    private String path;

    @Value("${jarvis.phone-forward.connect-timeout-ms:8000}")
    private int connectTimeoutMs;

    @Value("${jarvis.phone-forward.read-timeout-ms:60000}")
    private int readTimeoutMs;

    /** 为 true 时在 POST body 中携带 wait_reply、reply_take_nth（单次请求生效） */
    @Value("${jarvis.phone-forward.wait-reply:true}")
    private boolean waitReply;

    /** 与 wait_reply 配合：取第几条 Bot 回复作为 reply_text，须 ≥ 1 */
    @Value("${jarvis.phone-forward.reply-take-nth:2}")
    private int replyTakeNth;

    /**
     * @return 非 null 表示本条消息已由本服务处理（含错误提示）；null 表示不匹配规则
     */
    public String tryReply(String rawContent) {
        if (!enabled || !StringUtils.hasText(baseUrl) || rawContent == null) {
            return null;
        }
        String text = rawContent.trim().replaceFirst("^\uFEFF", "");
        if (!text.startsWith("开")) {
            return null;
        }
        String phone = extractFirstMobile11(text);
        if (phone == null) {
            return null;
        }
        return doForward(phone);
    }

    private static String extractFirstMobile11(String text) {
        Matcher m = MOBILE_11.matcher(text);
        if (m.find()) {
            return m.group(1);
        }
        return null;
    }

    private String doForward(String phone) {
        try {
            String base = baseUrl.trim();
            if (base.endsWith("/")) {
                base = base.substring(0, base.length() - 1);
            }
            String p = path.startsWith("/") ? path : "/" + path;
            String q;
            try {
                q = URLEncoder.encode(phone, StandardCharsets.UTF_8.name());
            } catch (UnsupportedEncodingException e) {
                q = phone;
            }
            String urlStr = base + p + "?text=" + q;

            JSONObject body = new JSONObject();
            body.put("text", phone);
            if (waitReply) {
                int nth = replyTakeNth >= 1 ? replyTakeNth : 1;
                if (replyTakeNth < 1) {
                    log.warn("phone-forward reply-take-nth={} 无效，已按 1 处理", replyTakeNth);
                }
                body.put("wait_reply", true);
                body.put("reply_take_nth", nth);
            }
            byte[] bytes = body.toJSONString().getBytes(StandardCharsets.UTF_8);

            HttpURLConnection conn = null;
            try {
                conn = (HttpURLConnection) new URL(urlStr).openConnection();
                conn.setRequestMethod("POST");
                conn.setConnectTimeout(connectTimeoutMs);
                conn.setReadTimeout(readTimeoutMs);
                conn.setDoOutput(true);
                conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
                conn.setRequestProperty("Accept", "*/*");
                try (OutputStream os = conn.getOutputStream()) {
                    os.write(bytes);
                }
                int code = conn.getResponseCode();
                InputStream is = code >= 200 && code < 300 ? conn.getInputStream() : conn.getErrorStream();
                String resp = readAll(is);
                if (code < 200 || code >= 300) {
                    log.warn("phone-forward HTTP {} url={} body={}", code, urlStr, resp);
                    return "「转发服务」请求失败（HTTP " + code + "），请稍后再试。";
                }
                JSONObject jo = JSONObject.parseObject(resp);
                if (jo == null) {
                    return "「转发服务」返回异常，请稍后再试。";
                }
                String reply = jo.getString("reply_text");
                if (!StringUtils.hasText(reply)) {
                    return "「转发服务」未返回 reply_text。";
                }
                return reply;
            } finally {
                if (conn != null) {
                    conn.disconnect();
                }
            }
        } catch (Exception e) {
            log.warn("phone-forward 异常 phone={} err={}", phone, e.toString());
            return "「转发服务」连接失败，请确认 Jarvis 与局域网服务可达。";
        }
    }

    private static String readAll(InputStream is) throws java.io.IOException {
        if (is == null) {
            return "";
        }
        byte[] buf = new byte[4096];
        StringBuilder sb = new StringBuilder();
        int n;
        while ((n = is.read(buf)) >= 0) {
            sb.append(new String(buf, 0, n, StandardCharsets.UTF_8));
        }
        return sb.toString();
    }
}
