import { Schema } from "effect"

export {
  SessionEventID as ID,
  type SessionEventID as IDType,
  Source,
  FileAttachment,
  AgentAttachment,
  RetryError,
  Prompt,
  Synthetic,
  Retried,
  Compacted,
} from "./session-event-base"

export { Step } from "./session-event-step"
export { Text, Reasoning } from "./session-event-stream"
export { Tool } from "./session-event-tool"

import { SessionEventID as ID } from "./session-event-base"
import { Source } from "./session-event-base"
import { FileAttachment } from "./session-event-base"
import { AgentAttachment } from "./session-event-base"
import { RetryError } from "./session-event-base"
import { Prompt } from "./session-event-base"
import { Synthetic } from "./session-event-base"
import { Retried } from "./session-event-base"
import { Compacted } from "./session-event-base"
import { Step } from "./session-event-step"
import { Text, Reasoning } from "./session-event-stream"
import { Tool } from "./session-event-tool"

const Event = Schema.Union(
  [
    Prompt,
    Synthetic,
    Step.Started,
    Step.Ended,
    Text.Started,
    Text.Delta,
    Text.Ended,
    Tool.Input.Started,
    Tool.Input.Delta,
    Tool.Input.Ended,
    Tool.Called,
    Tool.Success,
    Tool.Error,
    Reasoning.Started,
    Reasoning.Delta,
    Reasoning.Ended,
    Retried,
    Compacted,
  ],
  { mode: "oneOf" },
).pipe(Schema.toTaggedUnion("type"))

type Event = Schema.Schema.Type<typeof Event>

export const SessionEvent = {
  ID,
  Source,
  FileAttachment,
  AgentAttachment,
  RetryError,
  Prompt,
  Synthetic,
  Retried,
  Compacted,
  Step,
  Text,
  Reasoning,
  Tool,
  Event,
} as const

export type SessionEvent = {
  ID: typeof ID
  Source: typeof Source
  FileAttachment: typeof FileAttachment
  AgentAttachment: typeof AgentAttachment
  RetryError: typeof RetryError
  Prompt: typeof Prompt
  Synthetic: typeof Synthetic
  Retried: typeof Retried
  Compacted: typeof Compacted
  Step: typeof Step
  Text: typeof Text
  Reasoning: typeof Reasoning
  Tool: typeof Tool
  Event: Event
  Type: Event["type"]
}
