package com.zehong.system.udp;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author lenovo
 * @date 2025/8/5
 * @description TODO
 */
public class RobotArmMessageParser {
    private static final Logger log = LoggerFactory.getLogger(RobotArmMessageParser.class);
//    private static final Pattern STATUS_PATTERN = Pattern.compile(
//            "PPP (\\w+) (\\S+)(?: (\\d+),(\\d+),(\\d+),(\\d+),)?"
//    );
    // 修改正则表达式，支持负数的坐标
    private static final Pattern STATUS_PATTERN = Pattern.compile(
            "PPP (\\w+) (\\S+)(?: (-?\\d+),(-?\\d+),(-?\\d+),(-?\\d+),)?"
    );
    // 坐标判定的误差范围（-2到2之间）
    private static final int COORDINATE_TOLERANCE = 2;

    public static RobotArmStatus parseMessage(String message) {
        log.info("正在解析消息: {}", message);
        Matcher matcher = STATUS_PATTERN.matcher(message);
        if (matcher.find()) {
            log.info("正则匹配成功:");
            String statusCode = matcher.group(1);
            String statusText = matcher.group(2);
            String x = matcher.group(3);
            String y = matcher.group(4);
            String z = matcher.group(5);
            String r = matcher.group(6);
            RobotArmStatus status = new RobotArmStatus(statusCode, statusText,
                    parseCoord(x), parseCoord(y),
                    parseCoord(z), parseCoord(r));
            log.debug("解析结果: code={}, text={}, x={}, y={}, z={}, r={}, isFullyIdle={}",
                    statusCode, statusText, status.x, status.y, status.z, status.r,
                    status.isFullyIdle());

            return status;
//            return new RobotArmStatus(statusCode, statusText,
//                    parseCoord(x), parseCoord(y),
//                    parseCoord(z), parseCoord(r));
        }
        log.info("正则匹配失败，消息格式不正确: {}", message);
        return null;
    }

    private static Integer parseCoord(String coord) {
        if (coord == null || coord.isEmpty()) return null;
        try {
            return Integer.parseInt(coord);
        } catch (NumberFormatException e) {
            return null;
        }
    }

    public static class RobotArmStatus {
        private final String code;
        private final String text;
        private final Integer x;
        private final Integer y;
        private final Integer z;
        private final Integer r;

        public RobotArmStatus(String code, String text,
                              Integer x, Integer y, Integer z, Integer r) {
            this.code = code;
            this.text = text;
            this.x = x;
            this.y = y;
            this.z = z;
            this.r = r;
        }

        /**
         * 判断x坐标是否在[-2, 2]范围内（包含边界）
         */
        public boolean isXInRange() {
            return isCoordInRange(x);
        }

        /**
         * 判断y坐标是否在[-2, 2]范围内（包含边界）
         */
        public boolean isYInRange() {
            return isCoordInRange(y);
        }

        /**
         * 判断z坐标是否在[-2, 2]范围内（包含边界）
         */
        public boolean isZInRange() {
            return isCoordInRange(z);
        }

        /**
         * 判断r坐标是否在[-2, 2]范围内（包含边界）
         */
        public boolean isRInRange() {
            return isCoordInRange(r);
        }

        /**
         * 通用坐标判定：是否在[-2, 2]范围内
         * @param coord 坐标值（可能为null）
         * @return 若坐标在范围内则返回true，否则返回false（坐标为null时返回false）
         */
        private boolean isCoordInRange(Integer coord) {
            return coord != null && coord >= -COORDINATE_TOLERANCE && coord <= COORDINATE_TOLERANCE;
        }

        public boolean isBusy() {
            return "BUSY".equals(code);
        }

        public boolean isOk() {
            return "OK".equals(code);
        }

        public boolean isComplete() {
            return isOk() && "完成".equals(text);
        }

        /**
         * 判断是否完全空闲：状态完成且所有坐标在[-2, 2]范围内
         */
        public boolean isFullyIdle() {
            return isComplete()
                    && isXInRange()
                    && isYInRange()
                    && isZInRange()
                    && isRInRange();
        }

        // Getters
        public String getCode() { return code; }
        public String getText() { return text; }
        public Integer getX() { return x; }
        public Integer getY() { return y; }
        public Integer getZ() { return z; }
        public Integer getR() { return r; }
    }
}
