package com.correx.core.events.events

import com.correx.core.approvals.ApprovalOutcome
import com.correx.core.approvals.ApprovalStatus
import com.correx.core.approvals.GrantScope
import com.correx.core.approvals.Tier
import com.correx.core.approvals.UserSteering
import com.correx.core.events.risk.RiskSummary
import com.correx.core.events.types.ApprovalDecisionId
import com.correx.core.events.types.ApprovalRequestId
import com.correx.core.events.types.GrantId
import com.correx.core.events.types.ProjectId
import com.correx.core.events.types.RiskSummaryId
import com.correx.core.events.types.SessionId
import com.correx.core.events.types.StageId
import com.correx.core.events.types.ValidationReportId
import kotlinx.datetime.Instant
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
@SerialName("ApprovalRequested")
data class ApprovalRequestedEvent(
    val requestId: ApprovalRequestId,
    val tier: Tier,
    val validationReportId: ValidationReportId,
    val riskSummaryId: RiskSummaryId?,
    val riskSummary: RiskSummary? = null,
    val sessionId: SessionId,
    val stageId: StageId?,
    val projectId: ProjectId?,
    val userSteering: UserSteering? = null,
    val toolName: String? = null,
    val preview: String? = null,
) : EventPayload

@Serializable
@SerialName("ApprovalDecisionResolved")
data class ApprovalDecisionResolvedEvent(
    val decisionId: ApprovalDecisionId,
    val requestId: ApprovalRequestId,
    val outcome: ApprovalOutcome,
    val status: ApprovalStatus,
    val tier: Tier,
    val resolutionTimestamp: Instant,
    val reason: String?,
    val userSteering: UserSteering? = null,
) : EventPayload

@Serializable
@SerialName("ApprovalGrantCreated")
data class ApprovalGrantCreatedEvent(
    val grantId: GrantId,
    val scope: GrantScope,
    val permittedTiers: Set<Tier>,
    val reason: String,
    val expiresAt: Instant?,
    val sessionId: SessionId,
    val stageId: StageId?,
    val projectId: ProjectId?,
    // Operation identity — must match DomainApprovalRequest.toolName for SESSION grants.
    // Defaulted null for backward-compatible deserialization; new events always carry a value.
    @SerialName("toolName") val toolName: String? = null,
) : EventPayload

@Serializable
@SerialName("ApprovalGrantExpired")
data class ApprovalGrantExpiredEvent(
    val grantId: GrantId,
) : EventPayload
