package com.ygtx.gxt.task;

import com.ygtx.common.core.domain.entity.SysUser;
import com.ygtx.common.core.domain.model.LoginUser;
import com.ygtx.common.utils.DateUtils;
import com.ygtx.framework.web.service.SysPermissionService;
import com.ygtx.gxt.domain.*;
import com.ygtx.gxt.service.IGxtOrderScoreService;
import com.ygtx.gxt.service.IGxtRepairOrderFlowService;
import com.ygtx.gxt.service.IGxtRepairOrderService;
import com.ygtx.gxt.service.IGxtWorkOrderFlowService;
import com.ygtx.gxt.service.IGxtWorkOrderService;
import com.ygtx.system.mapper.SysUserMapper;
import com.ygtx.system.service.ISysConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 工单自动终评任务
 * 每小时执行，对复评超过24小时但未终评的维修工单和维保工单进行自动终评
 *
 * @author ouyj
 * @date 2026-01-23
 */
@EnableScheduling
@Component("orderScoreAutoFinalTask")
public class OrderScoreAutoFinalTask {

    private static final Logger log = LoggerFactory.getLogger(OrderScoreAutoFinalTask.class);

    @Autowired
    private IGxtRepairOrderService repairOrderService;

    @Autowired
    private IGxtRepairOrderFlowService repairOrderFlowService;

    @Autowired
    private IGxtWorkOrderService workOrderService;

    @Autowired
    private IGxtWorkOrderFlowService workOrderFlowService;

    @Autowired
    private IGxtOrderScoreService orderScoreService;

    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private SysPermissionService permissionService;

    @Autowired
    private ISysConfigService configService;

    /**
     * 每小时执行定时任务
     * 查找复评超过24小时但未终评的维修工单和维保工单，并进行自动终评
     */
    public void autoFinalOrders() {
        log.info("开始执行工单自动终评任务");
        
        // 设置系统用户上下文
        setSystemUserContext();
        
        try {
            // 处理维修工单的自动终评
            processRepairOrders();

            // 处理维保工单的自动终评
            processWorkOrders();

        } catch (Exception e) {
            log.error("执行工单自动终评任务时发生异常", e);
        }
    }

    /**
     * 处理维修工单的自动终评
     */
    private void processRepairOrders() {
        try {
            // 构造查询条件：待终评状态的工单
            GxtRepairOrder queryOrder = new GxtRepairOrder();
            queryOrder.setWorkOrderStatus("completed");
            queryOrder.setScoringStatus("to_final"); // 待终评状态
            List<GxtRepairOrder> orders = repairOrderService.selectGxtRepairOrderList(queryOrder);

            int finalCount = 0;
            for (GxtRepairOrder order : orders) {
                // 检查是否满足自动终评条件（复评超过24小时）
                //if (shouldAutoFinalRepairOrder(order)) {
                    // 执行自动终评操作
                    autoFinalRepairOrder(order);
                    finalCount++;
                //}
            }

            log.info("维修工单自动终评任务执行完成，共处理 {} 个工单", finalCount);
        } catch (Exception e) {
            log.error("处理维修工单自动终评时发生异常", e);
        }
    }

    /**
     * 处理维保工单的自动终评
     */
    private void processWorkOrders() {
        try {
            // 构造查询条件：待终评状态的维保工单
            GxtWorkOrder queryOrder = new GxtWorkOrder();
            queryOrder.setWorkOrderStatus("completed");
            queryOrder.setScoringStatus("to_final"); // 待终评状态
            List<GxtWorkOrder> orders = workOrderService.selectGxtWorkOrderList(queryOrder);

            int finalCount = 0;
            for (GxtWorkOrder order : orders) {
                // 检查是否满足自动终评条件（复评超过24小时）
                //if (shouldAutoFinalWorkOrder(order)) {
                    // 执行自动终评操作
                    autoFinalWorkOrder(order);
                    finalCount++;
                //}
            }

            log.info("维保工单自动终评任务执行完成，共处理 {} 个工单", finalCount);
        } catch (Exception e) {
            log.error("处理维保工单自动终评时发生异常", e);
        }
    }

    /**
     * 判断维修工单是否满足自动终评条件
     * 条件：处于待终评状态且超过配置的小时数，默认24小时
     *
     * @param order 维修工单
     * @return 是否满足自动终评条件
     */
    private boolean shouldAutoFinalRepairOrder(GxtRepairOrder order) {
        Date toFinalStatusTime = null;
        
        // 通过查询工单流转记录获取进入待终评状态的时间
        GxtRepairOrderFlow flowQuery = new GxtRepairOrderFlow();
        flowQuery.setOrderId(order.getId());
        flowQuery.setActionType("reviewRating");
        List<GxtRepairOrderFlow> flows = repairOrderFlowService.selectGxtRepairOrderFlowList(flowQuery);

        if (!flows.isEmpty()) {
            // 获取最后一次进入待终评状态的时间
            toFinalStatusTime = flows.get(flows.size() - 1).getActionTime();
        }

        if (toFinalStatusTime == null) {
            return false;
        }

        // 从配置中获取终评超时小时数，如果配置为空则默认24小时
        String hoursStr = configService.selectConfigByKey("gxt.orderScore.autoFinalHours");
        int finalHours = 24; // 默认24小时
        if (hoursStr != null && !hoursStr.trim().isEmpty()) {
            try {
                finalHours = Integer.parseInt(hoursStr.trim());
            } catch (NumberFormatException e) {
                log.warn("配置的自动终评小时数不是有效数字，使用默认值24小时: {}", hoursStr);
            }
        }

        // 检查进入待终评状态的时间是否已超过配置的小时数
        Date now = DateUtils.getNowDate();
        Date finalTimeThreshold = DateUtils.addHours(toFinalStatusTime, finalHours);

        return now.after(finalTimeThreshold);
    }

    /**
     * 判断维保工单是否满足自动终评条件
     * 条件：处于待终评状态且超过配置的小时数，默认24小时
     *
     * @param order 维保工单
     * @return 是否满足自动终评条件
     */
    private boolean shouldAutoFinalWorkOrder(GxtWorkOrder order) {
        Date toFinalStatusTime = null;
        
        // 通过查询工单流转记录获取进入待终评状态的时间
        GxtWorkOrderFlow flowQuery = new GxtWorkOrderFlow();
        flowQuery.setOrderId(order.getId());
        flowQuery.setActionType("reviewRating");
        List<GxtWorkOrderFlow> flows = workOrderFlowService.selectGxtWorkOrderFlowList(flowQuery);

        if (!flows.isEmpty()) {
            // 获取最后一次进入待终评状态的时间
            toFinalStatusTime = flows.get(flows.size() - 1).getActionTime();
        }

        if (toFinalStatusTime == null) {
            return false;
        }

        // 从配置中获取终评超时小时数，如果配置为空则默认24小时
        String hoursStr = configService.selectConfigByKey("gxt.orderScore.autoFinalHours");
        int finalHours = 24; // 默认24小时
        if (hoursStr != null && !hoursStr.trim().isEmpty()) {
            try {
                finalHours = Integer.parseInt(hoursStr.trim());
            } catch (NumberFormatException e) {
                log.warn("配置的自动终评小时数不是有效数字，使用默认值24小时: {}", hoursStr);
            }
        }

        // 检查进入待终评状态的时间是否已超过配置的小时数
        Date now = DateUtils.getNowDate();
        Date finalTimeThreshold = DateUtils.addHours(toFinalStatusTime, finalHours);

        return now.after(finalTimeThreshold);
    }

    /**
     * 对维修工单进行自动终评操作
     *
     * @param order 需要终评的工单
     */
    private void autoFinalRepairOrder(GxtRepairOrder order) {
        try {
            // 获取工单的人员评分信息
            List<GxtRepairOrderPerson> orderPersons = repairOrderService.selectRepairOrderPersonListByOrderId(order.getId());
            
            // 创建评分信息对象
            OrderScoreInfo orderScoreInfo = new OrderScoreInfo();
            orderScoreInfo.setId(order.getId());
            orderScoreInfo.setOrderType(1); // 维修工单
            orderScoreInfo.setWorkOrderProjectNo(order.getWorkOrderProjectNo());
            
            // 复制原工单的评分状态和类型信息
            //orderScoreInfo.setMaintenanceType(order.getMaintenanceType());
            orderScoreInfo.setFinalCoefficient(order.getFinalCoefficient() != null ? order.getFinalCoefficient() : BigDecimal.ONE); // 系数设为1
            
            // 如果有重启时间，这可能影响最终的状态
            //orderScoreInfo.setRestartTime(order.getRestartTime());
            
            // 设置人员评分列表
            if (orderPersons != null && !orderPersons.isEmpty()) {
                List<OrderScorePerson> scorePersons = orderPersons.stream().map(person -> {
                    OrderScorePerson scorePerson = new OrderScorePerson();
                    scorePerson.setId(person.getId());
                    scorePerson.setUserId(person.getUserId());
                    scorePerson.setNickName(person.getNickName());
                    
                    // 使用复评分作为终评分和总评分
                    Double reviewScore = person.getReviewScore();
                    scorePerson.setFinalScore(reviewScore);

                    Double totalScore = (person.getTotalScore() != null) ? person.getTotalScore() : reviewScore;
                    scorePerson.setTotalScore(totalScore != null ? totalScore : 0.0);
                    
                    // 保留原有的运行得分和停机扣分
                    scorePerson.setRunScore(person.getRunScore());
                    scorePerson.setStopScore(person.getStopScore());
                    
                    return scorePerson;
                }).collect(Collectors.toList());
                
                orderScoreInfo.setScorePersonList(scorePersons);
            } else {
                // 如果没有人员评分信息，则创建一个空列表，避免空指针异常
                orderScoreInfo.setScorePersonList(new ArrayList<>());
            }

            // 调用现有的终评方法
            int result = orderScoreService.finalEvaluation(orderScoreInfo);
            
            if (result > 0) {
                log.info("工单 {} 已成功自动终评", order.getWorkOrderProjectNo());
            } else {
                log.warn("工单 {} 自动终评失败", order.getWorkOrderProjectNo());
            }
        } catch (Exception e) {
            log.error("自动终评工单 {} 时发生异常", order.getWorkOrderProjectNo(), e);
        }
    }

    /**
     * 对维保工单进行自动终评操作
     *
     * @param order 需要终评的工单
     */
    private void autoFinalWorkOrder(GxtWorkOrder order) {
        try {
            // 获取工单的人员评分信息
            List<GxtWorkOrderPerson> orderPersons = workOrderService.selectWorkOrderPersonListByOrderId(order.getId());
            
            // 创建评分信息对象
            OrderScoreInfo orderScoreInfo = new OrderScoreInfo();
            orderScoreInfo.setId(order.getId());
            orderScoreInfo.setOrderType(2); // 维保工单
            orderScoreInfo.setWorkOrderProjectNo(order.getWorkOrderProjectNo());
            
            // 复制原工单的评分状态和类型信息
            //orderScoreInfo.setInspectionType(order.getInspectionType());
            //orderScoreInfo.setItemCompletionFactor(order.getItemCompletionFactor()); // 系数设为1
            
            // 如果有重启时间，这可能影响最终的状态
            //orderScoreInfo.setRestartTime(order.getRestartTime());
            
            // 设置人员评分列表
            if (orderPersons != null && !orderPersons.isEmpty()) {
                List<OrderScorePerson> scorePersons = orderPersons.stream().map(person -> {
                    OrderScorePerson scorePerson = new OrderScorePerson();
                    scorePerson.setId(person.getId());
                    scorePerson.setUserId(person.getUserId());
                    scorePerson.setNickName(person.getNickName());
                    
                    // 使用复评分作为终评分和总评分
                    Double reviewScore = person.getReviewScore();
                    scorePerson.setFinalScore(reviewScore);

                    Double totalScore = (person.getTotalScore() != null) ? person.getTotalScore() : reviewScore;
                    scorePerson.setTotalScore(totalScore != null ? totalScore : 0.0);
                    
                    // 保留原有的运行得分和停机扣分
                    scorePerson.setRunScore(person.getRunScore());
                    scorePerson.setStopScore(person.getStopScore());
                    
                    return scorePerson;
                }).collect(Collectors.toList());
                
                orderScoreInfo.setScorePersonList(scorePersons);
            } else {
                // 如果没有人员评分信息，则创建一个空列表，避免空指针异常
                orderScoreInfo.setScorePersonList(new ArrayList<>());
            }

            // 调用现有的终评方法
            int result = orderScoreService.finalEvaluation(orderScoreInfo);
            
            if (result > 0) {
                log.info("工单 {} 已成功自动终评", order.getWorkOrderProjectNo());
            } else {
                log.warn("工单 {} 自动终评失败", order.getWorkOrderProjectNo());
            }
        } catch (Exception e) {
            log.error("自动终评工单 {} 时发生异常", order.getWorkOrderProjectNo(), e);
        }
    }

    /**
     * 设置系统用户上下文，用于自动操作
     */
    private void setSystemUserContext() {
        try {
            // 获取admin用户信息
            SysUser userAdmin = userMapper.selectUserByUserName("admin");
            if (userAdmin != null) {
                Set<String> permissions = permissionService.getMenuPermission(userAdmin);
                LoginUser loginUser = new LoginUser(userAdmin, permissions);

                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                        loginUser,
                        null,
                        loginUser.getAuthorities()
                );

                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        } catch (Exception e) {
            log.error("设置系统用户上下文失败", e);
        }
    }
}