package com.openhis.administration.service.impl;

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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.openhis.administration.domain.OutpatientNoSegment;
import com.openhis.administration.mapper.OutpatientNoSegmentMapper;
import com.openhis.administration.service.IOutpatientNoSegmentService;

/**
 * 门诊号码段管理Service实现
 *
 * @author system
 * @date 2025-01-XX
 */
@Service
public class OutpatientNoSegmentServiceImpl implements IOutpatientNoSegmentService {

    @Autowired
    private OutpatientNoSegmentMapper outpatientNoSegmentMapper;

    /**
     * 分页查询门诊号码段列表
     */
    @Override
    public Page<OutpatientNoSegment> selectOutpatientNoSegmentPage(Page<OutpatientNoSegment> page, boolean onlySelf, Long userId) {
        LambdaQueryWrapper<OutpatientNoSegment> queryWrapper = new LambdaQueryWrapper<>();
        
        // 如果不是管理员，只查询自己的号码段
        if (onlySelf && userId != null) {
            queryWrapper.eq(OutpatientNoSegment::getOperatorId, userId);
        }
        
        // 按创建时间正序排列（新记录排在后面）
        queryWrapper.orderByAsc(OutpatientNoSegment::getCreateTime);
        
        return outpatientNoSegmentMapper.selectPage(page, queryWrapper);
    }

    /**
     * 新增门诊号码段
     */
    @Override
    public int insertOutpatientNoSegment(OutpatientNoSegment outpatientNoSegment) {
        return outpatientNoSegmentMapper.insert(outpatientNoSegment);
    }

    /**
     * 修改门诊号码段
     */
    @Override
    public int updateOutpatientNoSegment(OutpatientNoSegment outpatientNoSegment) {
        return outpatientNoSegmentMapper.updateById(outpatientNoSegment);
    }
    
    /**
     * 删除门诊号码段
     */
    @Override
    public int deleteOutpatientNoSegmentByIds(Long[] ids) {
        if (ids == null || ids.length == 0) {
            return 0;
        }
        return outpatientNoSegmentMapper.deleteBatchIds(java.util.Arrays.asList(ids));
    }
    
    /**
     * 根据ID查询门诊号码段
     * 注意：由于 @TableLogic 注解，selectById 会自动过滤已删除的记录（delete_flag = '1'）
     * 这意味着如果记录已经被软删除，此方法会返回 null
     */
    @Override
    public OutpatientNoSegment getById(Long id) {
        System.out.println("=== 查询门诊号码段开始 ===");
        System.out.println("查询ID: " + id);
        System.out.println("ID类型: " + (id != null ? id.getClass().getName() : "null"));
        System.out.println("ID值（字符串）: " + String.valueOf(id));
        
        // 使用 selectById 查询（会自动过滤 delete_flag = '1' 的记录）
        OutpatientNoSegment segment = outpatientNoSegmentMapper.selectById(id);
        
        if (segment != null) {
            System.out.println("查询成功 - 找到记录:");
            System.out.println("  - 记录ID: " + segment.getId());
            System.out.println("  - 操作员ID: " + segment.getOperatorId());
            System.out.println("  - 起始号码: " + segment.getStartNo());
            System.out.println("  - 终止号码: " + segment.getEndNo());
            System.out.println("  - 使用号码: " + segment.getUsedNo());
        } else {
            System.out.println("查询失败 - 未找到记录");
            System.out.println("可能原因：");
            System.out.println("  1. 记录不存在");
            System.out.println("  2. 记录已被软删除（delete_flag = '1'）");
            System.out.println("  3. ID 不匹配");
            
            // 尝试直接查询数据库（包括已删除的记录）来验证记录是否存在
            try {
                LambdaQueryWrapper<OutpatientNoSegment> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(OutpatientNoSegment::getId, id);
                // 注意：这里仍然会受到 @TableLogic 的影响，无法查询已删除的记录
                // 如果需要查询已删除的记录，需要使用原生 SQL 或禁用逻辑删除
                OutpatientNoSegment segmentWithDeleted = outpatientNoSegmentMapper.selectOne(queryWrapper);
                if (segmentWithDeleted != null) {
                    System.out.println("使用 LambdaQueryWrapper 查询结果: 找到记录，ID=" + segmentWithDeleted.getId());
                } else {
                    System.out.println("使用 LambdaQueryWrapper 查询结果: 未找到记录");
                }
            } catch (Exception e) {
                System.out.println("使用 LambdaQueryWrapper 查询时出错: " + e.getMessage());
            }
            
            // 尝试查询所有记录（不限制 delete_flag）来验证 ID 是否存在
            // 注意：由于 @TableLogic，无法直接查询已删除的记录
            // 但我们可以查询所有未删除的记录，看看是否有类似的 ID
            try {
                LambdaQueryWrapper<OutpatientNoSegment> allQuery = new LambdaQueryWrapper<>();
                // 查询所有未删除的记录
                List<OutpatientNoSegment> allSegments = outpatientNoSegmentMapper.selectList(allQuery);
                System.out.println("数据库中所有未删除的记录数: " + allSegments.size());
                System.out.println("所有记录的 ID 列表:");
                for (OutpatientNoSegment seg : allSegments) {
                    System.out.println("  - ID: " + seg.getId() + " (类型: " + seg.getId().getClass().getName() + ")");
                    // 检查是否有接近的 ID（可能是精度问题）
                    if (seg.getId() != null) {
                        String segIdStr = String.valueOf(seg.getId());
                        String searchIdStr = String.valueOf(id);
                        if (segIdStr.length() == searchIdStr.length() && 
                            segIdStr.substring(0, Math.min(10, segIdStr.length())).equals(
                                searchIdStr.substring(0, Math.min(10, searchIdStr.length())))) {
                            System.out.println("    警告：发现相似的 ID！");
                        }
                    }
                }
            } catch (Exception e) {
                System.out.println("查询所有记录时出错: " + e.getMessage());
            }
        }
        
        System.out.println("=== 查询门诊号码段结束 ===");
        return segment;
    }
    
    /**
     * 检查号码段是否重复（全系统范围）
     * 规则：从末位往前找到第一个字母作为前缀，比较前缀和数字范围
     */
    @Override
    public boolean checkNumberSegmentOverlap(String startNo, String endNo, Long excludeId) {
        if (startNo == null || endNo == null) {
            return false;
        }
        
        // 提取前缀（从末位往前找到第一个字母）
        String prefix1 = extractPrefix(startNo);
        String prefix2 = extractPrefix(endNo);
        
        // 前缀必须一致
        if (!prefix1.equals(prefix2)) {
            return false;
        }
        
        // 提取尾部数字
        Long num1 = extractTailNumber(startNo);
        Long num2 = extractTailNumber(endNo);
        
        if (num1 == null || num2 == null || num1 > num2) {
            return false;
        }
        
        // 查询所有相同前缀的号码段
        LambdaQueryWrapper<OutpatientNoSegment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.likeRight(OutpatientNoSegment::getStartNo, prefix1);
        if (excludeId != null) {
            queryWrapper.ne(OutpatientNoSegment::getId, excludeId);
        }
        
        List<OutpatientNoSegment> segments = outpatientNoSegmentMapper.selectList(queryWrapper);
        
        // 检查是否有重叠
        for (OutpatientNoSegment segment : segments) {
            String otherPrefix = extractPrefix(segment.getStartNo());
            if (!prefix1.equals(otherPrefix)) {
                continue;
            }
            
            Long otherNum1 = extractTailNumber(segment.getStartNo());
            Long otherNum2 = extractTailNumber(segment.getEndNo());
            
            if (otherNum1 != null && otherNum2 != null) {
                // 检查范围是否重叠
                if (Math.max(num1, otherNum1) <= Math.min(num2, otherNum2)) {
                    return true;
                }
            }
        }
        
        return false;
    }
    
    /**
     * 从末位往前找到第一个字母，返回前缀（包含该字母）
     */
    private String extractPrefix(String value) {
        if (value == null || value.isEmpty()) {
            return "";
        }
        char[] chars = value.toCharArray();
        for (int i = chars.length - 1; i >= 0; i--) {
            if (Character.isLetter(chars[i])) {
                return value.substring(0, i + 1);
            }
        }
        return "";
    }
    
    /**
     * 提取尾部数字
     */
    private Long extractTailNumber(String value) {
        if (value == null || value.isEmpty()) {
            return null;
        }
        Pattern pattern = Pattern.compile("(\\d+)$");
        Matcher matcher = pattern.matcher(value);
        if (matcher.find()) {
            try {
                return Long.parseLong(matcher.group(1));
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }
}

