package com.gameplatform.server.service.device;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gameplatform.server.model.dto.device.DeviceStatusResponse;
import com.gameplatform.server.service.admin.SystemConfigService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

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

/**
 * 设备状态服务
 *
 * 负责：
 * - 解析设备状态 JSON 字符串为结构化对象
 * - 识别空闲设备（支持配置项定义空闲值）
 * - 提供针对单机的 f0/f1 状态解析辅助方法
 * - 提供按系列分组和筛选空闲设备的便捷方法
 */
@Service
public class DeviceStatusService {
    private static final Logger log = LoggerFactory.getLogger(DeviceStatusService.class);
    
    private final ObjectMapper objectMapper;
    private final SystemConfigService systemConfigService;
    
    // 设备编号解析正则
    private static final Pattern DEVICE_PATTERN = Pattern.compile("^(f|s|g|d|ss|gg)(\\d+)$");
    
    public DeviceStatusService(ObjectMapper objectMapper, SystemConfigService systemConfigService) {
        this.objectMapper = objectMapper;
        this.systemConfigService = systemConfigService;
    }
    
    /**
     * 解析设备状态 JSON 响应。
     *
     * 输入 JSON 示例（简化）：
     * {
     *   "f1": { "val": "已运行", "time": "2025-09-15 10:00:00" },
     *   "f2": { "val": "正在登录中", "time": "2025-09-15 10:00:02" },
     *   "s1": { "val": "123", "time": "2025-09-15 10:01:00" }
     * }
     * 其中 val 可能取值：数字（积分/进度）、"正在登录中"、"已运行"、"已打完"、"空的"、"空闲" 等。
     */
    public DeviceStatusResponse parseDeviceStatus(String jsonResponse) {
        try {
            log.debug("开始解析设备状态响应，长度={} 字符", jsonResponse != null ? jsonResponse.length() : 0);
            
            JsonNode rootNode = objectMapper.readTree(jsonResponse);
            Map<String, DeviceStatusResponse.DeviceInfo> devices = new HashMap<>();
            List<String> availableDevices = new ArrayList<>();
            
            // 遍历所有设备节点，逐个解析
            Iterator<Map.Entry<String, JsonNode>> fields = rootNode.fields();
            while (fields.hasNext()) {
                Map.Entry<String, JsonNode> field = fields.next();
                String deviceId = field.getKey();
                JsonNode deviceNode = field.getValue();
                
                // 解析设备信息（含系列、序号、是否空闲）
                DeviceStatusResponse.DeviceInfo deviceInfo = parseDeviceInfo(deviceId, deviceNode);
                devices.put(deviceId, deviceInfo);
                
                // 检查是否空闲
                if (deviceInfo.isAvailable()) {
                    availableDevices.add(deviceId);
                }
            }
            
            // 构建响应
            DeviceStatusResponse response = new DeviceStatusResponse();
            response.setDevices(devices);
            response.setAvailableDevices(availableDevices);
            response.setTotalDevices(devices.size());
            response.setAvailableCount(availableDevices.size());
            
            log.info("设备状态解析完成: total={} availableCount={} availableDevices={}",
                    response.getTotalDevices(), response.getAvailableCount(), availableDevices);
            
            return response;
            
        } catch (JsonProcessingException e) {
            log.error("解析设备状态JSON失败: {}", e.getMessage(), e);
            throw new RuntimeException("解析设备状态失败", e);
        }
    }
    
    /**
     * 解析单个设备信息。
     * - 识别设备系列与序号
     * - 计算是否空闲（依赖配置项）
     */
    private DeviceStatusResponse.DeviceInfo parseDeviceInfo(String deviceId, JsonNode deviceNode) {
        DeviceStatusResponse.DeviceInfo deviceInfo = new DeviceStatusResponse.DeviceInfo();
        deviceInfo.setDeviceId(deviceId);
        
        // 解析val和time
        String val = deviceNode.get("val").asText();
        String time = deviceNode.get("time").asText();
        deviceInfo.setVal(val);
        deviceInfo.setTime(time);
        
        // 解析设备系列和序号
        parseDeviceIdComponents(deviceId, deviceInfo);
        
        // 判断是否空闲
        boolean available = isDeviceAvailable(val);
        deviceInfo.setAvailable(available);
        
//        log.debug("解析设备信息: id={} val='{}' time='{}' available={} series={} index={}",
//                deviceId, val, time, available, deviceInfo.getSeries(), deviceInfo.getIndex());
        
        return deviceInfo;
    }
    
    /**
     * 解析设备编号的组成部分。
     * 支持的前缀：f/s/g/d/ss/gg，后缀为数字序号。
     */
    private void parseDeviceIdComponents(String deviceId, DeviceStatusResponse.DeviceInfo deviceInfo) {
        Matcher matcher = DEVICE_PATTERN.matcher(deviceId);
        if (matcher.matches()) {
            String series = matcher.group(1);
            String indexStr = matcher.group(2);
            
            deviceInfo.setSeries(series);
            try {
                deviceInfo.setIndex(Integer.parseInt(indexStr));
            } catch (NumberFormatException e) {
                log.warn("解析设备序号失败: id={} indexStr='{}'", deviceId, indexStr);
                deviceInfo.setIndex(null);
            }
        } else {
            deviceInfo.setSeries(null);
            deviceInfo.setIndex(null);
        }
    }
    
    /**
     * 判断设备是否空闲。
     * 依据系统配置 `deviceIdleStatus` 的值进行比对。
     * 约定：返回 true 表示设备可分配使用。
     */
    private boolean isDeviceAvailable(String val) {
        String idleStatus = systemConfigService.getDeviceIdleStatus();
        return idleStatus.equals(val);
    }

    /**
     * 解析特定设备的状态信息（用于检查是否完成/或提取分数）。
     * @param jsonResponse JSON字符串
     * @param machineId 设备ID
     * @return 返回 map，可能包含键 f0(分数) 与 f1(状态)。
     */
    public Map<String, Object> parseDeviceStatusForMachine(String jsonResponse, String machineId) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            log.debug("解析设备状态：id={}，payloadLen={}", machineId, jsonResponse != null ? jsonResponse.length() : 0);
            
            JsonNode rootNode = objectMapper.readTree(jsonResponse);
            
            // 查找指定设备的信息
            JsonNode deviceNode = rootNode.get(machineId);
            if (deviceNode == null) {
                log.warn("未找到设备状态节点：id={}", machineId);
                return result;
            }
            
            // 解析f0(点数)和f1(状态)等信息
            String val = deviceNode.get("val").asText();
            String time = deviceNode.get("time").asText();
            
            // 构建f0和f1格式的返回数据
            Map<String, Object> f0Info = new HashMap<>();
            Map<String, Object> f1Info = new HashMap<>();
            
            // 假设val包含点数信息，f1包含状态信息
            // 根据实际API响应格式调整
            if (val.matches("\\d+")) {
                // 如果val是数字，则认为是点数
                f0Info.put("val", val);
                f0Info.put("time", time);
                result.put("f0", f0Info);
                
                // 状态信息需要额外获取，这里先设置默认值
                String idleStatus = systemConfigService.getDeviceIdleStatus();
                f1Info.put("val", idleStatus); // 如果能获取到点数，可能表示空闲
                f1Info.put("time", time);
                result.put("f1", f1Info);
            } else {
                // 如果val不是数字，可能是状态信息
                f1Info.put("val", val);
                f1Info.put("time", time);
                result.put("f1", f1Info);
            }
            
            log.debug("设备状态解析完成：id={} result={}", machineId, result);
            
        } catch (JsonProcessingException e) {
            log.error("设备状态JSON解析失败：id={} err={}", machineId, e.getMessage(), e);
        } catch (Exception e) {
            log.error("解析设备状态发生异常：id={}", machineId, e);
        }
        
        return result;
    }
    
    /**
     * 按系列分组空闲设备
     */
    public Map<String, List<String>> groupAvailableDevicesBySeries(DeviceStatusResponse deviceStatus) {
        Map<String, List<String>> groupedDevices = new HashMap<>();
        
        for (String deviceId : deviceStatus.getAvailableDevices()) {
            DeviceStatusResponse.DeviceInfo deviceInfo = deviceStatus.getDevices().get(deviceId);
            if (deviceInfo != null && deviceInfo.getSeries() != null) {
                String series = deviceInfo.getSeries();
                groupedDevices.computeIfAbsent(series, k -> new ArrayList<>()).add(deviceId);
            }
        }
        
        return groupedDevices;
    }
    
    /**
     * 获取指定系列的空闲设备
     */
    public List<String> getAvailableDevicesBySeries(DeviceStatusResponse deviceStatus, String series) {
        return deviceStatus.getAvailableDevices().stream()
                .filter(deviceId -> {
                    DeviceStatusResponse.DeviceInfo deviceInfo = deviceStatus.getDevices().get(deviceId);
                    return deviceInfo != null && series.equals(deviceInfo.getSeries());
                })
                .sorted() // 按设备编号排序
                .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
    }
}
