import ComposableArchitecture
import Foundation

/// Events that update the Orpheus session state.
///
/// These events are dispatched to the session store to update the session state.
public enum OrpheusSessionEvent: Equatable {
    /// A message has been added to the current session.
    case messageAdded(OrpheusMessage)
    
    /// A specific message has been updated via a transform function.
    /// If clipIdsToFetch is provided, the repository will fetch those clips and update the message.
    /// Note: In Swift, we can't use closures in Equatable, so we'll use a different approach
    case messageUpdated(messageId: String, message: OrpheusMessage, clipIdsToFetch: [String]? = nil)
    
    /// All messages have been replaced with a new list.
    case messagesReplaced(IdentifiedArrayOf<OrpheusMessage>)

    /// The workspace ID for the session has been updated.
    case workspaceUpdated(String)
    
    /// No operation - event handled but no state change needed.
    case noOp
    
    // MARK: - Equatable
    
    public static func == (lhs: OrpheusSessionEvent, rhs: OrpheusSessionEvent) -> Bool {
        switch (lhs, rhs) {
        case (.messageAdded(let lhsMsg), .messageAdded(let rhsMsg)):
            return lhsMsg == rhsMsg
        case (.messageUpdated(let lhsId, let lhsMsg, let lhsClips), .messageUpdated(let rhsId, let rhsMsg, let rhsClips)):
            return lhsId == rhsId && lhsMsg == rhsMsg && lhsClips == rhsClips
        case (.messagesReplaced(let lhsMessages), .messagesReplaced(let rhsMessages)):
            return lhsMessages == rhsMessages
        case (.workspaceUpdated(let lhsId), .workspaceUpdated(let rhsId)):
            return lhsId == rhsId
        case (.noOp, .noOp):
            return true
        default:
            return false
        }
    }
}

