package com.aegis.resource.equipment.service.impl;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.aegis.common.constant.UserConstants;
import com.aegis.common.exception.ServiceException;
import com.aegis.common.utils.SecurityUtils;
import com.aegis.common.utils.StringUtils;
import com.aegis.resource.equipment.domain.Equipment;
import com.aegis.resource.equipment.domain.EquipmentLog;
import com.aegis.resource.equipment.mapper.ResourceEquipmentMapper;
import com.aegis.resource.equipment.mapper.ResourceEquipmentLogMapper;
import com.aegis.resource.equipment.service.IResourceEquipmentService;

/**
 * 装备Service业务层处理
 * 
 * @author aegis
 */
@Service
public class ResourceEquipmentServiceImpl implements IResourceEquipmentService {

    @Autowired
    private ResourceEquipmentMapper equipmentMapper;

    @Autowired
    private ResourceEquipmentLogMapper equipmentLogMapper;

    /**
     * 查询装备列表
     * 
     * @param equipment 装备信息
     * @return 装备集合
     */
    @Override
    public List<Equipment> selectEquipmentList(Equipment equipment) {
        return equipmentMapper.selectEquipmentList(equipment);
    }

    /**
     * 根据ID查询装备
     * 
     * @param id 装备ID
     * @return 装备信息
     */
    @Override
    public Equipment selectEquipmentById(Long id) {
        return equipmentMapper.selectEquipmentById(id);
    }

    /**
     * 根据队伍ID查询装备列表
     * 
     * @param teamId 队伍ID
     * @return 装备集合
     */
    @Override
    public List<Equipment> selectEquipmentListByTeamId(Long teamId) {
        return equipmentMapper.selectEquipmentListByTeamId(teamId);
    }

    /**
     * 校验装备编码是否唯一
     * 
     * @param equipment 装备信息
     * @return 结果
     */
    @Override
    public boolean checkEquipmentCodeUnique(Equipment equipment) {
        if (StringUtils.isEmpty(equipment.getEquipmentCode())) {
            return UserConstants.UNIQUE; // 装备编码为空时认为唯一（由前端校验非空）
        }
        Long id = StringUtils.isNull(equipment.getId()) ? -1L : equipment.getId();
        Equipment info = equipmentMapper.checkEquipmentCodeUnique(equipment.getEquipmentCode(), id);
        if (StringUtils.isNotNull(info)) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 新增装备
     * 
     * @param equipment 装备信息
     * @return 结果
     */
    @Override
    @Transactional
    public int insertEquipment(Equipment equipment) {
        // 校验装备编码唯一性（检查未删除的记录）
        if (!checkEquipmentCodeUnique(equipment)) {
            throw new ServiceException("新增装备'" + equipment.getEquipmentName() + "'失败，装备编码已存在");
        }
        
        // 检查是否存在已删除的相同编码记录
        Equipment deletedEquipment = equipmentMapper.selectDeletedEquipmentByCode(equipment.getEquipmentCode());
        if (deletedEquipment != null) {
            // 如果存在已删除的记录，则恢复并更新该记录
            equipment.setId(deletedEquipment.getId());
            equipment.setCreateBy(deletedEquipment.getCreateBy()); // 保留原创建人
            String operator = SecurityUtils.getUsername();
            equipment.setUpdateBy(operator);
            equipment.initializeDefaults(operator);
            return equipmentMapper.restoreEquipment(equipment);
        }
        
        // 不存在已删除记录，正常插入新记录
        String operator = SecurityUtils.getUsername();
        equipment.setCreateBy(operator);
        equipment.initializeDefaults(operator);
        return equipmentMapper.insertEquipment(equipment);
    }

    /**
     * 修改装备
     * 
     * @param equipment 装备信息
     * @return 结果
     */
    @Override
    @Transactional
    public int updateEquipment(Equipment equipment) {
        // 校验装备是否存在（包括已删除的记录）
        Equipment oldEquipment = equipmentMapper.selectEquipmentById(equipment.getId());
        if (oldEquipment == null) {
            // 如果未删除的记录不存在，检查是否存在已删除的记录
            Equipment deletedEquipment = equipmentMapper.selectDeletedEquipmentByCode(equipment.getEquipmentCode());
            if (deletedEquipment != null && deletedEquipment.getId().equals(equipment.getId())) {
                // 如果存在已删除的记录且ID匹配，则恢复并更新
                equipment.setCreateBy(deletedEquipment.getCreateBy()); // 保留原创建人
                String operator = SecurityUtils.getUsername();
                equipment.setUpdateBy(operator);
                // 使用领域方法更新字段
                if (StringUtils.isNotEmpty(equipment.getEquipmentName())) {
                    equipment.setEquipmentName(equipment.getEquipmentName());
                }
                if (StringUtils.isNotEmpty(equipment.getEquipmentCode())) {
                    equipment.setEquipmentCode(equipment.getEquipmentCode());
                }
                if (equipment.getTeamId() != null) {
                    equipment.setTeamId(equipment.getTeamId());
                }
                if (equipment.getPurchaseDate() != null) {
                    equipment.setPurchaseDate(equipment.getPurchaseDate());
                }
                if (equipment.getWarrantyDate() != null) {
                    equipment.setWarrantyDate(equipment.getWarrantyDate());
                }
                if (StringUtils.isNotEmpty(equipment.getRemark())) {
                    equipment.setRemark(equipment.getRemark());
                }
                if (StringUtils.isNotEmpty(equipment.getEquipmentType())) {
                    equipment.setEquipmentType(equipment.getEquipmentType());
                }
                if (StringUtils.isNotEmpty(equipment.getBrand())) {
                    equipment.setBrand(equipment.getBrand());
                }
                if (StringUtils.isNotEmpty(equipment.getModel())) {
                    equipment.setModel(equipment.getModel());
                }
                if (StringUtils.isNotEmpty(equipment.getCapabilities())) {
                    equipment.setCapabilities(equipment.getCapabilities());
                }
                if (StringUtils.isNotEmpty(equipment.getStatus())) {
                    equipment.setStatus(equipment.getStatus());
                }
                return equipmentMapper.restoreEquipment(equipment);
            }
            throw new ServiceException("装备不存在");
        }
        
        // 如果装备编码发生变化，检查新车装备编码是否已被使用（包括已删除的记录）
        if (!oldEquipment.getEquipmentCode().equals(equipment.getEquipmentCode())) {
            // 校验新车装备编码唯一性（检查未删除的记录）
            if (!checkEquipmentCodeUnique(equipment)) {
                throw new ServiceException("修改装备'" + equipment.getEquipmentName() + "'失败，装备编码已存在");
            }
            // 检查新车装备编码是否存在已删除的记录
            Equipment deletedEquipmentWithNewCode = equipmentMapper.selectDeletedEquipmentByCode(equipment.getEquipmentCode());
            if (deletedEquipmentWithNewCode != null) {
                throw new ServiceException("修改装备'" + equipment.getEquipmentName() + "'失败，该装备编码已被删除，请先恢复该记录");
            }
        }
        
        String operator = SecurityUtils.getUsername();
        // 使用领域方法更新字段
        if (StringUtils.isNotEmpty(equipment.getEquipmentName()) 
            && !equipment.getEquipmentName().equals(oldEquipment.getEquipmentName())) {
            oldEquipment.rename(equipment.getEquipmentName(), operator);
        }
        if (StringUtils.isNotEmpty(equipment.getEquipmentCode()) 
            && !equipment.getEquipmentCode().equals(oldEquipment.getEquipmentCode())) {
            oldEquipment.changeCode(equipment.getEquipmentCode(), operator);
        }
        if (equipment.getTeamId() != null && !equipment.getTeamId().equals(oldEquipment.getTeamId())) {
            oldEquipment.changeTeam(equipment.getTeamId(), operator);
        }
        if (equipment.getPurchaseDate() != null && !equipment.getPurchaseDate().equals(oldEquipment.getPurchaseDate())) {
            oldEquipment.changePurchaseDate(equipment.getPurchaseDate(), operator);
        }
        if (equipment.getWarrantyDate() != null && !equipment.getWarrantyDate().equals(oldEquipment.getWarrantyDate())) {
            oldEquipment.changeWarrantyDate(equipment.getWarrantyDate(), operator);
        }
        if (StringUtils.isNotEmpty(equipment.getRemark()) 
            && !equipment.getRemark().equals(oldEquipment.getRemark())) {
            oldEquipment.changeRemark(equipment.getRemark(), operator);
        }
        // 直接设置其他字段（因为这些字段没有领域方法）
        if (StringUtils.isNotEmpty(equipment.getEquipmentType())) {
            oldEquipment.setEquipmentType(equipment.getEquipmentType());
        }
        if (StringUtils.isNotEmpty(equipment.getBrand())) {
            oldEquipment.setBrand(equipment.getBrand());
        }
        if (StringUtils.isNotEmpty(equipment.getModel())) {
            oldEquipment.setModel(equipment.getModel());
        }
        if (StringUtils.isNotEmpty(equipment.getCapabilities())) {
            oldEquipment.setCapabilities(equipment.getCapabilities());
        }
        return equipmentMapper.updateEquipment(oldEquipment);
    }

    /**
     * 分配占用（available → busy）
     * 
     * @param id 装备ID
     * @param dispatchId 调度ID（可选）
     * @param eventId 事件ID（可选）
     * @param remark 备注
     * @return 结果
     */
    @Override
    @Transactional
    public int assignEquipment(Long id, Long dispatchId, Long eventId, String remark) {
        Equipment equipment = equipmentMapper.selectEquipmentById(id);
        if (equipment == null) {
            throw new ServiceException("装备不存在");
        }
        String fromStatus = equipment.getStatus();
        String operator = SecurityUtils.getUsername();
        equipment.assign(operator);
        int result = equipmentMapper.updateEquipment(equipment);
        // 记录操作日志
        recordLog(equipment.getId(), "assign", fromStatus, equipment.getStatus(), dispatchId, eventId, remark);
        return result;
    }

    /**
     * 解除占用（busy → available）
     * 
     * @param id 装备ID
     * @param remark 备注
     * @return 结果
     */
    @Override
    @Transactional
    public int releaseEquipment(Long id, String remark) {
        Equipment equipment = equipmentMapper.selectEquipmentById(id);
        if (equipment == null) {
            throw new ServiceException("装备不存在");
        }
        String fromStatus = equipment.getStatus();
        String operator = SecurityUtils.getUsername();
        equipment.release(operator);
        int result = equipmentMapper.updateEquipment(equipment);
        // 记录操作日志
        recordLog(equipment.getId(), "release", fromStatus, equipment.getStatus(), null, null, remark);
        return result;
    }

    /**
     * 送修（available/busy → repair）
     * 
     * @param id 装备ID
     * @param remark 备注
     * @return 结果
     */
    @Override
    @Transactional
    public int sendRepair(Long id, String remark) {
        Equipment equipment = equipmentMapper.selectEquipmentById(id);
        if (equipment == null) {
            throw new ServiceException("装备不存在");
        }
        String fromStatus = equipment.getStatus();
        String operator = SecurityUtils.getUsername();
        equipment.sendRepair(operator);
        int result = equipmentMapper.updateEquipment(equipment);
        // 记录操作日志
        recordLog(equipment.getId(), "send_repair", fromStatus, equipment.getStatus(), null, null, remark);
        return result;
    }

    /**
     * 修复完成（repair → available）
     * 
     * @param id 装备ID
     * @param remark 备注
     * @return 结果
     */
    @Override
    @Transactional
    public int finishRepair(Long id, String remark) {
        Equipment equipment = equipmentMapper.selectEquipmentById(id);
        if (equipment == null) {
            throw new ServiceException("装备不存在");
        }
        String fromStatus = equipment.getStatus();
        String operator = SecurityUtils.getUsername();
        equipment.finishRepair(operator);
        int result = equipmentMapper.updateEquipment(equipment);
        // 记录操作日志
        recordLog(equipment.getId(), "finish_repair", fromStatus, equipment.getStatus(), null, null, remark);
        return result;
    }

    /**
     * 报废（→ scrap，终态）
     * 
     * @param id 装备ID
     * @param remark 备注
     * @return 结果
     */
    @Override
    @Transactional
    public int scrapEquipment(Long id, String remark) {
        Equipment equipment = equipmentMapper.selectEquipmentById(id);
        if (equipment == null) {
            throw new ServiceException("装备不存在");
        }
        String fromStatus = equipment.getStatus();
        String operator = SecurityUtils.getUsername();
        equipment.scrap(operator);
        int result = equipmentMapper.updateEquipment(equipment);
        // 记录操作日志
        recordLog(equipment.getId(), "scrap", fromStatus, equipment.getStatus(), null, null, remark);
        return result;
    }

    /**
     * 批量删除装备
     * 
     * @param ids 需要删除的装备ID数组
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteEquipmentByIds(Long[] ids) {
        return equipmentMapper.deleteEquipmentByIds(ids);
    }

    /**
     * 删除装备信息
     * 
     * @param id 装备ID
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteEquipmentById(Long id) {
        return equipmentMapper.deleteEquipmentById(id);
    }

    /**
     * 查询装备操作日志列表
     * 
     * @param log 日志信息
     * @return 日志集合
     */
    @Override
    public List<EquipmentLog> selectEquipmentLogList(EquipmentLog log) {
        return equipmentLogMapper.selectEquipmentLogList(log);
    }

    /**
     * 根据装备ID查询日志列表
     * 
     * @param equipmentId 装备ID
     * @return 日志集合
     */
    @Override
    public List<EquipmentLog> selectEquipmentLogListByEquipmentId(Long equipmentId) {
        return equipmentLogMapper.selectEquipmentLogListByEquipmentId(equipmentId);
    }

    /**
     * 记录操作日志
     */
    private void recordLog(Long equipmentId, String action, String fromStatus, String toStatus, 
                          Long dispatchId, Long eventId, String remark) {
        EquipmentLog log = new EquipmentLog();
        log.setEquipmentId(equipmentId);
        log.setAction(action);
        log.setFromStatus(fromStatus);
        log.setToStatus(toStatus);
        log.setDispatchId(dispatchId);
        log.setEventId(eventId);
        log.setRemark(remark);
        // 获取当前用户信息
        try {
            String username = SecurityUtils.getUsername();
            log.setOperatorName(username);
            // 如果SecurityUtils支持获取用户ID，可以设置
            // log.setOperatorId(SecurityUtils.getUserId());
        } catch (Exception e) {
            // 忽略异常
        }
        equipmentLogMapper.insertEquipmentLog(log);
    }
}