package org.example.service;

import org.example.config.CacheConstants;
import org.example.entity.Bed;
import org.example.mapper.BedMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 床位服务
 */
@Service
public class BedService {

    @Autowired
    private BedMapper bedMapper;

    /**
     * 查询床位列表
     */
    @Cacheable(value = CacheConstants.CACHE_BED, key = "'list:' + #code + ':' + #belongDept + ':' + #belongWard + ':' + #belongRoom")
    public List<Bed> findList(String code, String belongDept, String belongWard, String belongRoom) {
        return bedMapper.findList(code, belongDept, belongWard, belongRoom);
    }

    /**
     * 根据ID查询床位
     */
    @Cacheable(value = CacheConstants.CACHE_BED, key = "'id:' + #id")
    public Bed findById(Long id) {
        return bedMapper.findById(id);
    }

    /**
     * 保存床位
     */
    @CacheEvict(value = {CacheConstants.CACHE_BED, CacheConstants.CACHE_OPTIONS}, allEntries = true)
    public void save(Bed bed) {
        if (bed.getOutCode() == null || bed.getOutCode().isEmpty()) {
            bed.setOutCode(bed.getCode());
        }
        if (bed.getId() == null) {
            bedMapper.insert(bed);
        } else {
            bedMapper.update(bed);
        }
    }

    /**
     * 批量设置床位代码
     * @return 返回设置失败的信息
     */
    @CacheEvict(value = CacheConstants.CACHE_BED, allEntries = true)
    public List<String> batchSetCode(List<Long> ids, List<String> codes) {
        List<String> errors = new ArrayList<>();
        
        for (int i = 0; i < ids.size(); i++) {
            Long id = ids.get(i);
            String code = codes.get(i);
            
            // 格式化代码为三位数字
            code = formatCode(code);
            
            // 校验代码格式
            if (!code.matches("^\\d{3}$")) {
                Bed bed = bedMapper.findById(id);
                errors.add("床位[" + (bed != null ? bed.getName() : id) + "]代码格式错误，应为001~999");
                continue;
            }
            
            // 获取床位信息以获取所属病区
            Bed bed = bedMapper.findById(id);
            if (bed == null) {
                errors.add("床位ID[" + id + "]不存在");
                continue;
            }
            
            // 校验同病区下代码是否重复
            Bed existing = bedMapper.findByCodeAndWard(code, bed.getBelongWard());
            if (existing != null && !existing.getId().equals(id)) {
                errors.add("床位[" + bed.getName() + "]代码[" + code + "]在病区[" + bed.getBelongWard() + "]下已被使用");
                continue;
            }
            
            // 更新代码
            bedMapper.updateCode(id, code);
        }
        
        return errors;
    }

    /**
     * 格式化床位代码为三位数字
     */
    private String formatCode(String code) {
        if (code == null || code.isEmpty()) {
            return "000";
        }
        // 去除非数字字符
        code = code.replaceAll("\\D", "");
        if (code.isEmpty()) {
            return "000";
        }
        int num = Integer.parseInt(code);
        if (num > 999) num = 999;
        if (num < 0) num = 0;
        return String.format("%03d", num);
    }

    /**
     * 删除床位
     */
    @CacheEvict(value = {CacheConstants.CACHE_BED, CacheConstants.CACHE_OPTIONS}, allEntries = true)
    public void deleteById(Long id) {
        bedMapper.deleteById(id);
    }

    /**
     * 获取所有不重复的所属科室
     */
    @Cacheable(value = CacheConstants.CACHE_OPTIONS, key = "'bed:dept'")
    public List<String> findAllBelongDept() {
        return bedMapper.findAllBelongDept();
    }

    /**
     * 根据科室获取病区列表
     */
    @Cacheable(value = CacheConstants.CACHE_OPTIONS, key = "'bed:ward:' + #belongDept")
    public List<String> findWardsByDept(String belongDept) {
        return bedMapper.findWardsByDept(belongDept);
    }

    /**
     * 根据病区获取病房列表
     */
    @Cacheable(value = CacheConstants.CACHE_OPTIONS, key = "'bed:room:' + #belongWard")
    public List<String> findRoomsByWard(String belongWard) {
        return bedMapper.findRoomsByWard(belongWard);
    }
}
