package com.aucma.base.service.impl;

import java.util.*;

import com.aucma.common.utils.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.aucma.base.mapper.BaseDeviceParamValMapper;
import com.aucma.base.domain.BaseDeviceParamVal;
import com.aucma.base.service.IBaseDeviceParamValService;

/**
 * 设备工艺参数当前值Service业务层处理
 * 
 * @author zch
 * @date 2025-10-15
 */
@Service
public class BaseDeviceParamValServiceImpl implements IBaseDeviceParamValService
{
    private static final Logger log = LoggerFactory.getLogger(BaseDeviceParamValServiceImpl.class);

    @Autowired
    private BaseDeviceParamValMapper baseDeviceParamValMapper;

    /**
     * 查询设备工艺参数当前值
     * 
     * @param recordId 设备工艺参数当前值主键
     * @return 设备工艺参数当前值
     */
    @Override
    public BaseDeviceParamVal selectBaseDeviceParamValByRecordId(Long recordId)
    {
        return baseDeviceParamValMapper.selectBaseDeviceParamValByRecordId(recordId);
    }

    /**
     * 查询设备工艺参数当前值列表
     * 
     * @param baseDeviceParamVal 设备工艺参数当前值
     * @return 设备工艺参数当前值
     */
    @Override
    public List<BaseDeviceParamVal> selectBaseDeviceParamValList(BaseDeviceParamVal baseDeviceParamVal)
    {
        return baseDeviceParamValMapper.selectBaseDeviceParamValList(baseDeviceParamVal);
    }

    /**
     * 查询每设备每参数的最新记录列表（聚合最新值）
     *
     * @param baseDeviceParamVal 查询条件
     * @return 最新记录集合
     */
    @Override
    public List<BaseDeviceParamVal> selectLatestBaseDeviceParamValList(BaseDeviceParamVal baseDeviceParamVal)
    {
        try {
            // 入参为空直接返回，调用侧可据此判定为无效请求
        if (baseDeviceParamVal == null) {
                baseDeviceParamVal = new BaseDeviceParamVal();
            }
            // 防止全表扫描：若未指定时间范围，默认查询最近24小时
            if (baseDeviceParamVal.getBeginTime() == null && baseDeviceParamVal.getEndTime() == null) {
                Date end = new Date();
                Date begin = DateUtils.addHours(end, -24);
                baseDeviceParamVal.setBeginTime(begin);
                baseDeviceParamVal.setEndTime(end);
            }
            List<BaseDeviceParamVal> list = baseDeviceParamValMapper.selectLatestBaseDeviceParamValList(baseDeviceParamVal);
            return list != null ? list : Collections.emptyList();
        } catch (Exception e) {
            log.error("查询设备参数最新值失败: {}", e.getMessage());
            return Collections.emptyList();
        }
    }

    /**
     * 新增设备工艺参数当前值
     * 
     * @param baseDeviceParamVal 设备工艺参数当前值
     * @return 结果
     */
    @Override
    public int insertBaseDeviceParamVal(BaseDeviceParamVal baseDeviceParamVal)
    {
        // 当天无记录时再插入，兼容首次上报场景
        return baseDeviceParamValMapper.insertBaseDeviceParamVal(baseDeviceParamVal);
    }

    /**
     * 修改设备工艺参数当前值
     * 
     * @param baseDeviceParamVal 设备工艺参数当前值
     * @return 结果
     */
    @Override
    public int updateBaseDeviceParamVal(BaseDeviceParamVal baseDeviceParamVal)
    {
        return baseDeviceParamValMapper.updateBaseDeviceParamVal(baseDeviceParamVal);
    }

    /**
     * 批量删除设备工艺参数当前值
     * 
     * @param recordIds 需要删除的设备工艺参数当前值主键
     * @return 结果
     */
    @Override
    public int deleteBaseDeviceParamValByRecordIds(Long[] recordIds)
    {
        return baseDeviceParamValMapper.deleteBaseDeviceParamValByRecordIds(recordIds);
    }

    /**
     * 删除设备工艺参数当前值信息
     * 
     * @param recordId 设备工艺参数当前值主键
     * @return 结果
     */
    @Override
    public int deleteBaseDeviceParamValByRecordId(Long recordId)
    {
        return baseDeviceParamValMapper.deleteBaseDeviceParamValByRecordId(recordId);
    }

    /**
     * 查询设备状态统计（基于三色灯参数）
     *
     * @return 设备状态统计Map
     */
    @Override
    public Map<String, Object> selectDeviceStatusStatistics()
    {
        try {
            Map<String, Object> result = baseDeviceParamValMapper.selectDeviceStatusStatistics();
            if (result == null) {
                result = new HashMap<>();
                result.put("totalCount", 0);//从base_deviceledger中获取is_flag = 1
                result.put("runningCount", 0);//机台状态-三色灯机器运行
                result.put("stoppedCount", 0);//三色灯机器暂停
                result.put("standbyCount", 0);//三色灯机器待机
                result.put("alarmCount", 0);//三色灯机器报警
                result.put("notStartedCount", 0);//t.totalCount - s.runningCount - s.stoppedCount - s.standbyCount - s.alarmCount AS notStartedCount
                result.put("runningRate", "0%");
                return result;
            }
            // 计算开机率
            Object totalObj = result.get("TOTALCOUNT");
            Object runningObj = result.get("RUNNINGCOUNT");
            int total = totalObj != null ? ((Number) totalObj).intValue() : 0;
            int running = runningObj != null ? ((Number) runningObj).intValue() : 0;
            String runningRate = total > 0 ? String.format("%.2f%%", (running * 100.0 / total)) : "0%";
            result.put("runningRate", runningRate);
            return result;
        } catch (Exception e) {
            log.error("查询设备状态统计失败: {}", e.getMessage());
            Map<String, Object> result = new HashMap<>();
            result.put("totalCount", 0);
            result.put("runningCount", 0);
            result.put("stoppedCount", 0);
            result.put("standbyCount", 0);
            result.put("notStartedCount", 0);
            result.put("runningRate", "0%");
            return result;
        }
    }

    /**
     * 获取每个设备的编号、名称、三色灯状态
     *
     * @return 设备状态列表
     */
    @Override
    public List<Map<String, Object>> selectDeviceStatusList()
    {
        try {
            List<Map<String, Object>> list = baseDeviceParamValMapper.selectDeviceStatusList();
            return list != null ? list : Collections.emptyList();
        } catch (Exception e) {
            log.error("查询设备状态列表失败: {}", e.getMessage());
            return Collections.emptyList();
        }
    }

    /**
     * 获取每个设备的开机时间当天最新值
     *
     * @return 设备开机时间列表
     */
    @Override
    public List<Map<String, Object>> selectDeviceStartTimeList()
    {
        try {
            List<Map<String, Object>> list = baseDeviceParamValMapper.selectDeviceStartTimeList();
            return list != null ? list : Collections.emptyList();
        } catch (Exception e) {
            log.error("查询设备开机时间列表失败: {}", e.getMessage());
            return Collections.emptyList();
        }
    }

    /**
     * 参数追溯查询（按时间范围）
     */
    @Override
    public List<BaseDeviceParamVal> selectTraceList(String deviceCode, String paramCode, String startTime, String endTime) {
        try {
            // mapper层使用Map入参，便于只携带本次upsert所需字段
        Map<String, Object> params = new HashMap<>();
            params.put("deviceCode", deviceCode);
            params.put("paramCode", paramCode);
            params.put("startTime", startTime);
            params.put("endTime", endTime);
            List<BaseDeviceParamVal> list = baseDeviceParamValMapper.selectTraceList(params);
            return list != null ? list : Collections.emptyList();
        } catch (Exception e) {
            log.error("参数追溯查询失败: {}", e.getMessage());
            return Collections.emptyList();
        }
    }

    /**
     * 获取SPC分析数据
     */
    @Override
    public Map<String, Object> getSPCData(String deviceCode, String paramCode, String startTime, String endTime) {
        Map<String, Object> result = new HashMap<>();
        result.put("deviceCode", deviceCode);
        result.put("paramCode", paramCode);

        try {
            // 查询参数名称
            String paramName = baseDeviceParamValMapper.selectParamNameByCode(paramCode);
            result.put("paramName", paramName != null ? paramName : paramCode);

            // 查询参数历史值
            // mapper层使用Map入参，便于只携带本次upsert所需字段
        Map<String, Object> params = new HashMap<>();
            params.put("deviceCode", deviceCode);
            params.put("paramCode", paramCode);
            params.put("startTime", startTime);
            params.put("endTime", endTime);
            List<Double> values = baseDeviceParamValMapper.selectParamHistoryValues(params);

            if (values == null || values.isEmpty()) {
                result.put("values", new ArrayList<>());
                result.put("sampleSize", 0);
                result.put("mean", 0.0);
                result.put("stdDev", 0.0);
                result.put("cpk", 0.0);
                result.put("ucl", 0.0);
                result.put("lcl", 0.0);
                result.put("cl", 0.0);
                return result;
            }

            result.put("values", values);
            result.put("sampleSize", values.size());

            // 计算统计指标
            double mean = calculateMean(values);
            double stdDev = calculateStdDev(values, mean);
            double ucl = mean + 3 * stdDev;
            double lcl = mean - 3 * stdDev;

            result.put("mean", Math.round(mean * 1000.0) / 1000.0);
            result.put("stdDev", Math.round(stdDev * 1000.0) / 1000.0);
            result.put("ucl", Math.round(ucl * 1000.0) / 1000.0);
            result.put("lcl", Math.round(lcl * 1000.0) / 1000.0);
            result.put("cl", Math.round(mean * 1000.0) / 1000.0);

            // 计算CPK（假设规格限为均值±10%）
            double usl = mean * 1.1;
            double lsl = mean * 0.9;
            double cpk = calculateCPK(mean, stdDev, usl, lsl);
            result.put("cpk", Math.round(cpk * 100.0) / 100.0);
            result.put("usl", Math.round(usl * 1000.0) / 1000.0);
            result.put("lsl", Math.round(lsl * 1000.0) / 1000.0);

            return result;
        } catch (Exception e) {
            log.error("获取SPC分析数据失败: {}", e.getMessage());
            result.put("error", e.getMessage());
            return result;
        }
    }


    /**
     * 按设备与参数直接新增一条数据（不覆盖当天历史记录）
     */
    @Override
    public int upsertTodayParamValue(BaseDeviceParamVal baseDeviceParamVal)
    {
        // 入参为空直接返回，调用侧可据此判定为无效请求
        if (baseDeviceParamVal == null) {
            return 0;
        }
        // 若调用方未传时间，统一回填服务端当前时间，避免空时间导致SQL匹配偏差
        Date now = new Date();
        if (baseDeviceParamVal.getCollectTime() == null) {
            baseDeviceParamVal.setCollectTime(now);
        }
        if (baseDeviceParamVal.getRecordTime() == null) {
            baseDeviceParamVal.setRecordTime(now);
        }

        // Why：PDA上报需要沉淀完整过程数据，后续分析依赖时间序列，不能覆盖当天已有记录
        return baseDeviceParamValMapper.insertBaseDeviceParamVal(baseDeviceParamVal);
    }
    private double calculateMean(List<Double> values) {
        if (values == null || values.isEmpty()) return 0.0;
        double sum = 0.0;
        for (Double v : values) {
            if (v != null) sum += v;
        }
        return sum / values.size();
    }

    private double calculateStdDev(List<Double> values, double mean) {
        if (values == null || values.size() < 2) return 0.0;
        double sumSquares = 0.0;
        for (Double v : values) {
            if (v != null) {
                sumSquares += Math.pow(v - mean, 2);
            }
        }
        return Math.sqrt(sumSquares / (values.size() - 1));
    }

    private double calculateCPK(double mean, double stdDev, double usl, double lsl) {
        if (stdDev == 0) return 0.0;
        double cpupper = (usl - mean) / (3 * stdDev);
        double cplower = (mean - lsl) / (3 * stdDev);
        return Math.min(cpupper, cplower);
    }
}



