package com.openhis.web.lab.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.core.common.core.controller.BaseController;
import com.core.common.core.domain.AjaxResult;
import com.openhis.lab.domain.InspectionType;
import com.openhis.lab.service.IInspectionTypeService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 检验类型管理Controller
 *
 * @author system
 * @date 2025-12-09
 */
@RestController
@RequestMapping("/system/inspection-type")
@Slf4j
@AllArgsConstructor
public class InspectionTypeController extends BaseController {
    
    // 辅助方法：将字节数组转换为十六进制字符串
    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X ", b));
        }
        return sb.toString().trim();
    }

    private final IInspectionTypeService inspectionTypeService;
    private final TransactionTemplate transactionTemplate;

    /**
     * 获取检验类型列表
     */
    @GetMapping("/list")
    public AjaxResult list(InspectionType inspectionType) {
        // 使用Wrapper构建查询条件，确保order字段被正确处理
        QueryWrapper<InspectionType> queryWrapper = new QueryWrapper<>(inspectionType);
        List<InspectionType> list = inspectionTypeService.list(queryWrapper);
        return AjaxResult.success(list);
    }

    /**
     * 获取检验类型详细
     */
    @GetMapping("/{inspectionTypeId}")
    public AjaxResult getInfo(@PathVariable Long inspectionTypeId) {
        return AjaxResult.success(inspectionTypeService.getById(inspectionTypeId));
    }

    /**
     * 新增检验类型
     */
    @PostMapping
    public AjaxResult add(@RequestBody InspectionType inspectionType) {
        // 确保新增时ID为null，强制使用数据库自增序列
        inspectionType.setId(null);
        
        // 去除code字段的前后空格，确保唯一性验证准确
        if (inspectionType.getCode() != null) {
            inspectionType.setCode(inspectionType.getCode().trim());
        }
        
        // 验证code字段是否唯一
        QueryWrapper<InspectionType> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("code", inspectionType.getCode());
        
        // 输出调试信息
        System.out.println("检查编码唯一性：code=" + inspectionType.getCode() + ", 长度=" + inspectionType.getCode().length());
        System.out.println("code的十六进制表示：" + bytesToHex(inspectionType.getCode().getBytes()));
        
        // 直接查询具体记录，而不仅仅是计数
        List<InspectionType> existingRecords = inspectionTypeService.list(queryWrapper);
        System.out.println("数据库中存在的记录数：" + existingRecords.size());
        for (InspectionType record : existingRecords) {
            System.out.println("已存在记录：id=" + record.getId() + ", code=" + record.getCode() + ", code长度=" + record.getCode().length() + ", code十六进制=" + bytesToHex(record.getCode().getBytes()));
        }
        
        if (!existingRecords.isEmpty()) {
            return AjaxResult.error("检验类型编码已存在");
        }
        
        // 保存前再次验证
        System.out.println("准备保存数据：" + inspectionType);
        
        try {
            // 使用事务确保一致性
            return transactionTemplate.execute(status -> {
                // 再次检查，防止并发问题
                QueryWrapper<InspectionType> checkWrapper = new QueryWrapper<>();
                checkWrapper.eq("code", inspectionType.getCode());
                List<InspectionType> finalCheck = inspectionTypeService.list(checkWrapper);
                if (!finalCheck.isEmpty()) {
                    return AjaxResult.error("检验类型编码已存在");
                }
                
                boolean result = inspectionTypeService.save(inspectionType);
                System.out.println("保存结果：" + result);
                return toAjax(result);
            });
        } catch (Exception e) {
            System.out.println("保存失败，错误信息：" + e.getMessage());
            
            // 捕获唯一性约束冲突异常
            if (e.getMessage().contains("uk_inspection_type_code") || 
                e.getMessage().contains("duplicate key value") || 
                e.getMessage().contains("检验类型编码已存在")) {
                return AjaxResult.error("检验类型编码已存在");
            }
            
            return AjaxResult.error("保存失败：" + e.getMessage());
        }
    }

    /**
     * 修改检验类型
     */
    @PutMapping
    public AjaxResult edit(@RequestBody InspectionType inspectionType) {
        // 去除code字段的前后空格，确保唯一性验证准确
        if (inspectionType.getCode() != null) {
            inspectionType.setCode(inspectionType.getCode().trim());
        }
        
        // 验证code字段是否唯一（排除自身）
        QueryWrapper<InspectionType> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("code", inspectionType.getCode())
                   .ne("id", inspectionType.getId());
        if (inspectionTypeService.count(queryWrapper) > 0) {
            return AjaxResult.error("检验类型编码已存在");
        }
        
        try {
            boolean result = inspectionTypeService.updateById(inspectionType);
            return toAjax(result);
        } catch (Exception e) {
            // 捕获唯一性约束冲突异常
            if (e.getMessage().contains("uk_inspection_type_code") || 
                e.getMessage().contains("duplicate key value") || 
                e.getMessage().contains("检验类型编码已存在")) {
                return AjaxResult.error("检验类型编码已存在");
            }
            
            return AjaxResult.error("更新失败：" + e.getMessage());
        }
    }

    /**
     * 删除检验类型
     */
    @DeleteMapping("/{inspectionTypeId}")
    public AjaxResult remove(@PathVariable Long inspectionTypeId) {
        log.info("删除检验类型，ID: {}", inspectionTypeId);
        try {
            // 检查记录是否存在
            InspectionType existing = inspectionTypeService.getById(inspectionTypeId);
            log.info("删除前检查记录是否存在: {}", existing != null);
            
            if (existing == null) {
                log.warn("删除失败：检验类型ID: {} 不存在", inspectionTypeId);
                return AjaxResult.error("删除失败: 记录不存在");
            }
            
            // 使用MyBatis Plus的removeById方法执行逻辑删除
            boolean result = inspectionTypeService.removeById(inspectionTypeId);
            log.info("逻辑删除检验类型结果: {}", result);
            
            AjaxResult response = toAjax(result);
            log.info("删除响应: {}", response);
            return response;
        } catch (Exception e) {
            log.error("删除检验类型失败，ID: {}, 错误: {}", inspectionTypeId, e.getMessage(), e);
            return AjaxResult.error("删除失败: " + e.getMessage());
        }
    }
    
    // 测试删除接口，直接返回成功
    @DeleteMapping("/test-delete/{id}")
    public AjaxResult testDelete(@PathVariable Long id) {
        log.info("测试删除接口，ID: {}", id);
        return AjaxResult.success("测试删除成功");
    }
}