package com.fs.erp.mapper;

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

import java.util.List;

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

    /**
     * 根据ID查询
     */
    @Select("SELECT * FROM fs_jst_aftersale_push_scrm WHERE id = #{id}")
    FsJstAftersalePush selectById(Long id);

    /**
     * 根据订单ID查询
     */
    @Select("SELECT * FROM fs_jst_aftersale_push_scrm WHERE order_id = #{orderId}")
    FsJstAftersalePush selectByOrderId(String orderId);

    /**
     * 查询待处理的任务
     */
    @Select("SELECT * FROM fs_jst_aftersale_push_scrm WHERE task_status = #{status} AND retry_count < #{maxRetry} LIMIT #{limit}")
    List<FsJstAftersalePush> selectByStatusAndRetry(Byte status, Integer maxRetry, Integer limit);

    /**
     * 插入记录
     */
    @Insert("INSERT INTO fs_jst_aftersale_push_scrm(order_id,after_sale_id, type, task_status, retry_count, last_execute_time, params) " +
            "VALUES(#{orderId},#{afterSaleId}, #{type}, #{taskStatus}, #{retryCount}, #{lastExecuteTime}, #{params})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insert(FsJstAftersalePush push);

    /**
     * 更新记录
     */
    @Update("UPDATE fs_jst_aftersale_push_scrm SET params=#{params},task_status = #{taskStatus}, retry_count = #{retryCount}, " +
            "last_execute_time = #{lastExecuteTime}, result = #{result}, error_message = #{errorMessage} " +
            "WHERE id = #{id}")
    int update(FsJstAftersalePush push);

    /**
     * 更新任务状态
     */
    @Update("UPDATE fs_jst_aftersale_push_scrm SET task_status = #{taskStatus}, " +
            "last_execute_time = now() WHERE id = #{id}")
    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\n" +
            "    FROM \n" +
            "        fs_jst_aftersale_push_scrm\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\n" +
            "    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\n" +
            "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();
}
