import type { Tables, TablesInsert } from '../../supabase/database.types'
import type { MessageEvent } from '../../execution/engine/base/types'
import type { AgentMemory } from '../../execution/engine/agent/memory/types'

// Database table types (use imported Supabase types)
export type SessionRow = Tables<'sessions'>
export type SessionInsert = TablesInsert<'sessions'>
export type SessionMessageRow = Tables<'session_messages'>
export type SessionMessageInsert = TablesInsert<'session_messages'>

// Extract all event types from MessageEvent discriminated union
export type MessageType = MessageEvent['type']

/**
 * Session Data Transfer Object (DTO)
 * Transform type for API responses (snake_case DB → camelCase frontend)
 * Used by frontend apps to display session data
 */
export interface SessionDTO {
  sessionId: string
  resourceId: string
  organizationId: string
  userId?: string | null
  turnCount: number
  isEnded: boolean
  title?: string | null
  memorySnapshot?: AgentMemory
  metadata?: Record<string, unknown> | null
  createdAt: Date
  updatedAt: Date
  endedAt?: Date | null
}

// Transform type (snake_case DB → camelCase domain)
export interface ChatMessage {
  id: string
  role: 'user' | 'assistant'
  messageType: MessageType
  text: string
  metadata?: MessageEvent
  turnNumber: number
  messageIndex?: number // Optional - auto-generated by DB trigger, may be undefined for temp messages
  createdAt: Date
}

export interface SessionTurnResult<TOutput> {
  sessionId: string
  executionId: string
  turnNumber: number
  output: TOutput | null // Null for side-effect agents with no output schema
  duration: number
}

export interface CreateSessionParams {
  resourceId: string
  organizationId: string
  userId?: string
  metadata?: Record<string, unknown>
  /** Context window size from the agent's model config (tokens) */
  contextWindowSize?: number
}

export interface ListSessionsFilters {
  organizationId: string
  userId?: string
  resourceId?: string
  limit?: number
}

// API Request/Response Types

/**
 * Execute turn request body
 * Supports both object format (with message key) and plain string
 */
export interface ExecuteTurnRequest {
  input:
    | {
        message: string
      }
    | string
}

/** Token usage data sent with turn:complete WebSocket events */
export interface SessionTokenUsage {
  /** Tokens consumed by this turn's input */
  turnInputTokens: number
  /** Tokens generated by this turn's output */
  turnOutputTokens: number
  /** Total tokens for this turn (turnInputTokens + turnOutputTokens) */
  turnTotalTokens: number
  /** Cumulative input tokens across all turns in this session */
  cumulativeInputTokens: number
  /** Cumulative output tokens across all turns in this session */
  cumulativeOutputTokens: number
  /** The model's context window size for this session (e.g., 200K) */
  contextWindowSize: number
}
