// Code generated by sqlc. DO NOT EDIT.
// versions:
//   sqlc v1.31.1
// source: dashboard.sql

package acpsqlc

import (
	"context"

	"github.com/jackc/pgx/v5/pgtype"
)

const sessionRollup = `-- name: SessionRollup :one
SELECT
  COUNT(*)::bigint                                                            AS total,
  COUNT(*) FILTER (WHERE status = 'exited')::bigint                           AS succeeded,
  COUNT(*) FILTER (WHERE status = 'crashed')::bigint                          AS crashed,
  COUNT(*) FILTER (WHERE status IN ('starting','running'))::bigint            AS active,
  COALESCE(SUM(cost_usd), 0)::numeric                                         AS total_cost_usd,
  COALESCE(SUM(tokens_total), 0)::bigint                                      AS total_tokens,
  COALESCE(
    AVG(EXTRACT(EPOCH FROM (ended_at - started_at)))
      FILTER (WHERE ended_at IS NOT NULL),
    0)::float8                                                                AS avg_duration_seconds
FROM acp_sessions
WHERE ($1::uuid IS NULL OR user_id = $1)
  AND ($2::uuid IS NULL OR project_id = $2)
  AND ($3::uuid IS NULL OR requirement_id = $3)
  AND started_at >= $4
  AND started_at < $5
`

type SessionRollupParams struct {
	Column1     pgtype.UUID        `json:"column_1"`
	Column2     pgtype.UUID        `json:"column_2"`
	Column3     pgtype.UUID        `json:"column_3"`
	StartedAt   pgtype.Timestamptz `json:"started_at"`
	StartedAt_2 pgtype.Timestamptz `json:"started_at_2"`
}

type SessionRollupRow struct {
	Total              int64          `json:"total"`
	Succeeded          int64          `json:"succeeded"`
	Crashed            int64          `json:"crashed"`
	Active             int64          `json:"active"`
	TotalCostUsd       pgtype.Numeric `json:"total_cost_usd"`
	TotalTokens        int64          `json:"total_tokens"`
	AvgDurationSeconds float64        `json:"avg_duration_seconds"`
}

// owner/admin scope + 可选 project/requirement + 时间窗内的会话汇总。
// success = status='exited'；avg_duration_seconds 仅统计已结束（ended_at 非空）会话。
func (q *Queries) SessionRollup(ctx context.Context, arg SessionRollupParams) (SessionRollupRow, error) {
	row := q.db.QueryRow(ctx, sessionRollup,
		arg.Column1,
		arg.Column2,
		arg.Column3,
		arg.StartedAt,
		arg.StartedAt_2,
	)
	var i SessionRollupRow
	err := row.Scan(
		&i.Total,
		&i.Succeeded,
		&i.Crashed,
		&i.Active,
		&i.TotalCostUsd,
		&i.TotalTokens,
		&i.AvgDurationSeconds,
	)
	return i, err
}

const sessionTimeline = `-- name: SessionTimeline :many

SELECT direction,
       rpc_kind,
       COALESCE(method, '')                AS method,
       COUNT(*)::bigint                    AS event_count,
       MIN(created_at)::timestamptz        AS first_at,
       MAX(created_at)::timestamptz        AS last_at
FROM acp_events
WHERE session_id = $1
GROUP BY direction, rpc_kind, COALESCE(method, '')
ORDER BY first_at ASC
`

type SessionTimelineRow struct {
	Direction  string             `json:"direction"`
	RpcKind    string             `json:"rpc_kind"`
	Method     string             `json:"method"`
	EventCount int64              `json:"event_count"`
	FirstAt    pgtype.Timestamptz `json:"first_at"`
	LastAt     pgtype.Timestamptz `json:"last_at"`
}

// dashboard.sql: run-history dashboard 读模型（只读聚合）。
//   - SessionTimeline: 单会话的 RPC 事件按 (direction, rpc_kind, method) 分桶，
//     给出条数 + 首/末时间戳，用于会话时间线概览。
//   - SessionRollup: 在 owner/admin scope + 可选 project/requirement 过滤下，
//     统计会话总数、成功率（exited 视为成功）、总成本、平均时长。
//   - SessionsByDay: 按天的 总数 / 成功 / 失败 / 成本 时间序列。
//
// scope 约定（与 ListSessionsByUser/ListAllSessions 一致）：
//
//	$1 user_id 为 NULL 时不按用户过滤（admin 全量），非 NULL 时仅该用户。
//
// 单会话事件时间线：按 method/kind 分桶聚合（条数 + 首末时间）。
func (q *Queries) SessionTimeline(ctx context.Context, sessionID pgtype.UUID) ([]SessionTimelineRow, error) {
	rows, err := q.db.Query(ctx, sessionTimeline, sessionID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []SessionTimelineRow
	for rows.Next() {
		var i SessionTimelineRow
		if err := rows.Scan(
			&i.Direction,
			&i.RpcKind,
			&i.Method,
			&i.EventCount,
			&i.FirstAt,
			&i.LastAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const sessionsByDay = `-- name: SessionsByDay :many
SELECT
  date_trunc('day', started_at)::timestamptz                        AS day,
  COUNT(*)::bigint                                                  AS total,
  COUNT(*) FILTER (WHERE status = 'exited')::bigint                 AS succeeded,
  COUNT(*) FILTER (WHERE status = 'crashed')::bigint                AS crashed,
  COALESCE(SUM(cost_usd), 0)::numeric                               AS total_cost_usd
FROM acp_sessions
WHERE ($1::uuid IS NULL OR user_id = $1)
  AND ($2::uuid IS NULL OR project_id = $2)
  AND ($3::uuid IS NULL OR requirement_id = $3)
  AND started_at >= $4
  AND started_at < $5
GROUP BY day
ORDER BY day ASC
`

type SessionsByDayParams struct {
	Column1     pgtype.UUID        `json:"column_1"`
	Column2     pgtype.UUID        `json:"column_2"`
	Column3     pgtype.UUID        `json:"column_3"`
	StartedAt   pgtype.Timestamptz `json:"started_at"`
	StartedAt_2 pgtype.Timestamptz `json:"started_at_2"`
}

type SessionsByDayRow struct {
	Day          pgtype.Timestamptz `json:"day"`
	Total        int64              `json:"total"`
	Succeeded    int64              `json:"succeeded"`
	Crashed      int64              `json:"crashed"`
	TotalCostUsd pgtype.Numeric     `json:"total_cost_usd"`
}

// 按天的会话时间序列（总数 / 成功 / 失败 / 成本），同 SessionRollup 的 scope。
func (q *Queries) SessionsByDay(ctx context.Context, arg SessionsByDayParams) ([]SessionsByDayRow, error) {
	rows, err := q.db.Query(ctx, sessionsByDay,
		arg.Column1,
		arg.Column2,
		arg.Column3,
		arg.StartedAt,
		arg.StartedAt_2,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []SessionsByDayRow
	for rows.Next() {
		var i SessionsByDayRow
		if err := rows.Scan(
			&i.Day,
			&i.Total,
			&i.Succeeded,
			&i.Crashed,
			&i.TotalCostUsd,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}
