package com.ruoyi.web.calculate.service.impl;

import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
// import com.ruoyi.web.calculate.mapper.CmcGaussPositiveMapper;
import com.ruoyi.web.calculate.domain.CmcEleDifSideLandDir;
import com.ruoyi.web.calculate.service.ICmcEleDifSideLandDirService;

/**
 * 高差边长方向值服务实现
 * 
 * @author R
 * @date 2026-06-12
 */
@Service
public class CmcEleDifSideLandDirServiceImpl implements ICmcEleDifSideLandDirService {
    /**
     * 导入Excel数据（支持多个工作表）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult importExcelData(MultipartFile file, List<String> sheetNames) {
        return importExcelData(file, sheetNames, null);
    }
    
    /**
     * 导入Excel数据（支持多个工作表和列映射）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult importExcelData(MultipartFile file, List<String> sheetNames, String columnMappingsJson) {
        // 解析列映射配置
        Map<String, Map<String, Integer>> columnMappings = null;
        if (columnMappingsJson != null && !columnMappingsJson.isEmpty()) {
            try {
                ObjectMapper mapper = new ObjectMapper();
                columnMappings = mapper.readValue(columnMappingsJson, 
                    new TypeReference<Map<String, Map<String, Integer>>>() {});
            } catch (Exception e) {
                // 解析失败，使用默认映射
            }
        }
        try {
            // 存储每个工作表的数据
            List<Map<String, Object>> sheetDataList = new ArrayList<>();
            
            // 合并所有工作表的数据用于计算
            List<CmcEleDifSideLandDir> allDataList = new ArrayList<>();
            
            List<String> targetSheetNames;
            
            // 判断是否指定了工作表
            if (sheetNames != null && !sheetNames.isEmpty()) {
                targetSheetNames = sheetNames;
            } else {
                // 如果未指定，读取所有工作表
                targetSheetNames = getSheetNames(file);
            }
            
            // 获取当前工作表的列映射
            Map<String, Integer> currentMapping = null;
            
            // 读取指定的多个工作表
            for (String sheetName : targetSheetNames) {
                // 获取当前工作表的列映射配置
                if (columnMappings != null && columnMappings.containsKey(sheetName)) {
                    currentMapping = columnMappings.get(sheetName);
                } else {
                    currentMapping = null;
                }
                
                List<CmcEleDifSideLandDir> sheetData = importExcelFromSheet(file, sheetName, currentMapping);
                List<String> headers = readSheetHeaders(file, sheetName);
                List<List<Object>> rawData = readRawSheetData(file, sheetName);
                if (sheetData != null && !sheetData.isEmpty()) {
                    // 按工作表分组存储
                    Map<String, Object> sheetInfo = new HashMap<>();
                    sheetInfo.put("sheetName", sheetName);
                    sheetInfo.put("headers", headers);
                    sheetInfo.put("rawData", rawData);
                    sheetInfo.put("data", convertToMapList(sheetData));
                    sheetDataList.add(sheetInfo);
                    
                    // 添加到合并列表用于后续计算
                    allDataList.addAll(sheetData);
                }
            }

            // 检查是否有数据
            if (allDataList == null || allDataList.isEmpty()) {
                return AjaxResult.error("Excel文件中没有数据！");
            }

            // 将数据分为两组：点信息组 和 方向信息组
            // 第一组：ipointNumber, pointName, cpX, cpY, cpZ（点的基本信息）
            // 第二组：stationPN, directionPN（测站和方向信息）
            
            List<Map<String, Object>> pointDataList = new ArrayList<>();  // 点信息组
            List<Map<String, Object>> directionDataList = new ArrayList<>();  // 方向信息组
            
            int pointCount = 0;
            int directionCount = 0;
            StringBuilder errorMsg = new StringBuilder();

            for (int i = 0; i < allDataList.size(); i++) {
                CmcEleDifSideLandDir item = allDataList.get(i);

                try {
                    // 判断是点信息还是方向信息
                    boolean hasPointInfo = item.getPointNumber() != null && !item.getPointNumber().isEmpty();
                    boolean hasDirectionInfo = item.getStationPN() != null && item.getDirectionPN() != null;
                    
                    // 如果有点号，作为点信息处理
                    if (hasPointInfo) {
                        Map<String, Object> pointMap = new HashMap<>();
                        pointMap.put("pointNumber", item.getPointNumber());
                        pointMap.put("pointName", item.getPointName());
                        pointMap.put("cpX", item.getCPX());
                        pointMap.put("cpY", item.getCPY());
                        pointMap.put("cpZ", item.getCPZ());
                        pointMap.put("rowNum", i + 2); // Excel中的行号
                        pointDataList.add(pointMap);
                        pointCount++;
                    }
                    
                    // 如果有测站和方向序号，作为方向信息处理
                    if (hasDirectionInfo) {
                        Map<String, Object> directionMap = new HashMap<>();
                        directionMap.put("pointNumber", item.getPointNumber()); // 关联的点号（可能为空）
                        directionMap.put("stationPN", item.getStationPN());
                        directionMap.put("directionPN", item.getDirectionPN());
                        directionMap.put("rowNum", i + 2); // Excel中的行号
                        directionDataList.add(directionMap);
                        directionCount++;
                    }
                    
                } catch (Exception e) {
                    errorMsg.append(String.format("第%d行数据验证失败：%s；", i + 2, e.getMessage()));
                }
            }

            // 构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("total", allDataList.size());
            result.put("pointCount", pointCount);
            result.put("directionCount", directionCount);
            result.put("pointData", pointDataList);
            result.put("directionData", directionDataList);
            // 添加按工作表分组的数据
            result.put("sheetData", sheetDataList);

            if (pointCount == 0 && directionCount == 0) {
                return AjaxResult.error("没有有效数据！" + errorMsg.toString());
            }

            String message = String.format("导入成功！共解析%d条数据，其中点信息%d条，方向信息%d条", 
                    allDataList.size(), pointCount, directionCount);
            if (errorMsg.length() > 0) {
                message += "；部分数据验证失败：" + errorMsg.toString();
                return AjaxResult.success(message, result);
            }

            return AjaxResult.success(message, result);

        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("导入失败：" + e.getMessage());
        }
    }
    
    /**
     * 将实体列表转换为Map列表
     */
    private List<Map<String, Object>> convertToMapList(List<CmcEleDifSideLandDir> dataList) {
        List<Map<String, Object>> result = new ArrayList<>();
        for (CmcEleDifSideLandDir item : dataList) {
            Map<String, Object> map = new HashMap<>();
            map.put("pointNumber", item.getPointNumber());
            map.put("pointName", item.getPointName());
            map.put("cpX", item.getCPX());
            map.put("cpY", item.getCPY());
            map.put("cpZ", item.getCPZ());
            map.put("stationPN", item.getStationPN());
            map.put("directionPN", item.getDirectionPN());
            result.add(map);
        }
        return result;
    }

    /**
     * 读取工作表的表头信息
     * 
     * @param file Excel文件
     * @param sheetName 工作表名称
     * @return 表头列表
     */
    private List<String> readSheetHeaders(MultipartFile file, String sheetName) {
        List<String> headers = new ArrayList<>();
        
        try (InputStream inputStream = file.getInputStream();
             Workbook workbook = createWorkbook(inputStream, file.getOriginalFilename())) {
            // 查找指定名称的工作表
            Sheet sheet = workbook.getSheet(sheetName);
            
            if (sheet == null) {
                // 如果按名称找不到，尝试按索引查找
                try {
                    int sheetIndex = Integer.parseInt(sheetName);
                    sheet = workbook.getSheetAt(sheetIndex);
                } catch (NumberFormatException e) {
                    return headers;
                }
            }
            
            if (sheet == null) {
                return headers;
            }
            
            // 读取第一行作为表头
            org.apache.poi.ss.usermodel.Row headerRow = sheet.getRow(0);
            if (headerRow != null) {
                int lastCellNum = headerRow.getLastCellNum();
                for (int i = 0; i < lastCellNum; i++) {
                    headers.add(getCellStringValue(headerRow.getCell(i)));
                }
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return headers;
    }
    
    /**
     * 读取工作表的原始数据（从第二行开始）
     * 
     * @param file Excel文件
     * @param sheetName 工作表名称
     * @return 原始数据列表
     */
    private List<List<Object>> readRawSheetData(MultipartFile file, String sheetName) {
        List<List<Object>> rawData = new ArrayList<>();
        
        try (InputStream inputStream = file.getInputStream();
             Workbook workbook = createWorkbook(inputStream, file.getOriginalFilename())) {
            // 查找指定名称的工作表
            Sheet sheet = workbook.getSheet(sheetName);
            
            if (sheet == null) {
                // 如果按名称找不到，尝试按索引查找
                try {
                    int sheetIndex = Integer.parseInt(sheetName);
                    sheet = workbook.getSheetAt(sheetIndex);
                } catch (NumberFormatException e) {
                    return rawData;
                }
            }
            
            if (sheet == null) {
                return rawData;
            }
            
            // 获取表头列数
            org.apache.poi.ss.usermodel.Row headerRow = sheet.getRow(0);
            int colCount = headerRow != null ? headerRow.getLastCellNum() : 10;
            
            // 从第二行开始读取数据
            int lastRowNum = sheet.getLastRowNum();
            for (int i = 1; i <= lastRowNum; i++) {
                org.apache.poi.ss.usermodel.Row row = sheet.getRow(i);
                if (row == null) continue;
                
                List<Object> rowData = new ArrayList<>();
                for (int j = 0; j < colCount; j++) {
                    rowData.add(getCellStringValue(row.getCell(j)));
                }
                
                // 跳过空行
                boolean hasData = false;
                for (Object obj : rowData) {
                    if (obj != null && !"".equals(obj.toString().trim())) {
                        hasData = true;
                        break;
                    }
                }
                if (hasData) {
                    rawData.add(rowData);
                }
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return rawData;
    }
    
    /**
     * 从指定工作表读取Excel数据
     * 
     * @param file Excel文件
     * @param sheetName 工作表名称
     * @return 数据列表
     */
    private List<CmcEleDifSideLandDir> importExcelFromSheet(MultipartFile file, String sheetName) {
        return importExcelFromSheet(file, sheetName, null);
    }
    
    /**
     * 从指定工作表读取Excel数据（支持列映射）
     * 
     * @param file Excel文件
     * @param sheetName 工作表名称
     * @param columnMapping 列映射配置（字段名 -> 列索引），为空则使用默认映射
     * @return 数据列表
     */
    private List<CmcEleDifSideLandDir> importExcelFromSheet(MultipartFile file, String sheetName, Map<String, Integer> columnMapping) {
        List<CmcEleDifSideLandDir> dataList = new ArrayList<>();
        
        try (InputStream inputStream = file.getInputStream();
             Workbook workbook = createWorkbook(inputStream, file.getOriginalFilename())) {
            // 查找指定名称的工作表
            Sheet sheet = workbook.getSheet(sheetName);
            
            if (sheet == null) {
                // 如果按名称找不到，尝试按索引查找
                try {
                    int sheetIndex = Integer.parseInt(sheetName);
                    sheet = workbook.getSheetAt(sheetIndex);
                } catch (NumberFormatException e) {
                    // 不是数字索引，返回空列表
                    return dataList;
                }
            }
            
            if (sheet == null) {
                return dataList;
            }
            
            // 直接使用POI解析Sheet数据
            int lastRowNum = sheet.getLastRowNum();
            // 从第二行开始读取（跳过表头）
            for (int i = 1; i <= lastRowNum; i++) {
                org.apache.poi.ss.usermodel.Row row = sheet.getRow(i);
                if (row == null) {
                    continue;
                }
                
                CmcEleDifSideLandDir item = new CmcEleDifSideLandDir();
                
                if (columnMapping != null && !columnMapping.isEmpty()) {
                    // 使用自定义列映射
                    int colIndex = columnMapping.getOrDefault("pointNumber", -1);
                    if (colIndex >= 0) {
                        item.setPointNumber(getCellStringValue(row.getCell(colIndex)));
                    }
                    
                    colIndex = columnMapping.getOrDefault("pointName", -1);
                    if (colIndex >= 0) {
                        item.setPointName(getCellStringValue(row.getCell(colIndex)));
                    }
                    
                    colIndex = columnMapping.getOrDefault("cpX", -1);
                    if (colIndex >= 0) {
                        item.setCPX(getCellDoubleValue(row.getCell(colIndex)));
                    }
                    
                    colIndex = columnMapping.getOrDefault("cpY", -1);
                    if (colIndex >= 0) {
                        item.setCPY(getCellDoubleValue(row.getCell(colIndex)));
                    }
                    
                    colIndex = columnMapping.getOrDefault("cpZ", -1);
                    if (colIndex >= 0) {
                        item.setCPZ(getCellDoubleValue(row.getCell(colIndex)));
                    }
                    
                    colIndex = columnMapping.getOrDefault("stationPN", -1);
                    if (colIndex >= 0) {
                        item.setStationPN(getCellIntegerValue(row.getCell(colIndex)));
                    }
                    
                    colIndex = columnMapping.getOrDefault("directionPN", -1);
                    if (colIndex >= 0) {
                        item.setDirectionPN(getCellIntegerValue(row.getCell(colIndex)));
                    }
                } else {
                    // 使用默认列映射：ipointNumber, pointName, cpX, cpY, cpZ, stationPN, directionPN
                    item.setPointNumber(getCellStringValue(row.getCell(0)));
                    item.setPointName(getCellStringValue(row.getCell(1)));
                    item.setCPX(getCellDoubleValue(row.getCell(2)));
                    item.setCPY(getCellDoubleValue(row.getCell(3)));
                    item.setCPZ(getCellDoubleValue(row.getCell(4)));
                    item.setStationPN(getCellIntegerValue(row.getCell(5)));
                    item.setDirectionPN(getCellIntegerValue(row.getCell(6)));
                }
                
                dataList.add(item);
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return dataList;
    }
    
    /**
     * 获取单元格的字符串值
     */
    private String getCellStringValue(org.apache.poi.ss.usermodel.Cell cell) {
        if (cell == null) {
            return null;
        }
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                // 数字类型转字符串，避免科学计数法
                double numValue = cell.getNumericCellValue();
                if (numValue == Math.floor(numValue)) {
                    return String.valueOf((long) numValue);
                }
                return String.valueOf(numValue);
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                try {
                    return cell.getStringCellValue();
                } catch (Exception e) {
                    return String.valueOf(cell.getNumericCellValue());
                }
            default:
                return null;
        }
    }
    
    /**
     * 获取单元格的Double值
     */
    private Double getCellDoubleValue(org.apache.poi.ss.usermodel.Cell cell) {
        if (cell == null) {
            return null;
        }
        switch (cell.getCellType()) {
            case NUMERIC:
                return cell.getNumericCellValue();
            case STRING:
                try {
                    return Double.parseDouble(cell.getStringCellValue().trim());
                } catch (NumberFormatException e) {
                    return null;
                }
            default:
                return null;
        }
    }
    
    /**
     * 获取单元格的Integer值
     */
    private Integer getCellIntegerValue(org.apache.poi.ss.usermodel.Cell cell) {
        if (cell == null) {
            return null;
        }
        switch (cell.getCellType()) {
            case NUMERIC:
                return (int) cell.getNumericCellValue();
            case STRING:
                try {
                    return Integer.parseInt(cell.getStringCellValue().trim());
                } catch (NumberFormatException e) {
                    return null;
                }
            default:
                return null;
        }
    }

    /**
     * 根据文件类型创建Workbook
     */
    private Workbook createWorkbook(InputStream inputStream, String fileName) throws Exception {
        if (fileName != null && fileName.endsWith(".xlsx")) {
            return new XSSFWorkbook(inputStream);
        } else {
            return new HSSFWorkbook(inputStream);
        }
    }

    /**
     * 获取Excel文件的所有工作表名称
     * 
     * @param file Excel文件
     * @return 工作表名称列表
     */
    @Override
    public List<String> getSheetNames(MultipartFile file) {
        List<String> sheetNames = new ArrayList<>();
        
        try (InputStream inputStream = file.getInputStream();
             Workbook workbook = createWorkbook(inputStream, file.getOriginalFilename())) {
            int numberOfSheets = workbook.getNumberOfSheets();
            for (int i = 0; i < numberOfSheets; i++) {
                sheetNames.add(workbook.getSheetName(i));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return sheetNames;
    }

    /**
     * 执行高差边长方向值计算
     */
    @Override
    public List<CmcEleDifSideLandDir> calculateEleDifSideLandDir(List<CmcEleDifSideLandDir> dataList) {
        return calculateEleDifSideLandDir(dataList, null);
    }
    
    /**
     * 执行高差边长方向值计算（带列映射）
     */
    @Override
    public List<CmcEleDifSideLandDir> calculateEleDifSideLandDir(List<CmcEleDifSideLandDir> dataList, Map<String, Map<String, Integer>> columnMappings) {
        // 列映射参数在计算阶段不需要使用，因为数据已经在导入阶段按映射解析好了
        // 这里保留方法签名以兼容接口
        List<CmcEleDifSideLandDir> resultList = new ArrayList<>();
        
        // 第一组：控制网点信息，key 是序号（ipointNumber作为序号）
        // 假设 ipointNumber 是整数序号，用于匹配 stationPN 和 directionPN
        Map<Integer, CmcEleDifSideLandDir> controlPointMap = new HashMap<>();
        
        // 第二组：测站和方向序号对
        List<Map<String, Integer>> stationDirectionList = new ArrayList<>();
        
        for (CmcEleDifSideLandDir item : dataList) {
            try {
                String pointNumber = item.getPointNumber();
                Integer stationPN = item.getStationPN();
                Integer directionPN = item.getDirectionPN();
                
                // 处理第一组：控制网点信息
                // 检查是否有有效的坐标信息（cpX/cpY/cpZ）
                boolean hasCoordinates = item.getCPX() != null || item.getCPY() != null || item.getCPZ() != null;
                
                // 优先使用 pointNumber 作为序号，如果不是数字则尝试使用其他字段
                Integer seqNumber = null;
                if (pointNumber != null && !pointNumber.isEmpty()) {
                    try {
                        seqNumber = Integer.parseInt(pointNumber.trim());
                    } catch (NumberFormatException e) {
                        // 如果点号不是数字格式，尝试使用stationPN作为备选序号
                        if (stationPN != null) {
                            seqNumber = stationPN;
                        } else if (directionPN != null) {
                            seqNumber = directionPN;
                        }
                    }
                } else if (stationPN != null) {
                    // 如果没有pointNumber，使用stationPN作为序号
                    seqNumber = stationPN;
                } else if (directionPN != null) {
                    // 如果没有pointNumber和stationPN，使用directionPN作为序号
                    seqNumber = directionPN;
                }
                
                // 如果有序号且有坐标信息，添加到控制点映射
                if (seqNumber != null && hasCoordinates) {
                    if (!controlPointMap.containsKey(seqNumber)) {
                        CmcEleDifSideLandDir pointData = new CmcEleDifSideLandDir();
                        pointData.setPointNumber(item.getPointNumber());
                        pointData.setPointName(item.getPointName());
                        pointData.setCPX(item.getCPX());
                        pointData.setCPY(item.getCPY());
                        pointData.setCPZ(item.getCPZ());
                        controlPointMap.put(seqNumber, pointData);
                    }
                }
                
                // 处理第二组：测站和方向序号（独立处理，不依赖pointNumber）
                if (stationPN != null && directionPN != null) {
                    Map<String, Integer> stationDir = new HashMap<>();
                    stationDir.put("stationPN", stationPN);
                    stationDir.put("directionPN", directionPN);
                    stationDirectionList.add(stationDir);
                }
                
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        
        // 根据 stationPN 和 directionPN 匹配控制网点坐标
        for (Map<String, Integer> stationDir : stationDirectionList) {
            Integer stationPN = stationDir.get("stationPN");
            Integer directionPN = stationDir.get("directionPN");
            
            CmcEleDifSideLandDir result = new CmcEleDifSideLandDir();
            
            // 设置序号（始终设置，即使匹配失败）
            result.setStationPN(stationPN);
            result.setDirectionPN(directionPN);
            
            // 根据 stationPN 查找测站控制网点坐标
            CmcEleDifSideLandDir stationPoint = controlPointMap.get(stationPN);
            if (stationPoint != null) {
                // 将测站控制网点坐标设置为测站坐标
                result.setSPX(stationPoint.getCPX());
                result.setSPY(stationPoint.getCPY());
                result.setSPZ(stationPoint.getCPZ());
                result.setStationPointName(stationPoint.getPointName());
            }
            
            // 根据 directionPN 查找方向控制网点坐标
            CmcEleDifSideLandDir directionPoint = controlPointMap.get(directionPN);
            if (directionPoint != null) {
                // 将方向控制网点坐标设置为方向坐标
                result.setDPX(directionPoint.getCPX());
                result.setDPY(directionPoint.getCPY());
                result.setDPZ(directionPoint.getCPZ());
                result.setDirectionPointName(directionPoint.getPointName());
            }
            
            // 只要有一个匹配成功就添加到结果（允许部分匹配）
            if (stationPoint != null || directionPoint != null) {
                resultList.add(result);
            }
        }
        
        return resultList;
    }
    
    /**
     * 计算方位角
     * 使用 ATAN2(方向y-测站y, 方向x-测站x) 并转换为度
     * 同一测站号的所有记录使用第一个计算出的方位角值
     * 同时计算角度差：原始方位角 - 复用后的方位角
     * 
     * @param resultList 包含测站坐标和方向坐标的结果列表
     * @return 计算方位角后的结果列表
     */
    public List<CmcEleDifSideLandDir> calculateAzimuthAngle(List<CmcEleDifSideLandDir> resultList) {
        // 缓存每个测站号对应的第一个方位角值
        Map<Integer, Double> stationAzimuthMap = new HashMap<>();
        
        for (CmcEleDifSideLandDir item : resultList) {
            try {
                Integer stationPN = item.getStationPN();
                
                // 如果测站号为空，跳过
                if (stationPN == null) {
                    continue;
                }
                
                Double spX = item.getSPX();
                Double spY = item.getSPY();
                Double dpX = item.getDPX();
                Double dpY = item.getDPY();
                
                // 计算原始方位角
                Double originalAzimuth = null;
                if (spX != null && spY != null && dpX != null && dpY != null) {
                    // 计算坐标差
                    double deltaX = dpX - spX;
                    double deltaY = dpY - spY;
                    
                    // 计算 ATAN2(Δy, Δx)，结果为弧度
                    double azimuthRadians = Math.atan2(deltaY, deltaX);
                    
                    // 转换为度
                    originalAzimuth = Math.toDegrees(azimuthRadians);
                    
                    // 方位角标准化到 0-360 度范围
                    if (originalAzimuth < 0) {
                        originalAzimuth += 360.0;
                    }
                    
                    // 保存原始方位角
                    item.setOriginalAzimuthAngle(originalAzimuth);
                }
                
                // 检查该测站号是否已经有缓存的方位角值
                if (stationAzimuthMap.containsKey(stationPN)) {
                    // 使用缓存的第一个方位角值
                    double reusedAzimuth = stationAzimuthMap.get(stationPN);
                    
                    // 计算角度差：原始方位角 - 复用后的方位角
                    double angleDiff = 0.0;
                    if (originalAzimuth != null) {
                        angleDiff = originalAzimuth - reusedAzimuth;
                        
                        // 如果角度差小于0，则+360，反之保持原样
                        if (angleDiff < 0) {
                            angleDiff += 360.0;
                        }
                        
                        item.setAngleDifference(angleDiff);
                    }
                    
                    // 设置方位角为角度差（直接使用十进制度数）
                    item.setAzimuthAngle(angleDiff);
                } else {
                    // 使用自己计算的方位角作为复用值
                    if (originalAzimuth != null) {
                        // 缓存该测站号的第一个方位角值
                        stationAzimuthMap.put(stationPN, originalAzimuth);
                        
                        // 角度差为 0（自己与自己相同）
                        item.setAngleDifference(0.0);
                        
                        // 第一个方向的方位角（角度差）为0
                        item.setAzimuthAngle(0.0);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return resultList;
    }
}