/**
 * 优先级队列实现（使用最小堆）
 * 优先级高的任务（priority值大）会优先出队
 */
class PriorityQueue {
    constructor() {
        this.heap = [];
    }

    /**
     * 获取父节点索引
     */
    parent(index) {
        return Math.floor((index - 1) / 2);
    }

    /**
     * 获取左子节点索引
     */
    leftChild(index) {
        return 2 * index + 1;
    }

    /**
     * 获取右子节点索引
     */
    rightChild(index) {
        return 2 * index + 2;
    }

    /**
     * 交换两个节点
     */
    swap(i, j) {
        [this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]];
    }

    /**
     * 上浮操作（插入时使用）
     */
    bubbleUp(index) {
        if (index === 0) return;

        const parentIndex = this.parent(index);
        const current = this.heap[index];
        const parent = this.heap[parentIndex];

        // 优先级高的在前（priority值大），如果优先级相同，创建时间早的在前
        if (
            current.priority > parent.priority ||
            (current.priority === parent.priority && current.createdAt < parent.createdAt)
        ) {
            this.swap(index, parentIndex);
            this.bubbleUp(parentIndex);
        }
    }

    /**
     * 下沉操作（删除时使用）
     */
    bubbleDown(index) {
        const leftIndex = this.leftChild(index);
        const rightIndex = this.rightChild(index);
        let largest = index;

        const current = this.heap[index];

        // 比较左子节点
        if (leftIndex < this.heap.length) {
            const left = this.heap[leftIndex];
            if (
                left.priority > current.priority ||
                (left.priority === current.priority && left.createdAt < current.createdAt)
            ) {
                largest = leftIndex;
            }
        }

        // 比较右子节点
        if (rightIndex < this.heap.length) {
            const right = this.heap[rightIndex];
            const largestNode = this.heap[largest];
            if (
                right.priority > largestNode.priority ||
                (right.priority === largestNode.priority && right.createdAt < largestNode.createdAt)
            ) {
                largest = rightIndex;
            }
        }

        if (largest !== index) {
            this.swap(index, largest);
            this.bubbleDown(largest);
        }
    }

    /**
     * 添加任务到队列
     * @param {Object} task - 任务对象，必须包含 priority 和 createdAt 属性
     */
    push(task) {
        if (!task.hasOwnProperty('priority')) {
            task.priority = 5; // 默认优先级
        }
        if (!task.hasOwnProperty('createdAt')) {
            task.createdAt = Date.now();
        }
        this.heap.push(task);
        this.bubbleUp(this.heap.length - 1);
    }

    /**
     * 取出优先级最高的任务
     * @returns {Object|null} 任务对象或null
     */
    pop() {
        if (this.heap.length === 0) {
            return null;
        }

        if (this.heap.length === 1) {
            return this.heap.pop();
        }

        const top = this.heap[0];
        this.heap[0] = this.heap.pop();
        this.bubbleDown(0);

        return top;
    }

    /**
     * 查看优先级最高的任务（不移除）
     * @returns {Object|null} 任务对象或null
     */
    peek() {
        return this.heap.length > 0 ? this.heap[0] : null;
    }

    /**
     * 获取队列大小
     * @returns {number}
     */
    size() {
        return this.heap.length;
    }

    /**
     * 检查队列是否为空
     * @returns {boolean}
     */
    isEmpty() {
        return this.heap.length === 0;
    }

    /**
     * 清空队列
     */
    clear() {
        this.heap = [];
    }

    /**
     * 查找任务
     * @param {Function} predicate - 查找条件函数
     * @returns {Object|null} 任务对象或null
     */
    find(predicate) {
        return this.heap.find(predicate) || null;
    }

    /**
     * 移除任务
     * @param {Function} predicate - 查找条件函数
     * @returns {boolean} 是否成功移除
     */
    remove(predicate) {
        const index = this.heap.findIndex(predicate);
        if (index === -1) {
            return false;
        }

        if (index === this.heap.length - 1) {
            this.heap.pop();
            return true;
        }

        // 将最后一个元素移到当前位置
        this.heap[index] = this.heap.pop();

        // 重新调整堆
        const parentIndex = this.parent(index);
        if (index > 0 && this.heap[parentIndex] && 
            (this.heap[index].priority > this.heap[parentIndex].priority ||
             (this.heap[index].priority === this.heap[parentIndex].priority && 
              this.heap[index].createdAt < this.heap[parentIndex].createdAt))) {
            this.bubbleUp(index);
        } else {
            this.bubbleDown(index);
        }

        return true;
    }

    /**
     * 转换为数组（用于调试）
     * @returns {Array}
     */
    toArray() {
        return [...this.heap];
    }
}

module.exports = PriorityQueue;

