import { fileURLToPath as __fileURLToPath } from 'url';
import { dirname as __pathDirname } from 'path';
const __filename = __fileURLToPath(import.meta.url);
const __dirname = __pathDirname(__filename);
import { logger } from "../monitoring/logger.js";
import { ValidationError, DatabaseError, ErrorCode } from "../errors/index.js";
import {
  validateInput,
  InitiateHandoffSchema,
  HandoffApprovalSchema
} from "./validation.js";
class FrameHandoffManager {
  dualStackManager;
  activeHandoffs = /* @__PURE__ */ new Map();
  pendingApprovals = /* @__PURE__ */ new Map();
  notifications = /* @__PURE__ */ new Map();
  constructor(dualStackManager) {
    this.dualStackManager = dualStackManager;
  }
  /**
   * Initiate a frame handoff with rich metadata and approval workflow
   */
  async initiateHandoff(targetStackId, frameIds, metadata, targetUserId, message) {
    const input = validateInput(InitiateHandoffSchema, {
      targetStackId,
      frameIds,
      handoffRequest: metadata,
      reviewerId: targetUserId,
      description: message
    });
    try {
      await this.dualStackManager.getPermissionManager().enforcePermission(
        this.dualStackManager.getPermissionManager().createContext(
          input.handoffRequest.initiatorId,
          "handoff",
          "handoff",
          input.targetStackId
        )
      );
      await this.validateFramesForHandoff(input.frameIds);
      const requestId = await this.dualStackManager.initiateHandoff(
        input.targetStackId,
        input.frameIds,
        input.reviewerId,
        input.description
      );
      const progress = {
        requestId,
        status: "pending_review",
        transferredFrames: 0,
        totalFrames: input.frameIds.length,
        currentStep: "Awaiting approval",
        errors: []
      };
      this.activeHandoffs.set(requestId, progress);
      await this.createHandoffNotifications(requestId, metadata, targetUserId);
      await this.scheduleHandoffReminders(requestId, metadata);
      logger.info(`Initiated enhanced handoff: ${requestId}`, {
        frameCount: frameIds.length,
        priority: metadata.businessContext?.priority,
        targetUser: targetUserId
      });
      return requestId;
    } catch (error) {
      throw new DatabaseError(
        "Failed to initiate handoff",
        ErrorCode.OPERATION_FAILED,
        { targetStackId, frameIds },
        error instanceof Error ? error : void 0
      );
    }
  }
  /**
   * Submit approval/rejection for handoff request
   */
  async submitHandoffApproval(requestId, approval) {
    const input = validateInput(HandoffApprovalSchema, {
      ...approval,
      reviewerId: approval.reviewerId
    });
    const progress = this.activeHandoffs.get(requestId);
    if (!progress) {
      throw new ValidationError(
        `Handoff request not found: ${requestId}`,
        ErrorCode.HANDOFF_REQUEST_EXPIRED
      );
    }
    const fullApproval = {
      ...input,
      requestId,
      reviewedAt: /* @__PURE__ */ new Date()
    };
    const existingApprovals = this.pendingApprovals.get(requestId) || [];
    existingApprovals.push(fullApproval);
    this.pendingApprovals.set(requestId, existingApprovals);
    if (input.decision === "approved") {
      progress.status = "approved";
      progress.currentStep = "Ready for transfer";
      await this.executeHandoffTransfer(requestId);
    } else if (input.decision === "rejected") {
      progress.status = "failed";
      progress.currentStep = "Rejected by reviewer";
      progress.errors.push({
        step: "approval",
        error: input.feedback || "Request rejected",
        timestamp: /* @__PURE__ */ new Date()
      });
    } else if (input.decision === "needs_changes") {
      progress.status = "pending_review";
      progress.currentStep = "Changes requested";
      await this.notifyChangesRequested(requestId, approval);
    }
    this.activeHandoffs.set(requestId, progress);
    logger.info(`Handoff approval submitted: ${requestId}`, {
      decision: approval.decision,
      reviewer: approval.reviewerId
    });
  }
  /**
   * Execute the actual frame transfer after approval
   */
  async executeHandoffTransfer(requestId) {
    logger.debug("executeHandoffTransfer called", {
      requestId,
      availableHandoffs: Array.from(this.activeHandoffs.keys())
    });
    const progress = this.activeHandoffs.get(requestId);
    if (!progress) {
      logger.error("Handoff progress not found", {
        requestId,
        availableHandoffs: Array.from(this.activeHandoffs.keys())
      });
      throw new DatabaseError(
        `Handoff progress not found: ${requestId}`,
        ErrorCode.INVALID_STATE
      );
    }
    try {
      logger.debug("Setting progress status to in_transfer", { requestId });
      progress.status = "in_transfer";
      progress.currentStep = "Transferring frames";
      progress.estimatedCompletion = new Date(Date.now() + 5 * 60 * 1e3);
      logger.debug("About to call acceptHandoff", { requestId });
      const result = await this.dualStackManager.acceptHandoff(requestId);
      logger.debug("acceptHandoff returned", {
        requestId,
        success: result.success
      });
      if (result.success) {
        progress.status = "completed";
        progress.currentStep = "Transfer completed";
        progress.transferredFrames = result.mergedFrames.length;
        await this.notifyHandoffCompletion(requestId, result);
        logger.info(`Handoff transfer completed: ${requestId}`, {
          transferredFrames: progress.transferredFrames,
          conflicts: result.conflictFrames.length
        });
      } else {
        progress.status = "failed";
        progress.currentStep = "Transfer failed";
        result.errors.forEach((error) => {
          progress.errors.push({
            step: "transfer",
            error: `Frame ${error.frameId}: ${error.error}`,
            timestamp: /* @__PURE__ */ new Date()
          });
        });
        throw new DatabaseError(
          "Handoff transfer failed",
          ErrorCode.OPERATION_FAILED,
          { errors: result.errors }
        );
      }
    } catch (error) {
      progress.status = "failed";
      progress.currentStep = "Transfer error";
      progress.errors.push({
        step: "transfer",
        error: error instanceof Error ? error.message : String(error),
        timestamp: /* @__PURE__ */ new Date()
      });
      logger.error(`Handoff transfer failed: ${requestId}`, error);
      throw error;
    } finally {
      this.activeHandoffs.set(requestId, progress);
    }
  }
  /**
   * Get handoff progress and status
   */
  async getHandoffProgress(requestId) {
    return this.activeHandoffs.get(requestId) || null;
  }
  /**
   * Cancel a pending handoff request
   */
  async cancelHandoff(requestId, reason) {
    const progress = this.activeHandoffs.get(requestId);
    if (!progress) {
      throw new DatabaseError(
        `Handoff request not found: ${requestId}`,
        ErrorCode.RESOURCE_NOT_FOUND
      );
    }
    if (progress.status === "in_transfer") {
      throw new DatabaseError(
        "Cannot cancel handoff that is currently transferring",
        ErrorCode.INVALID_STATE
      );
    }
    progress.status = "cancelled";
    progress.currentStep = "Cancelled by user";
    progress.errors.push({
      step: "cancellation",
      error: reason,
      timestamp: /* @__PURE__ */ new Date()
    });
    this.activeHandoffs.set(requestId, progress);
    await this.notifyHandoffCancellation(requestId, reason);
    logger.info(`Handoff cancelled: ${requestId}`, { reason });
  }
  /**
   * Get all active handoffs for a user or team
   */
  async getActiveHandoffs(userId, teamId) {
    const handoffs = Array.from(this.activeHandoffs.values());
    if (userId || teamId) {
      return handoffs.filter(
        (handoff) => handoff.status === "pending_review" || handoff.status === "approved" || handoff.status === "in_transfer"
      );
    }
    return handoffs;
  }
  /**
   * Get notifications for a user
   */
  async getUserNotifications(userId) {
    return this.notifications.get(userId) || [];
  }
  /**
   * Mark notification as read
   */
  async markNotificationRead(notificationId, userId) {
    const userNotifications = this.notifications.get(userId) || [];
    const updatedNotifications = userNotifications.filter(
      (n) => n.id !== notificationId
    );
    this.notifications.set(userId, updatedNotifications);
  }
  /**
   * Validate frames are suitable for handoff
   */
  async validateFramesForHandoff(frameIds) {
    const activeStack = this.dualStackManager.getActiveStack();
    for (const frameId of frameIds) {
      const frame = await activeStack.getFrame(frameId);
      if (!frame) {
        throw new DatabaseError(
          `Frame not found: ${frameId}`,
          ErrorCode.RESOURCE_NOT_FOUND
        );
      }
      if (frame.state === "active") {
        logger.warn(`Transferring active frame: ${frameId}`, {
          frameName: frame.name
        });
      }
    }
  }
  /**
   * Create notifications for handoff stakeholders
   */
  async createHandoffNotifications(requestId, metadata, targetUserId) {
    const notifications = [];
    if (targetUserId) {
      notifications.push({
        id: `${requestId}-target`,
        type: "request",
        requestId,
        recipientId: targetUserId,
        title: "Frame Handoff Request",
        message: `${metadata.initiatorId} wants to transfer ${metadata.frameContext.totalFrames} frames to you`,
        actionRequired: true,
        expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1e3),
        createdAt: /* @__PURE__ */ new Date()
      });
    }
    if (metadata.businessContext?.stakeholders) {
      for (const stakeholderId of metadata.businessContext.stakeholders) {
        notifications.push({
          id: `${requestId}-stakeholder-${stakeholderId}`,
          type: "request",
          requestId,
          recipientId: stakeholderId,
          title: "Frame Handoff Notification",
          message: `Frame transfer initiated for ${metadata.businessContext?.milestone || "project milestone"}`,
          actionRequired: false,
          createdAt: /* @__PURE__ */ new Date()
        });
      }
    }
    for (const notification of notifications) {
      const userNotifications = this.notifications.get(notification.recipientId) || [];
      userNotifications.push(notification);
      this.notifications.set(notification.recipientId, userNotifications);
    }
  }
  /**
   * Schedule reminder notifications
   */
  async scheduleHandoffReminders(requestId, metadata) {
    if (metadata.businessContext?.priority === "high" || metadata.businessContext?.priority === "critical") {
      setTimeout(
        async () => {
          const progress = this.activeHandoffs.get(requestId);
          if (progress && progress.status === "pending_review") {
            await this.sendHandoffReminder(requestId, metadata);
          }
        },
        4 * 60 * 60 * 1e3
      );
    }
  }
  /**
   * Send handoff reminder
   */
  async sendHandoffReminder(requestId, metadata) {
    const progress = this.activeHandoffs.get(requestId);
    if (!progress || progress.status !== "pending_review") {
      return;
    }
    const reminderNotification = {
      id: `${requestId}-reminder-${Date.now()}`,
      type: "reminder",
      requestId,
      recipientId: metadata.targetUserId || "unknown",
      title: "\u23F0 Handoff Request Reminder",
      message: `Reminder: ${metadata.initiatorId} is waiting for approval on ${metadata.frameContext.totalFrames} frames. Priority: ${metadata.businessContext?.priority || "medium"}`,
      actionRequired: true,
      expiresAt: new Date(Date.now() + 12 * 60 * 60 * 1e3),
      // 12 hours
      createdAt: /* @__PURE__ */ new Date()
    };
    if (metadata.targetUserId) {
      const userNotifications = this.notifications.get(metadata.targetUserId) || [];
      userNotifications.push(reminderNotification);
      this.notifications.set(metadata.targetUserId, userNotifications);
      logger.info(`Sent handoff reminder: ${requestId}`, {
        priority: metadata.businessContext?.priority,
        recipient: metadata.targetUserId
      });
    }
    if (metadata.businessContext?.stakeholders) {
      for (const stakeholderId of metadata.businessContext.stakeholders) {
        const stakeholderNotification = {
          ...reminderNotification,
          id: `${requestId}-reminder-stakeholder-${stakeholderId}-${Date.now()}`,
          recipientId: stakeholderId,
          title: "\u{1F4CB} Handoff Status Update",
          message: `Pending handoff approval: ${metadata.businessContext?.milestone || "development work"} requires attention`,
          actionRequired: false
        };
        const stakeholderNotifications = this.notifications.get(stakeholderId) || [];
        stakeholderNotifications.push(stakeholderNotification);
        this.notifications.set(stakeholderId, stakeholderNotifications);
      }
    }
  }
  /**
   * Notify when changes are requested
   */
  async notifyChangesRequested(requestId, approval) {
    const progress = this.activeHandoffs.get(requestId);
    if (!progress) return;
    const changeRequestNotification = {
      id: `${requestId}-changes-${Date.now()}`,
      type: "request",
      requestId,
      recipientId: "requester",
      // TODO: Get actual requester from handoff metadata
      title: "Changes Requested for Handoff",
      message: `${approval.reviewerId} has requested changes: ${approval.feedback || "See detailed suggestions"}`,
      actionRequired: true,
      expiresAt: new Date(Date.now() + 48 * 60 * 60 * 1e3),
      // 48 hours
      createdAt: /* @__PURE__ */ new Date()
    };
    const notifications = this.notifications.get("requester") || [];
    notifications.push(changeRequestNotification);
    this.notifications.set("requester", notifications);
    logger.info(`Changes requested for handoff: ${requestId}`, {
      reviewer: approval.reviewerId,
      feedback: approval.feedback,
      suggestedChangesCount: approval.suggestedChanges?.length || 0
    });
    if (approval.suggestedChanges && approval.suggestedChanges.length > 0) {
      logger.info(`Detailed change suggestions:`, {
        requestId,
        suggestions: approval.suggestedChanges.map((change) => ({
          frameId: change.frameId,
          suggestion: change.suggestion,
          reason: change.reason
        }))
      });
    }
  }
  /**
   * Notify handoff completion
   */
  async notifyHandoffCompletion(requestId, result) {
    const progress = this.activeHandoffs.get(requestId);
    if (!progress) return;
    const completionNotification = {
      id: `${requestId}-completion-${Date.now()}`,
      type: "completion",
      requestId,
      recipientId: "all",
      // Will be distributed to all stakeholders
      title: "Handoff Completed Successfully",
      message: `Frame transfer completed: ${result.mergedFrames.length} frames transferred${result.conflictFrames.length > 0 ? `, ${result.conflictFrames.length} conflicts resolved` : ""}`,
      actionRequired: false,
      createdAt: /* @__PURE__ */ new Date()
    };
    const allUsers = Array.from(this.notifications.keys());
    for (const userId of allUsers) {
      const userSpecificNotification = {
        ...completionNotification,
        id: `${requestId}-completion-${userId}-${Date.now()}`,
        recipientId: userId
      };
      const userNotifications = this.notifications.get(userId) || [];
      userNotifications.push(userSpecificNotification);
      this.notifications.set(userId, userNotifications);
    }
    logger.info(`Handoff completed: ${requestId}`, {
      mergedFrames: result.mergedFrames.length,
      conflicts: result.conflictFrames.length,
      notifiedUsers: allUsers.length
    });
    if (result.conflictFrames.length > 0) {
      logger.info(`Handoff completion details:`, {
        requestId,
        transferredFrames: result.mergedFrames.map(
          (f) => f.frameId || f.id
        ),
        conflictFrames: result.conflictFrames.map(
          (f) => f.frameId || f.id
        )
      });
    }
  }
  /**
   * Notify handoff cancellation
   */
  async notifyHandoffCancellation(requestId, reason) {
    const cancellationNotification = {
      id: `${requestId}-cancellation-${Date.now()}`,
      type: "request",
      // Using 'request' type as it's informational
      requestId,
      recipientId: "all",
      // Will be distributed to all stakeholders
      title: "Handoff Cancelled",
      message: `Handoff request has been cancelled. Reason: ${reason}`,
      actionRequired: false,
      createdAt: /* @__PURE__ */ new Date()
    };
    const allUsers = Array.from(this.notifications.keys());
    for (const userId of allUsers) {
      const userSpecificNotification = {
        ...cancellationNotification,
        id: `${requestId}-cancellation-${userId}-${Date.now()}`,
        recipientId: userId
      };
      const userNotifications = this.notifications.get(userId) || [];
      userNotifications.push(userSpecificNotification);
      this.notifications.set(userId, userNotifications);
    }
    logger.info(`Handoff cancelled: ${requestId}`, {
      reason,
      notifiedUsers: allUsers.length
    });
  }
  /**
   * Get handoff analytics and metrics
   */
  async getHandoffMetrics(timeRange) {
    const handoffs = Array.from(this.activeHandoffs.values());
    const filteredHandoffs = timeRange ? handoffs.filter((h) => {
      return true;
    }) : handoffs;
    const completedHandoffs = filteredHandoffs.filter(
      (h) => h.status === "completed"
    );
    return {
      totalHandoffs: filteredHandoffs.length,
      completedHandoffs: completedHandoffs.length,
      averageProcessingTime: this.calculateAverageProcessingTime(completedHandoffs),
      topFrameTypes: this.analyzeFrameTypes(filteredHandoffs),
      collaborationPatterns: this.analyzeCollaborationPatterns(filteredHandoffs)
    };
  }
  calculateAverageProcessingTime(handoffs) {
    if (handoffs.length === 0) return 0;
    let totalProcessingTime = 0;
    let validHandoffs = 0;
    for (const handoff of handoffs) {
      if (handoff.status === "completed" && handoff.estimatedCompletion) {
        const frameComplexity = handoff.totalFrames * 0.5;
        const errorPenalty = handoff.errors.length * 2;
        const processingTime = Math.max(1, frameComplexity + errorPenalty);
        totalProcessingTime += processingTime;
        validHandoffs++;
      }
    }
    return validHandoffs > 0 ? Math.round(totalProcessingTime / validHandoffs) : 0;
  }
  analyzeFrameTypes(handoffs) {
    const frameTypeCount = /* @__PURE__ */ new Map();
    for (const handoff of handoffs) {
      const estimatedTypes = this.estimateFrameTypes(handoff);
      for (const type of estimatedTypes) {
        frameTypeCount.set(type, (frameTypeCount.get(type) || 0) + 1);
      }
    }
    return Array.from(frameTypeCount.entries()).map(([type, count]) => ({ type, count })).sort((a, b) => b.count - a.count).slice(0, 10);
  }
  estimateFrameTypes(handoff) {
    const types = [];
    if (handoff.totalFrames > 10) {
      types.push("bulk_transfer");
    }
    if (handoff.errors.length > 0) {
      types.push("complex_handoff");
    }
    if (handoff.transferredFrames === handoff.totalFrames) {
      types.push("complete_transfer");
    } else {
      types.push("partial_transfer");
    }
    types.push("development", "collaboration");
    return types;
  }
  analyzeCollaborationPatterns(handoffs) {
    const collaborationCount = /* @__PURE__ */ new Map();
    for (const handoff of handoffs) {
      const pattern = this.extractCollaborationPattern(handoff);
      if (pattern) {
        const key = `${pattern.sourceUser}->${pattern.targetUser}`;
        collaborationCount.set(key, (collaborationCount.get(key) || 0) + 1);
      }
    }
    return Array.from(collaborationCount.entries()).map(([pattern, count]) => {
      const [sourceUser, targetUser] = pattern.split("->");
      return { sourceUser, targetUser, count };
    }).sort((a, b) => b.count - a.count).slice(0, 20);
  }
  extractCollaborationPattern(handoff) {
    if (handoff.status === "completed") {
      return {
        sourceUser: "developer",
        targetUser: "reviewer"
      };
    } else if (handoff.status === "failed") {
      return {
        sourceUser: "developer",
        targetUser: "lead"
      };
    }
    return null;
  }
  /**
   * Real-time collaboration features
   */
  /**
   * Get real-time handoff status updates
   */
  async getHandoffStatusStream(requestId) {
    const progress = this.activeHandoffs.get(requestId);
    if (!progress) {
      throw new DatabaseError(
        `Handoff request not found: ${requestId}`,
        ErrorCode.RESOURCE_NOT_FOUND
      );
    }
    const self = this;
    return {
      async *[Symbol.asyncIterator]() {
        let lastStatus = progress.status;
        while (lastStatus !== "completed" && lastStatus !== "failed" && lastStatus !== "cancelled") {
          const currentProgress = self.activeHandoffs.get(requestId);
          if (currentProgress && currentProgress.status !== lastStatus) {
            lastStatus = currentProgress.status;
            yield currentProgress;
          }
          await new Promise((resolve) => setTimeout(resolve, 1e3));
        }
      }
    };
  }
  /**
   * Update handoff progress in real-time
   */
  async updateHandoffProgress(requestId, update) {
    let progress = this.activeHandoffs.get(requestId);
    if (!progress && update.requestId && update.status && update.totalFrames !== void 0) {
      progress = {
        requestId: update.requestId,
        status: update.status,
        transferredFrames: 0,
        totalFrames: update.totalFrames,
        currentStep: "Initialized",
        errors: [],
        ...update
      };
    } else if (!progress) {
      throw new DatabaseError(
        `Handoff request not found: ${requestId}`,
        ErrorCode.RESOURCE_NOT_FOUND
      );
    } else {
      progress = {
        ...progress,
        ...update
      };
    }
    this.activeHandoffs.set(requestId, progress);
    logger.info(`Handoff progress updated: ${requestId}`, {
      status: progress.status,
      currentStep: progress.currentStep,
      transferredFrames: progress.transferredFrames
    });
    await this.notifyProgressUpdate(requestId, progress);
  }
  /**
   * Notify stakeholders of progress updates
   */
  async notifyProgressUpdate(requestId, progress) {
    const updateNotification = {
      id: `${requestId}-progress-${Date.now()}`,
      type: "request",
      requestId,
      recipientId: "all",
      title: "Handoff Progress Update",
      message: `Status: ${progress.status} | Step: ${progress.currentStep} | Progress: ${progress.transferredFrames}/${progress.totalFrames} frames`,
      actionRequired: false,
      createdAt: /* @__PURE__ */ new Date()
    };
    const allUsers = Array.from(this.notifications.keys());
    for (const userId of allUsers) {
      const userNotifications = this.notifications.get(userId) || [];
      userNotifications.push({
        ...updateNotification,
        id: `${requestId}-progress-${userId}-${Date.now()}`,
        recipientId: userId
      });
      this.notifications.set(userId, userNotifications);
    }
  }
  /**
   * Get active handoffs with real-time filtering
   */
  async getActiveHandoffsRealTime(filters) {
    let handoffs = Array.from(this.activeHandoffs.values());
    if (filters?.status) {
      handoffs = handoffs.filter((h) => h.status === filters.status);
    }
    if (filters?.userId) {
      handoffs = handoffs.filter(
        (h) => h.requestId.includes(filters.userId || "")
      );
    }
    if (filters?.priority) {
      handoffs = handoffs.filter((h) => {
        const estimatedPriority = this.estimateHandoffPriority(h);
        return estimatedPriority === filters.priority;
      });
    }
    return handoffs.sort((a, b) => {
      const statusPriority = {
        in_transfer: 4,
        approved: 3,
        pending_review: 2,
        completed: 1,
        failed: 1,
        cancelled: 0
      };
      return (statusPriority[b.status] || 0) - (statusPriority[a.status] || 0);
    });
  }
  estimateHandoffPriority(handoff) {
    if (handoff.errors.length > 2 || handoff.totalFrames > 50)
      return "critical";
    if (handoff.errors.length > 0 || handoff.totalFrames > 20) return "high";
    if (handoff.totalFrames > 5) return "medium";
    return "low";
  }
  /**
   * Bulk handoff operations for team collaboration
   */
  async bulkHandoffOperation(operation) {
    const results = {
      successful: [],
      failed: []
    };
    for (const requestId of operation.requestIds) {
      try {
        switch (operation.action) {
          case "approve":
            await this.submitHandoffApproval(requestId, {
              reviewerId: operation.reviewerId,
              decision: "approved",
              feedback: operation.feedback
            });
            results.successful.push(requestId);
            break;
          case "reject":
            await this.submitHandoffApproval(requestId, {
              reviewerId: operation.reviewerId,
              decision: "rejected",
              feedback: operation.feedback || "Bulk rejection"
            });
            results.successful.push(requestId);
            break;
          case "cancel":
            await this.cancelHandoff(
              requestId,
              operation.feedback || "Bulk cancellation"
            );
            results.successful.push(requestId);
            break;
        }
      } catch (error) {
        results.failed.push({
          requestId,
          error: error instanceof Error ? error.message : String(error)
        });
      }
    }
    logger.info(`Bulk handoff operation completed`, {
      action: operation.action,
      successful: results.successful.length,
      failed: results.failed.length,
      reviewerId: operation.reviewerId
    });
    return results;
  }
  /**
   * Enhanced notification management with cleanup
   */
  async cleanupExpiredNotifications(userId) {
    let cleanedCount = 0;
    const now = /* @__PURE__ */ new Date();
    const userIds = userId ? [userId] : Array.from(this.notifications.keys());
    for (const uid of userIds) {
      const userNotifications = this.notifications.get(uid) || [];
      const activeNotifications = userNotifications.filter((notification) => {
        if (notification.expiresAt && notification.expiresAt < now) {
          cleanedCount++;
          return false;
        }
        return true;
      });
      this.notifications.set(uid, activeNotifications);
    }
    if (cleanedCount > 0) {
      logger.info(`Cleaned up expired notifications`, {
        count: cleanedCount,
        userId: userId || "all"
      });
    }
    return cleanedCount;
  }
}
export {
  FrameHandoffManager
};
//# sourceMappingURL=frame-handoff-manager.js.map
