package com.ygtx.gxt.service.impl;

import java.util.List;
import com.ygtx.common.utils.DateUtils;
import com.ygtx.common.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ygtx.gxt.mapper.GxtWorkOrderMapper;
import com.ygtx.gxt.mapper.GxtWorkOrderFlowMapper;
import com.ygtx.gxt.mapper.GxtWorkOrderPersonMapper;
import com.ygtx.gxt.domain.GxtWorkOrder;
import com.ygtx.gxt.domain.GxtWorkOrderFlow;
import com.ygtx.gxt.domain.GxtWorkOrderPerson;
import com.ygtx.gxt.service.IGxtWorkOrderService;
import com.ygtx.common.exception.ServiceException;

/**
 * 维保工单Service业务层处理
 *
 * @author ygtx
 * @date 2025-10-25
 */
@Service
public class GxtWorkOrderServiceImpl implements IGxtWorkOrderService
{
    @Autowired
    private GxtWorkOrderMapper gxtWorkOrderMapper;

    @Autowired
    private GxtWorkOrderFlowMapper gxtWorkOrderFlowMapper;

    @Autowired
    private GxtWorkOrderPersonMapper gxtWorkOrderPersonMapper;

    /**
     * 查询维保工单
     *
     * @param id 维保工单主键
     * @return 维保工单
     */
    @Override
    public GxtWorkOrder selectGxtWorkOrderById(Long id)
    {
        return gxtWorkOrderMapper.selectGxtWorkOrderById(id);
    }

    /**
     * 查询维保工单列表
     *
     * @param gxtWorkOrder 维保工单
     * @return 维保工单
     */
    @Override
    public List<GxtWorkOrder> selectGxtWorkOrderList(GxtWorkOrder gxtWorkOrder)
    {
        return gxtWorkOrderMapper.selectGxtWorkOrderList(gxtWorkOrder);
    }

    /**
     * 新增维保工单
     *
     * @param gxtWorkOrder 维保工单
     * @return 结果
     */
    @Override
    @Transactional
    public int insertGxtWorkOrder(GxtWorkOrder gxtWorkOrder)
    {
        // 检查工单编码是否已存在
        GxtWorkOrder existOrder = gxtWorkOrderMapper.selectGxtWorkOrderByCode(gxtWorkOrder.getWorkOrderProjectNo());
        if (existOrder != null)
        {
            throw new ServiceException("工单编码已存在");
        }

        // 设置默认状态为草稿
        if (gxtWorkOrder.getWorkOrderStatus() == null || gxtWorkOrder.getWorkOrderStatus().isEmpty())
        {
            gxtWorkOrder.setWorkOrderStatus("draft");
        }

        gxtWorkOrder.setCreateTime(DateUtils.getNowDate());
        int result = gxtWorkOrderMapper.insertGxtWorkOrder(gxtWorkOrder);

        // 记录创建流转
        if (result > 0)
        {
            recordWorkOrderFlow(gxtWorkOrder.getId(), gxtWorkOrder.getWorkOrderProjectNo(),
                    "create", null, gxtWorkOrder.getWorkOrderStatus(), "创建工单");
        }

        return result;
    }

    /**
     * 修改维保工单
     *
     * @param gxtWorkOrder 维保工单
     * @return 结果
     */
    @Override
    public int updateGxtWorkOrder(GxtWorkOrder gxtWorkOrder)
    {
        // 检查工单编码是否与其他工单重复
        GxtWorkOrder existOrder = gxtWorkOrderMapper.selectGxtWorkOrderByCode(gxtWorkOrder.getWorkOrderProjectNo());
        if (existOrder != null && !existOrder.getId().equals(gxtWorkOrder.getId()))
        {
            throw new ServiceException("工单编码已存在");
        }

        gxtWorkOrder.setUpdateTime(DateUtils.getNowDate());
        return gxtWorkOrderMapper.updateGxtWorkOrder(gxtWorkOrder);
    }

    /**
     * 批量删除维保工单
     *
     * @param ids 需要删除的维保工单主键
     * @return 结果
     */
    @Override
    public int deleteGxtWorkOrderByIds(Long[] ids)
    {
        return gxtWorkOrderMapper.deleteGxtWorkOrderByIds(ids);
    }

    /**
     * 删除维保工单信息
     *
     * @param id 维保工单主键
     * @return 结果
     */
    @Override
    public int deleteGxtWorkOrderById(Long id)
    {
        return gxtWorkOrderMapper.deleteGxtWorkOrderById(id);
    }

    /**
     * 派单给班组组长
     *
     * @param id 工单ID
     * @param teamLeaderId 班组组长ID
     * @param teamLeaderName 班组组长姓名
     * @return 结果
     */
    @Override
    @Transactional
    public int assignToTeamLeader(Long id, Long teamLeaderId, String teamLeaderName)
    {
        GxtWorkOrder order = gxtWorkOrderMapper.selectGxtWorkOrderById(id);
        if (order == null)
        {
            throw new ServiceException("工单不存在");
        }

        // 只有草稿或待派单状态才能派单
        if (!"draft".equals(order.getWorkOrderStatus()) && !"to_assign".equals(order.getWorkOrderStatus()))
        {
            throw new ServiceException("当前工单状态不允许派单");
        }

        String oldStatus = order.getWorkOrderStatus();

        order.setTeamLeaderId(teamLeaderId);
        order.setTeamLeaderName(teamLeaderName);
        order.setAssignTime(DateUtils.getNowDate());
        order.setAssignUserId(SecurityUtils.getUserId());
        order.setAssignUserName(SecurityUtils.getUsername());
        order.setWorkOrderStatus("assigned");
        order.setUpdateTime(DateUtils.getNowDate());

        int result = gxtWorkOrderMapper.updateGxtWorkOrder(order);

        // 记录流转
        if (result > 0)
        {
            recordWorkOrderFlow(id, order.getWorkOrderProjectNo(), "assign", oldStatus, "assigned",
                    "派单给班组组长：" + teamLeaderName);
        }

        return result;
    }

    /**
     * 班组组长接单
     *
     * @param id 工单ID
     * @return 结果
     */
    @Override
    @Transactional
    public int acceptByTeamLeader(Long id)
    {
        GxtWorkOrder order = gxtWorkOrderMapper.selectGxtWorkOrderById(id);
        if (order == null)
        {
            throw new ServiceException("工单不存在");
        }

        // 只有已派单状态才能接单
        if (!"assigned".equals(order.getWorkOrderStatus()))
        {
            throw new ServiceException("当前工单状态不允许接单");
        }

        // 验证是否为班组组长
        Long currentUserId = SecurityUtils.getUserId();
        if (!currentUserId.equals(order.getTeamLeaderId()))
        {
            throw new ServiceException("只有被指派的班组组长才能接单");
        }

        String oldStatus = order.getWorkOrderStatus();

        order.setAcceptTime(DateUtils.getNowDate());
        order.setAcceptUserId(currentUserId);
        order.setAcceptUserName(SecurityUtils.getUsername());
        order.setWorkOrderStatus("accepted");
        order.setUpdateTime(DateUtils.getNowDate());

        int result = gxtWorkOrderMapper.updateGxtWorkOrder(order);

        // 记录流转
        if (result > 0)
        {
            recordWorkOrderFlow(id, order.getWorkOrderProjectNo(), "accept", oldStatus, "accepted",
                    "班组组长接单");
        }

        return result;
    }

    /**
     * 班组组长派单给工作组成员
     *
     * @param id 工单ID
     * @param workGroupMemberId 工作组成员ID
     * @param workGroupMemberName 工作组成员姓名
     * @return 结果
     */
    @Override
    @Transactional
    public int assignToWorkGroupMember(Long id, Long workGroupMemberId, String workGroupMemberName)
    {
        GxtWorkOrder order = gxtWorkOrderMapper.selectGxtWorkOrderById(id);
        if (order == null)
        {
            throw new ServiceException("工单不存在");
        }

        // 只有已接单状态才能派给工作组成员
        if (!"accepted".equals(order.getWorkOrderStatus()))
        {
            throw new ServiceException("当前工单状态不允许派单给工作组成员");
        }

        // 验证是否为班组组长
        Long currentUserId = SecurityUtils.getUserId();
        if (!currentUserId.equals(order.getTeamLeaderId()))
        {
            throw new ServiceException("只有班组组长才能派单给工作组成员");
        }

        String oldStatus = order.getWorkOrderStatus();

        order.setWorkGroupMemberId(workGroupMemberId);
        order.setWorkGroupMemberName(workGroupMemberName);
        order.setWorkOrderStatus("assigned");
        order.setUpdateTime(DateUtils.getNowDate());

        int result = gxtWorkOrderMapper.updateGxtWorkOrder(order);

        // 记录流转
        if (result > 0)
        {
            recordWorkOrderFlow(id, order.getWorkOrderProjectNo(), "assign", oldStatus, "assigned",
                    "派单给工作组成员：" + workGroupMemberName);
        }

        return result;
    }

    /**
     * 工作组成员接单
     *
     * @param id 工单ID
     * @return 结果
     */
    @Override
    @Transactional
    public int acceptByWorkGroupMember(Long id)
    {
        GxtWorkOrder order = gxtWorkOrderMapper.selectGxtWorkOrderById(id);
        if (order == null)
        {
            throw new ServiceException("工单不存在");
        }

        // 只有已派单状态才能接单
        if (!"assigned".equals(order.getWorkOrderStatus()))
        {
            throw new ServiceException("当前工单状态不允许接单");
        }

        // 验证是否为工作组成员
        Long currentUserId = SecurityUtils.getUserId();
        if (order.getWorkGroupMemberId() == null || !currentUserId.equals(order.getWorkGroupMemberId()))
        {
            throw new ServiceException("只有被指派的工作组成员才能接单");
        }

        String oldStatus = order.getWorkOrderStatus();

        order.setAcceptTime(DateUtils.getNowDate());
        order.setAcceptUserId(currentUserId);
        order.setAcceptUserName(SecurityUtils.getUsername());
        order.setWorkOrderStatus("processing");
        order.setUpdateTime(DateUtils.getNowDate());

        int result = gxtWorkOrderMapper.updateGxtWorkOrder(order);

        // 记录流转
        if (result > 0)
        {
            recordWorkOrderFlow(id, order.getWorkOrderProjectNo(), "accept", oldStatus, "processing",
                    "工作组成员接单，开始处理");
        }

        return result;
    }

    /**
     * 挂起工单
     *
     * @param id 工单ID
     * @param suspendReason 挂起原因
     * @return 结果
     */
    @Override
    @Transactional
    public int suspendWorkOrder(Long id, String suspendReason)
    {
        GxtWorkOrder order = gxtWorkOrderMapper.selectGxtWorkOrderById(id);
        if (order == null)
        {
            throw new ServiceException("工单不存在");
        }

        // 只有处理中的工单才能挂起
        if (!"processing".equals(order.getWorkOrderStatus()) && !"paused".equals(order.getWorkOrderStatus()))
        {
            throw new ServiceException("只有处理中的工单才能挂起");
        }

        // 验证是否为班组组长或工作组成员
        Long currentUserId = SecurityUtils.getUserId();
        if (!currentUserId.equals(order.getTeamLeaderId()) && !currentUserId.equals(order.getWorkGroupMemberId()))
        {
            throw new ServiceException("只有班组组长或工作组成员才能挂起工单");
        }

        String oldStatus = order.getWorkOrderStatus();

        order.setSuspendReason(suspendReason);
        order.setSuspendTime(DateUtils.getNowDate());
        order.setWorkOrderStatus("suspended");
        order.setUpdateTime(DateUtils.getNowDate());

        int result = gxtWorkOrderMapper.updateGxtWorkOrder(order);

        // 记录流转
        if (result > 0)
        {
            recordWorkOrderFlow(id, order.getWorkOrderProjectNo(), "suspend", oldStatus, "suspended",
                    "挂起工单，原因：" + suspendReason);
        }

        return result;
    }

    /**
     * 重启工单
     *
     * @param id 工单ID
     * @return 结果
     */
    @Override
    @Transactional
    public int restartWorkOrder(Long id)
    {
        GxtWorkOrder order = gxtWorkOrderMapper.selectGxtWorkOrderById(id);
        if (order == null)
        {
            throw new ServiceException("工单不存在");
        }

        // 只有挂起的工单才能重启
        if (!"suspended".equals(order.getWorkOrderStatus()))
        {
            throw new ServiceException("只有挂起的工单才能重启");
        }

        // 验证是否为班组组长或工作组成员
        Long currentUserId = SecurityUtils.getUserId();
        if (!currentUserId.equals(order.getTeamLeaderId()) && !currentUserId.equals(order.getWorkGroupMemberId()))
        {
            throw new ServiceException("只有班组组长或工作组成员才能重启工单");
        }

        String oldStatus = order.getWorkOrderStatus();

        order.setRestartTime(DateUtils.getNowDate());
        order.setWorkOrderStatus("processing");
        order.setUpdateTime(DateUtils.getNowDate());

        int result = gxtWorkOrderMapper.updateGxtWorkOrder(order);

        // 记录流转
        if (result > 0)
        {
            recordWorkOrderFlow(id, order.getWorkOrderProjectNo(), "restart", oldStatus, "processing",
                    "重启工单，继续处理");
        }

        return result;
    }

    /**
     * 完成工单
     *
     * @param id 工单ID
     * @return 结果
     */
    @Override
    @Transactional
    public int completeWorkOrder(Long id)
    {
        GxtWorkOrder order = gxtWorkOrderMapper.selectGxtWorkOrderById(id);
        if (order == null)
        {
            throw new ServiceException("工单不存在");
        }

        // 只有处理中的工单才能完成
        if (!"processing".equals(order.getWorkOrderStatus()))
        {
            throw new ServiceException("只有处理中的工单才能完成");
        }

        // 验证是否为工作组成员或班组组长
        Long currentUserId = SecurityUtils.getUserId();
        if (!currentUserId.equals(order.getWorkGroupMemberId()) && !currentUserId.equals(order.getTeamLeaderId()))
        {
            throw new ServiceException("只有工作组成员或班组组长才能完成工单");
        }

        String oldStatus = order.getWorkOrderStatus();

        order.setCompleteTime(DateUtils.getNowDate());
        order.setWorkOrderStatus("completed");
        order.setUpdateTime(DateUtils.getNowDate());

        int result = gxtWorkOrderMapper.updateGxtWorkOrder(order);

        // 记录流转
        if (result > 0)
        {
            recordWorkOrderFlow(id, order.getWorkOrderProjectNo(), "complete", oldStatus, "completed",
                    "工单完成");
        }

        return result;
    }

    /**
     * 查询工单流转记录
     *
     * @param orderId 工单ID
     * @return 流转记录集合
     */
    @Override
    public List<GxtWorkOrderFlow> selectWorkOrderFlowByOrderId(Long orderId)
    {
        return gxtWorkOrderFlowMapper.selectGxtWorkOrderFlowByOrderId(orderId);
    }

    /**
     * 接单（支持一次性选择处理人员）
     *
     * @param gxtWorkOrder 工单
     * @return 结果
     */
    @Override
    @Transactional
    public int acceptOrder(GxtWorkOrder gxtWorkOrder)
    {
        Long id = gxtWorkOrder.getId();
        GxtWorkOrder order = gxtWorkOrderMapper.selectGxtWorkOrderById(id);
        if (order == null)
        {
            throw new ServiceException("工单不存在");
        }

        // 仅有已派单状态才能接单
        if (!"assigned".equals(order.getWorkOrderStatus()))
        {
            throw new ServiceException("当前工单状态不允许接单");
        }

        // 验证处理人员
        if (gxtWorkOrder.getAcceptUserId() == null)
        {
            throw new ServiceException("处理人员不能为空");
        }

        // 验证检修人员
        if (gxtWorkOrder.getWorkOrderPersonList() == null || gxtWorkOrder.getWorkOrderPersonList().isEmpty())
        {
            throw new ServiceException("至少需要一名检修人员");
        }

        String oldStatus = order.getWorkOrderStatus();

        // 1. 更新工单信息
        order.setAcceptTime(DateUtils.getNowDate());
        order.setAcceptUserId(gxtWorkOrder.getAcceptUserId());
        order.setAcceptUserName(gxtWorkOrder.getAcceptUserName());
        order.setWorkOrderStatus("accepted");
        order.setUpdateTime(DateUtils.getNowDate());

        int result = gxtWorkOrderMapper.updateGxtWorkOrder(order);

        if (result > 0)
        {
            // 2. 删除旧的工作组成员
            gxtWorkOrderPersonMapper.deleteGxtWorkOrderPersonByOrderId(id);

            // 3. 添加新的工作组成员
            for (GxtWorkOrderPerson person : gxtWorkOrder.getWorkOrderPersonList())
            {
                person.setOrderId(id);
                person.setOrderCode(order.getWorkOrderProjectNo());
                person.setStatus(1);
                person.setCreateBy(SecurityUtils.getUsername());
                person.setCreateTime(DateUtils.getNowDate());
                gxtWorkOrderPersonMapper.insertGxtWorkOrderPerson(person);
            }

            // 4. 记录流转
            String memberNames = gxtWorkOrder.getWorkOrderPersonList().stream()
                    .map(GxtWorkOrderPerson::getNickName)
                    .collect(java.util.stream.Collectors.joining(","));

            recordWorkOrderFlow(id, order.getWorkOrderProjectNo(), "accept", oldStatus, "accepted",
                    "接单人: " + gxtWorkOrder.getAcceptUserName() + ", 检修人员: " + memberNames);
        }

        return result;
    }

    /**
     * 记录工单流转
     *
     * @param orderId 工单ID
     * @param orderCode 工单编码
     * @param actionType 操作类型
     * @param fromStatus 原状态
     * @param toStatus 目标状态
     * @param remark 备注
     */
    private void recordWorkOrderFlow(Long orderId, String orderCode, String actionType,
                                      String fromStatus, String toStatus, String remark)
    {
        GxtWorkOrderFlow flow = new GxtWorkOrderFlow();
        flow.setOrderId(orderId);
        flow.setOrderCode(orderCode);
        flow.setActionType(actionType);
        flow.setFromStatus(fromStatus);
        flow.setToStatus(toStatus);
        flow.setOperatorId(SecurityUtils.getUserId());
        flow.setOperatorName(SecurityUtils.getUsername());
        flow.setActionTime(DateUtils.getNowDate());
        flow.setActionRemark(remark);
        flow.setCreateBy(SecurityUtils.getUsername());
        flow.setCreateTime(DateUtils.getNowDate());

        gxtWorkOrderFlowMapper.insertGxtWorkOrderFlow(flow);
    }
}
