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

import java.util.Date;
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.requisition.domain.Requisition;
import com.aegis.resource.requisition.domain.RequisitionAgreement;
import com.aegis.resource.requisition.domain.RequisitionCompensation;
import com.aegis.resource.requisition.mapper.ResourceRequisitionAgreementMapper;
import com.aegis.resource.requisition.mapper.ResourceRequisitionCompensationMapper;
import com.aegis.resource.requisition.mapper.ResourceRequisitionMapper;
import com.aegis.resource.requisition.service.IResourceRequisitionService;
import com.aegis.resource.team.domain.Team;
import com.aegis.resource.team.service.IResourceTeamService;

/**
 * 征用申请Service业务层处理
 * 
 * @author aegis
 */
@Service
public class ResourceRequisitionServiceImpl implements IResourceRequisitionService {

    @Autowired
    private ResourceRequisitionMapper requisitionMapper;

    @Autowired
    private ResourceRequisitionAgreementMapper agreementMapper;

    @Autowired
    private ResourceRequisitionCompensationMapper compensationMapper;

    @Autowired
    private IResourceTeamService teamService;

    /**
     * 查询征用申请列表
     */
    @Override
    public List<Requisition> listRequisitions(Requisition requisition) {
        return requisitionMapper.selectRequisitionList(requisition);
    }

    /**
     * 根据ID查询征用申请
     */
    @Override
    public Requisition getRequisitionById(Long id) {
        return requisitionMapper.selectRequisitionById(id);
    }

    /**
     * 根据队伍ID查询征用申请列表
     */
    @Override
    public List<Requisition> listRequisitionsByTeamId(Long teamId) {
        return requisitionMapper.selectRequisitionListByTeamId(teamId);
    }

    /**
     * 校验征用编号是否唯一
     */
    @Override
    public boolean isRequisitionNoUnique(String requisitionNo, Long id) {
        if (StringUtils.isEmpty(requisitionNo)) {
            return UserConstants.UNIQUE; // 编号为空时认为唯一（由前端校验非空）
        }
        Long excludeId = StringUtils.isNull(id) ? -1L : id;
        Requisition info = requisitionMapper.checkRequisitionNoUnique(requisitionNo, excludeId);
        if (StringUtils.isNotNull(info)) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 新增征用申请
     */
    @Override
    @Transactional
    public int createRequisition(Requisition requisition) {
        // 校验征用编号唯一性（检查未删除的记录）
        if (!isRequisitionNoUnique(requisition.getRequisitionNo(), null)) {
            throw new ServiceException("新增征用申请失败，征用编号已存在");
        }
        
        // 检查是否存在已删除的相同编号记录
        Requisition deletedRequisition = requisitionMapper.selectDeletedRequisitionByNo(requisition.getRequisitionNo());
        if (deletedRequisition != null) {
            // 如果存在已删除的记录，则恢复并更新该记录
            String operator = SecurityUtils.getUsername();
            requisition.setId(deletedRequisition.getId());
            requisition.setCreateBy(deletedRequisition.getCreateBy()); // 保留原创建人
            requisition.setUpdateBy(operator);
            requisition.initializeDefaults(operator);
            return requisitionMapper.restoreRequisition(requisition);
        }
        
        // 校验队伍是否存在
        Team team = teamService.getById(requisition.getTeamId());
        if (team == null) {
            throw new ServiceException("队伍不存在");
        }
        requisition.setCreateBy(SecurityUtils.getUsername());
        requisition.initializeDefaults(SecurityUtils.getUsername());
        return requisitionMapper.insertRequisition(requisition);
    }

    /**
     * 修改征用申请
     */
    @Override
    @Transactional
    public int modifyRequisition(Requisition requisition) {
        Requisition oldRequisition = requisitionMapper.selectRequisitionById(requisition.getId());
        if (oldRequisition == null) {
            // 如果未删除的记录不存在，检查是否存在已删除的记录
            Requisition deletedRequisition = requisitionMapper.selectDeletedRequisitionByNo(requisition.getRequisitionNo());
            if (deletedRequisition != null && deletedRequisition.getId().equals(requisition.getId())) {
                // 如果存在已删除的记录且ID匹配，则恢复并更新
                String operator = SecurityUtils.getUsername();
                requisition.setCreateBy(deletedRequisition.getCreateBy()); // 保留原创建人
                requisition.setUpdateBy(operator);
                requisition.initializeDefaults(operator);
                return requisitionMapper.restoreRequisition(requisition);
            }
            throw new ServiceException("征用申请不存在");
        }
        
        oldRequisition.ensureEditable();
        
        // 如果征用编号发生变化，检查新征用编号是否已被使用（包括已删除的记录）
        if (!oldRequisition.getRequisitionNo().equals(requisition.getRequisitionNo())) {
            // 校验新征用编号唯一性（检查未删除的记录）
            if (!isRequisitionNoUnique(requisition.getRequisitionNo(), requisition.getId())) {
                throw new ServiceException("修改征用申请失败，征用编号已存在");
            }
            // 检查新征用编号是否存在已删除的记录
            Requisition deletedRequisitionWithNewNo = requisitionMapper.selectDeletedRequisitionByNo(requisition.getRequisitionNo());
            if (deletedRequisitionWithNewNo != null) {
                throw new ServiceException("修改征用申请失败，该征用编号已被删除，请先恢复该记录");
            }
        }
        // 使用领域方法更新字段
        if (StringUtils.isNotBlank(requisition.getReason()) && !requisition.getReason().equals(oldRequisition.getReason())) {
            oldRequisition.changeReason(requisition.getReason(), SecurityUtils.getUsername());
        }
        if (StringUtils.isNotBlank(requisition.getRemark()) && !requisition.getRemark().equals(oldRequisition.getRemark())) {
            oldRequisition.changeRemark(requisition.getRemark(), SecurityUtils.getUsername());
        }
        // 更新其他字段
        if (requisition.getStartAt() != null) {
            oldRequisition.setStartAt(requisition.getStartAt());
        }
        if (requisition.getEndAt() != null) {
            oldRequisition.setEndAt(requisition.getEndAt());
        }
        return requisitionMapper.updateRequisition(oldRequisition);
    }

    /**
     * 批量删除征用申请
     */
    @Override
    @Transactional
    public int removeRequisitions(Long[] ids) {
        for (Long id : ids) {
            Requisition requisition = requisitionMapper.selectRequisitionById(id);
            if (requisition == null) {
                throw new ServiceException("征用申请不存在，ID: " + id);
            }
            requisition.markDeleted(SecurityUtils.getUsername());
            // 删除关联的协议和补偿记录
            agreementMapper.deleteRequisitionAgreementByRequisitionId(id);
            compensationMapper.deleteRequisitionCompensationByRequisitionId(id);
            requisitionMapper.updateRequisition(requisition);
        }
        return ids.length;
    }

    /**
     * 删除征用申请信息
     */
    @Override
    @Transactional
    public int removeRequisition(Long id) {
        Requisition requisition = requisitionMapper.selectRequisitionById(id);
        if (requisition == null) {
            throw new ServiceException("征用申请不存在");
        }
        requisition.markDeleted(SecurityUtils.getUsername());
        // 删除关联的协议和补偿记录
        agreementMapper.deleteRequisitionAgreementByRequisitionId(id);
        compensationMapper.deleteRequisitionCompensationByRequisitionId(id);
        return requisitionMapper.updateRequisition(requisition);
    }

    /**
     * 审批通过（draft → approved）
     */
    @Override
    @Transactional
    public int approveRequisition(Long id, String comment) {
        Requisition requisition = requisitionMapper.selectRequisitionById(id);
        if (requisition == null) {
            throw new ServiceException("征用申请不存在");
        }
        requisition.approve(SecurityUtils.getUserId(), SecurityUtils.getUsername(), comment, SecurityUtils.getUsername());
        return requisitionMapper.updateRequisition(requisition);
    }

    /**
     * 审批驳回（draft → rejected）
     */
    @Override
    @Transactional
    public int rejectRequisition(Long id, String comment) {
        Requisition requisition = requisitionMapper.selectRequisitionById(id);
        if (requisition == null) {
            throw new ServiceException("征用申请不存在");
        }
        requisition.reject(SecurityUtils.getUserId(), SecurityUtils.getUsername(), comment, SecurityUtils.getUsername());
        return requisitionMapper.updateRequisition(requisition);
    }

    /**
     * 开始征用（approved → active，置队伍 busy）
     */
    @Override
    @Transactional
    public int startRequisition(Long id) {
        Requisition requisition = requisitionMapper.selectRequisitionById(id);
        if (requisition == null) {
            throw new ServiceException("征用申请不存在");
        }
        if (!"approved".equals(requisition.getStatus())) {
            throw new ServiceException("只有已审批通过状态的征用申请才能开始");
        }
        // 检查队伍状态
        Team team = teamService.getById(requisition.getTeamId());
        if (team == null) {
            throw new ServiceException("队伍不存在");
        }
        if (!"available".equals(team.getStatus())) {
            throw new ServiceException("队伍不是可用状态，无法开始征用");
        }
        // 检查该队伍是否已有active状态的征用（防止并发征用）
        Requisition checkRequisition = new Requisition();
        checkRequisition.setTeamId(requisition.getTeamId());
        checkRequisition.setStatus("active");
        List<Requisition> activeRequisitions = requisitionMapper.selectRequisitionList(checkRequisition);
        if (activeRequisitions != null && !activeRequisitions.isEmpty()) {
            // 排除当前征用申请
            boolean hasOtherActive = activeRequisitions.stream()
                .anyMatch(r -> !r.getId().equals(id));
            if (hasOtherActive) {
                throw new ServiceException("该队伍已有进行中的征用申请，无法开始新的征用");
            }
        }
        // 设置开始时间（如果未设置）
        if (requisition.getStartAt() == null) {
            requisition.setStartAt(new Date());
        }
        // 使用领域方法更新状态
        requisition.start(SecurityUtils.getUsername());
        requisitionMapper.updateRequisition(requisition);
        // 更新队伍状态为busy
        team.setStatus("busy");
        team.setUpdateBy(SecurityUtils.getUsername());
        teamService.updateById(team);
        return 1;
    }

    /**
     * 结束征用（active → ended，置队伍 available）
     */
    @Override
    @Transactional
    public int endRequisition(Long id) {
        Requisition requisition = requisitionMapper.selectRequisitionById(id);
        if (requisition == null) {
            throw new ServiceException("征用申请不存在");
        }
        if (!"active".equals(requisition.getStatus())) {
            throw new ServiceException("只有进行中状态的征用申请才能结束");
        }
        // 使用领域方法更新状态
        requisition.end(SecurityUtils.getUsername());
        requisitionMapper.updateRequisition(requisition);
        // 检查队伍是否存在
        Team team = teamService.getById(requisition.getTeamId());
        if (team == null) {
            throw new ServiceException("队伍不存在，无法恢复队伍状态");
        }
        // 检查该队伍是否还有其他active状态的征用
        Requisition checkRequisition = new Requisition();
        checkRequisition.setTeamId(requisition.getTeamId());
        checkRequisition.setStatus("active");
        List<Requisition> activeRequisitions = requisitionMapper.selectRequisitionList(checkRequisition);
        // 如果没有其他active状态的征用，才恢复队伍状态为available
        if (activeRequisitions == null || activeRequisitions.isEmpty()) {
            team.setStatus("available");
            team.setUpdateBy(SecurityUtils.getUsername());
            teamService.updateById(team);
        }
        // 如果还有其他active状态的征用，保持队伍状态为busy
        return 1;
    }

    /**
     * 重新提交（rejected → approved）
     */
    @Override
    @Transactional
    public int resubmitRequisition(Long id) {
        Requisition requisition = requisitionMapper.selectRequisitionById(id);
        if (requisition == null) {
            throw new ServiceException("征用申请不存在");
        }
        requisition.resubmit(SecurityUtils.getUsername());
        return requisitionMapper.updateRequisition(requisition);
    }

    /**
     * 查询征用协议列表
     */
    @Override
    public List<RequisitionAgreement> listRequisitionAgreements(RequisitionAgreement agreement) {
        return agreementMapper.selectRequisitionAgreementList(agreement);
    }

    /**
     * 根据征用ID查询协议列表
     */
    @Override
    public List<RequisitionAgreement> listRequisitionAgreementsByRequisitionId(Long requisitionId) {
        return agreementMapper.selectRequisitionAgreementListByRequisitionId(requisitionId);
    }

    /**
     * 根据ID查询协议
     */
    @Override
    public RequisitionAgreement getRequisitionAgreementById(Long id) {
        return agreementMapper.selectRequisitionAgreementById(id);
    }

    /**
     * 新增征用协议
     */
    @Override
    @Transactional
    public int createRequisitionAgreement(RequisitionAgreement agreement) {
        // 校验征用申请是否存在
        Requisition requisition = requisitionMapper.selectRequisitionById(agreement.getRequisitionId());
        if (requisition == null) {
            throw new ServiceException("征用申请不存在");
        }
        // 已结束的征用申请不应允许新增协议
        if (Requisition.RequisitionStatus.ENDED.getCode().equals(requisition.getStatus())) {
            throw new ServiceException("已结束的征用申请不能新增协议");
        }
        agreement.setCreateBy(SecurityUtils.getUsername());
        agreement.initializeDefaults(SecurityUtils.getUsername());
        return agreementMapper.insertRequisitionAgreement(agreement);
    }

    /**
     * 修改征用协议
     */
    @Override
    @Transactional
    public int modifyRequisitionAgreement(RequisitionAgreement agreement) {
        // 校验协议是否存在
        RequisitionAgreement oldAgreement = agreementMapper.selectRequisitionAgreementById(agreement.getId());
        if (oldAgreement == null) {
            throw new ServiceException("协议不存在");
        }
        // 校验征用申请是否存在
        Requisition requisition = requisitionMapper.selectRequisitionById(agreement.getRequisitionId());
        if (requisition == null) {
            throw new ServiceException("征用申请不存在");
        }
        // 已结束的征用申请不应允许修改协议
        if (Requisition.RequisitionStatus.ENDED.getCode().equals(requisition.getStatus())) {
            throw new ServiceException("已结束的征用申请不能修改协议");
        }
        agreement.setUpdateBy(SecurityUtils.getUsername());
        return agreementMapper.updateRequisitionAgreement(agreement);
    }

    /**
     * 删除征用协议
     */
    @Override
    @Transactional
    public int removeRequisitionAgreement(Long id) {
        // 校验协议是否存在
        RequisitionAgreement agreement = agreementMapper.selectRequisitionAgreementById(id);
        if (agreement == null) {
            throw new ServiceException("协议不存在");
        }
        // 校验征用申请是否存在
        Requisition requisition = requisitionMapper.selectRequisitionById(agreement.getRequisitionId());
        if (requisition == null) {
            throw new ServiceException("征用申请不存在");
        }
        // 已结束的征用申请不应允许删除协议
        if (Requisition.RequisitionStatus.ENDED.getCode().equals(requisition.getStatus())) {
            throw new ServiceException("已结束的征用申请不能删除协议");
        }
        return agreementMapper.deleteRequisitionAgreementById(id);
    }

    /**
     * 查询补偿记录列表
     */
    @Override
    public List<RequisitionCompensation> listRequisitionCompensations(RequisitionCompensation compensation) {
        return compensationMapper.selectRequisitionCompensationList(compensation);
    }

    /**
     * 根据征用ID查询补偿记录列表
     */
    @Override
    public List<RequisitionCompensation> listRequisitionCompensationsByRequisitionId(Long requisitionId) {
        return compensationMapper.selectRequisitionCompensationListByRequisitionId(requisitionId);
    }

    /**
     * 根据ID查询补偿记录
     */
    @Override
    public RequisitionCompensation getRequisitionCompensationById(Long id) {
        return compensationMapper.selectRequisitionCompensationById(id);
    }

    /**
     * 新增补偿记录
     */
    @Override
    @Transactional
    public int createRequisitionCompensation(RequisitionCompensation compensation) {
        // 校验征用申请是否存在
        Requisition requisition = requisitionMapper.selectRequisitionById(compensation.getRequisitionId());
        if (requisition == null) {
            throw new ServiceException("征用申请不存在");
        }
        // 已结束的征用申请不应允许新增补偿记录
        if (Requisition.RequisitionStatus.ENDED.getCode().equals(requisition.getStatus())) {
            throw new ServiceException("已结束的征用申请不能新增补偿记录");
        }
        compensation.setCreateBy(SecurityUtils.getUsername());
        compensation.initializeDefaults(SecurityUtils.getUsername());
        return compensationMapper.insertRequisitionCompensation(compensation);
    }

    /**
     * 修改补偿记录
     */
    @Override
    @Transactional
    public int modifyRequisitionCompensation(RequisitionCompensation compensation) {
        // 校验补偿记录是否存在
        RequisitionCompensation oldCompensation = compensationMapper.selectRequisitionCompensationById(compensation.getId());
        if (oldCompensation == null) {
            throw new ServiceException("补偿记录不存在");
        }
        // 已结算的补偿记录不允许修改
        if (RequisitionCompensation.CompensationStatus.SETTLED.getCode().equals(oldCompensation.getStatus())) {
            throw new ServiceException("已结算的补偿记录不能修改");
        }
        // 更新字段
        if (compensation.getWorkload() != null) {
            oldCompensation.setWorkload(compensation.getWorkload());
        }
        if (compensation.getWorkloadUnit() != null) {
            oldCompensation.setWorkloadUnit(compensation.getWorkloadUnit());
        }
        if (compensation.getUnitPrice() != null) {
            oldCompensation.setUnitPrice(compensation.getUnitPrice());
        }
        if (compensation.getCurrency() != null) {
            oldCompensation.setCurrency(compensation.getCurrency());
        }
        if (compensation.getRemark() != null) {
            oldCompensation.setRemark(compensation.getRemark());
        }
        // 重新计算金额
        oldCompensation.calculateAmount();
        // 如果前端提供了金额，允许手动调整
        if (compensation.getAmount() != null) {
            oldCompensation.setAmount(compensation.getAmount());
        }
        oldCompensation.setUpdateBy(SecurityUtils.getUsername());
        return compensationMapper.updateRequisitionCompensation(oldCompensation);
    }

    /**
     * 删除补偿记录
     */
    @Override
    @Transactional
    public int removeRequisitionCompensation(Long id) {
        // 校验补偿记录是否存在
        RequisitionCompensation compensation = compensationMapper.selectRequisitionCompensationById(id);
        if (compensation == null) {
            throw new ServiceException("补偿记录不存在");
        }
        // 已结算的补偿记录不允许删除
        if (RequisitionCompensation.CompensationStatus.SETTLED.getCode().equals(compensation.getStatus())) {
            throw new ServiceException("已结算的补偿记录不能删除");
        }
        return compensationMapper.deleteRequisitionCompensationById(id);
    }

    /**
     * 结算补偿（pending → settled）
     */
    @Override
    @Transactional
    public int settleCompensation(Long id, String invoiceNo, Date paidAt) {
        RequisitionCompensation compensation = compensationMapper.selectRequisitionCompensationById(id);
        if (compensation == null) {
            throw new ServiceException("补偿记录不存在");
        }
        compensation.settle(invoiceNo, paidAt, SecurityUtils.getUsername());
        return compensationMapper.updateRequisitionCompensation(compensation);
    }
}