package com.fs.erp.mapper;

import com.fs.erp.domain.FsJstAftersalePush;
import org.apache.ibatis.annotations.*;

import java.util.List;

/**
 * 订阅物流Mapper
 */
@Mapper
public interface FsJstAftersalePushMapper {

    /**
     * 根据ID查询
     */
    @Select("<script>" +
            "SELECT * FROM fs_jst_aftersale_push " +
            "<where>" +
            "   <if test='id != null'>" +
            "       id = #{id}" +
            "   </if>" +
            "</where>" +
            "</script>")
    FsJstAftersalePush selectById(Long id);

    /**
     * 根据订单ID查询
     */
    @Select("<script>" +
            "SELECT * FROM fs_jst_aftersale_push " +
            "<where>" +
            "   <if test='orderId != null and orderId != \"\"'>" +
            "       order_id = #{orderId}" +
            "   </if>" +
            "</where>" +
            "</script>")
    FsJstAftersalePush selectByOrderId(String orderId);

    /**
     * 查询待处理的任务
     */
    @Select("<script>" +
            "SELECT * FROM fs_jst_aftersale_push " +
            "<where>" +
            "   <if test='status != null'>" +
            "       task_status = #{status}" +
            "   </if>" +
            "   <if test='maxRetry != null'>" +
            "       AND retry_count &lt; #{maxRetry}" +
            "   </if>" +
            "</where>" +
            "<if test='limit != null and limit > 0'>" +
            "   LIMIT #{limit}" +
            "</if>" +
            "</script>")
    List<FsJstAftersalePush> selectByStatusAndRetry(Byte status, Integer maxRetry, Integer limit);

    /**
     * 插入记录
     */
    @Insert("<script>" +
            "<if test='orderId != null and orderId != \"\"'>" +
            "INSERT INTO fs_jst_aftersale_push(" +
            "   <trim suffixOverrides=','>" +
            "       order_id," +
            "       <if test='afterSaleId != null and afterSaleId != \"\"'>after_sale_id,</if>" +
            "       <if test='type != null'>type,</if>" +
            "       <if test='taskStatus != null'>task_status,</if>" +
            "       <if test='retryCount != null'>retry_count,</if>" +
            "       <if test='lastExecuteTime != null'>last_execute_time,</if>" +
            "       <if test='params != null and params != \"\"'>params,</if>" +
            "       <if test='orderType != null and orderType != \"\"'>order_type</if>" +
            "   </trim>" +
            ") VALUES(" +
            "   <trim suffixOverrides=','>" +
            "       #{orderId}," +
            "       <if test='afterSaleId != null and afterSaleId != \"\"'>#{afterSaleId},</if>" +
            "       <if test='type != null'>#{type},</if>" +
            "       <if test='taskStatus != null'>#{taskStatus},</if>" +
            "       <if test='retryCount != null'>#{retryCount},</if>" +
            "       <if test='lastExecuteTime != null'>#{lastExecuteTime},</if>" +
            "       <if test='params != null and params != \"\"'>#{params},</if>" +
            "       <if test='orderType != null and orderType != \"\"'>#{orderType}</if>" +
            "   </trim>" +
            ")" +
            "</if>" +
            "</script>")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insert(FsJstAftersalePush push);

    /**
     * 更新记录
     */
    @Update("<script>" +
            "<if test='id != null'>" +
            "UPDATE fs_jst_aftersale_push " +
            "<set>" +
            "   <if test='params != null'>params = #{params},</if>" +
            "   <if test='taskStatus != null'>task_status = #{taskStatus},</if>" +
            "   <if test='retryCount != null'>retry_count = #{retryCount},</if>" +
            "   <if test='lastExecuteTime != null'>last_execute_time = #{lastExecuteTime},</if>" +
            "   <if test='result != null'>result = #{result},</if>" +
            "   <if test='errorMessage != null'>error_message = #{errorMessage},</if>" +
        "       <if test='orderType != null and orderType != \"\"'>order_type = #{orderType}</if>" +
            "</set>" +
            "WHERE id = #{id}" +
            "</if>" +
            "</script>")
    int update(FsJstAftersalePush push);

    /**
     * 更新任务状态
     */
    @Update("<script>" +
            "<if test='id != null and taskStatus != null'>" +
            "UPDATE fs_jst_aftersale_push SET " +
            "   task_status = #{taskStatus}, " +
            "   last_execute_time = now() " +
            "WHERE id = #{id}" +
            "</if>" +
            "</script>")
    int updateStatus(@Param("id") Long id, @Param("taskStatus") Byte taskStatus);

    /**
     * 查询待处理数据 - 复杂查询保持原样，因为这是内部调用的复杂业务逻辑
     */
    @Select("WITH OrderWithNextTaskType AS (\n" +
            "    SELECT \n" +
            "        id,\n" +
            "        order_id,\n" +
            "        after_sale_id,\n" +
            "        type,\n" +
            "        task_status,\n" +
            "        retry_count,\n" +
            "        ROW_NUMBER() OVER(PARTITION BY order_id ORDER BY CAST(type AS UNSIGNED)) AS task_seq, order_type " +
            "    FROM \n" +
            "        fs_jst_aftersale_push\n" +
            "),\n" +
            "PendingTasks AS (\n" +
            "    SELECT \n" +
            "        o.id,\n" +
            "        o.order_id,\n" +
            "        o.after_sale_id,\n" +
            "        o.type,\n" +
            "        o.task_status,\n" +
            "        o.retry_count,\n" +
            "        o.task_seq,\n" +
            "        (\n" +
            "            SELECT MAX(p.task_status)  \n" +
            "            FROM OrderWithNextTaskType p\n" +
            "            WHERE p.order_id = o.order_id\n" +
            "              AND p.task_seq = o.task_seq - 1\n" +
            "        ) AS prev_task_status,\n" +
            "        EXISTS (\n" +
            "            SELECT 1\n" +
            "            FROM OrderWithNextTaskType p\n" +
            "            WHERE p.order_id = o.order_id\n" +
            "              AND p.task_seq < o.task_seq\n" +
            "              AND p.task_status != 1\n" +
            "        ) AS has_pending_prev_task, order_type " +
            "    FROM \n" +
            "        OrderWithNextTaskType o\n" +
            "    WHERE \n" +
            "        o.task_status = 0 OR (o.task_status = 2 AND o.retry_count < 3)\n" +
            ")\n" +
            "SELECT \n" +
            "    id,\n" +
            "    order_id,\n" +
            "    after_sale_id,\n" +
            "    type,\n" +
            "    task_status,\n" +
            "    retry_count, order_type " +
            "FROM \n" +
            "    PendingTasks\n" +
            "WHERE \n" +
            "    (task_seq = 1 OR prev_task_status = 1)\n" +
            "    AND has_pending_prev_task = 0\n" +
            "ORDER BY\n" +
            "    order_id,\n" +
            "    task_seq;\n")
    List<FsJstAftersalePush> queryPenddingData();
}
