// Code generated by sqlc. DO NOT EDIT.
// versions:
//   sqlc v1.30.0
// source: stats.sql

package db

import (
	"context"
	"database/sql"
)

const getAverageResponseTime = `-- name: GetAverageResponseTime :one
SELECT
    CAST(COALESCE(AVG(finished_at - created_at), 0) AS INTEGER) as avg_response_seconds
FROM messages
WHERE role = 'assistant'
  AND finished_at IS NOT NULL
  AND finished_at > created_at
`

func (q *Queries) GetAverageResponseTime(ctx context.Context) (int64, error) {
	row := q.queryRow(ctx, q.getAverageResponseTimeStmt, getAverageResponseTime)
	var avg_response_seconds int64
	err := row.Scan(&avg_response_seconds)
	return avg_response_seconds, err
}

const getHourDayHeatmap = `-- name: GetHourDayHeatmap :many
SELECT
    CAST(strftime('%w', created_at, 'unixepoch') AS INTEGER) as day_of_week,
    CAST(strftime('%H', created_at, 'unixepoch') AS INTEGER) as hour,
    COUNT(*) as session_count
FROM sessions
WHERE parent_session_id IS NULL
GROUP BY day_of_week, hour
ORDER BY day_of_week, hour
`

type GetHourDayHeatmapRow struct {
	DayOfWeek    int64 `json:"day_of_week"`
	Hour         int64 `json:"hour"`
	SessionCount int64 `json:"session_count"`
}

func (q *Queries) GetHourDayHeatmap(ctx context.Context) ([]GetHourDayHeatmapRow, error) {
	rows, err := q.query(ctx, q.getHourDayHeatmapStmt, getHourDayHeatmap)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []GetHourDayHeatmapRow{}
	for rows.Next() {
		var i GetHourDayHeatmapRow
		if err := rows.Scan(&i.DayOfWeek, &i.Hour, &i.SessionCount); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getRecentActivity = `-- name: GetRecentActivity :many
SELECT
    date(created_at, 'unixepoch') as day,
    COUNT(*) as session_count,
    SUM(prompt_tokens + completion_tokens) as total_tokens,
    SUM(cost) as cost
FROM sessions
WHERE parent_session_id IS NULL
  AND created_at >= strftime('%s', 'now', '-30 days')
GROUP BY date(created_at, 'unixepoch')
ORDER BY day ASC
`

type GetRecentActivityRow struct {
	Day          interface{}     `json:"day"`
	SessionCount int64           `json:"session_count"`
	TotalTokens  sql.NullFloat64 `json:"total_tokens"`
	Cost         sql.NullFloat64 `json:"cost"`
}

func (q *Queries) GetRecentActivity(ctx context.Context) ([]GetRecentActivityRow, error) {
	rows, err := q.query(ctx, q.getRecentActivityStmt, getRecentActivity)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []GetRecentActivityRow{}
	for rows.Next() {
		var i GetRecentActivityRow
		if err := rows.Scan(
			&i.Day,
			&i.SessionCount,
			&i.TotalTokens,
			&i.Cost,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getToolUsage = `-- name: GetToolUsage :many
SELECT
    json_extract(value, '$.data.name') as tool_name,
    COUNT(*) as call_count
FROM messages, json_each(parts)
WHERE json_extract(value, '$.type') = 'tool_call'
  AND json_extract(value, '$.data.name') IS NOT NULL
GROUP BY tool_name
ORDER BY call_count DESC
`

type GetToolUsageRow struct {
	ToolName  interface{} `json:"tool_name"`
	CallCount int64       `json:"call_count"`
}

func (q *Queries) GetToolUsage(ctx context.Context) ([]GetToolUsageRow, error) {
	rows, err := q.query(ctx, q.getToolUsageStmt, getToolUsage)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []GetToolUsageRow{}
	for rows.Next() {
		var i GetToolUsageRow
		if err := rows.Scan(&i.ToolName, &i.CallCount); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getTotalStats = `-- name: GetTotalStats :one
SELECT
    COUNT(*) as total_sessions,
    COALESCE(SUM(prompt_tokens), 0) as total_prompt_tokens,
    COALESCE(SUM(completion_tokens), 0) as total_completion_tokens,
    COALESCE(SUM(cost), 0) as total_cost,
    COALESCE(SUM(message_count), 0) as total_messages,
    COALESCE(AVG(prompt_tokens + completion_tokens), 0) as avg_tokens_per_session,
    COALESCE(AVG(message_count), 0) as avg_messages_per_session
FROM sessions
WHERE parent_session_id IS NULL
`

type GetTotalStatsRow struct {
	TotalSessions         int64       `json:"total_sessions"`
	TotalPromptTokens     interface{} `json:"total_prompt_tokens"`
	TotalCompletionTokens interface{} `json:"total_completion_tokens"`
	TotalCost             interface{} `json:"total_cost"`
	TotalMessages         interface{} `json:"total_messages"`
	AvgTokensPerSession   interface{} `json:"avg_tokens_per_session"`
	AvgMessagesPerSession interface{} `json:"avg_messages_per_session"`
}

func (q *Queries) GetTotalStats(ctx context.Context) (GetTotalStatsRow, error) {
	row := q.queryRow(ctx, q.getTotalStatsStmt, getTotalStats)
	var i GetTotalStatsRow
	err := row.Scan(
		&i.TotalSessions,
		&i.TotalPromptTokens,
		&i.TotalCompletionTokens,
		&i.TotalCost,
		&i.TotalMessages,
		&i.AvgTokensPerSession,
		&i.AvgMessagesPerSession,
	)
	return i, err
}

const getUsageByDay = `-- name: GetUsageByDay :many
SELECT
    date(created_at, 'unixepoch') as day,
    SUM(prompt_tokens) as prompt_tokens,
    SUM(completion_tokens) as completion_tokens,
    SUM(cost) as cost,
    COUNT(*) as session_count
FROM sessions
WHERE parent_session_id IS NULL
GROUP BY date(created_at, 'unixepoch')
ORDER BY day DESC
`

type GetUsageByDayRow struct {
	Day              interface{}     `json:"day"`
	PromptTokens     sql.NullFloat64 `json:"prompt_tokens"`
	CompletionTokens sql.NullFloat64 `json:"completion_tokens"`
	Cost             sql.NullFloat64 `json:"cost"`
	SessionCount     int64           `json:"session_count"`
}

func (q *Queries) GetUsageByDay(ctx context.Context) ([]GetUsageByDayRow, error) {
	rows, err := q.query(ctx, q.getUsageByDayStmt, getUsageByDay)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []GetUsageByDayRow{}
	for rows.Next() {
		var i GetUsageByDayRow
		if err := rows.Scan(
			&i.Day,
			&i.PromptTokens,
			&i.CompletionTokens,
			&i.Cost,
			&i.SessionCount,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getUsageByDayOfWeek = `-- name: GetUsageByDayOfWeek :many
SELECT
    CAST(strftime('%w', created_at, 'unixepoch') AS INTEGER) as day_of_week,
    COUNT(*) as session_count,
    SUM(prompt_tokens) as prompt_tokens,
    SUM(completion_tokens) as completion_tokens
FROM sessions
WHERE parent_session_id IS NULL
GROUP BY day_of_week
ORDER BY day_of_week
`

type GetUsageByDayOfWeekRow struct {
	DayOfWeek        int64           `json:"day_of_week"`
	SessionCount     int64           `json:"session_count"`
	PromptTokens     sql.NullFloat64 `json:"prompt_tokens"`
	CompletionTokens sql.NullFloat64 `json:"completion_tokens"`
}

func (q *Queries) GetUsageByDayOfWeek(ctx context.Context) ([]GetUsageByDayOfWeekRow, error) {
	rows, err := q.query(ctx, q.getUsageByDayOfWeekStmt, getUsageByDayOfWeek)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []GetUsageByDayOfWeekRow{}
	for rows.Next() {
		var i GetUsageByDayOfWeekRow
		if err := rows.Scan(
			&i.DayOfWeek,
			&i.SessionCount,
			&i.PromptTokens,
			&i.CompletionTokens,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getUsageByHour = `-- name: GetUsageByHour :many
SELECT
    CAST(strftime('%H', created_at, 'unixepoch') AS INTEGER) as hour,
    COUNT(*) as session_count
FROM sessions
WHERE parent_session_id IS NULL
GROUP BY hour
ORDER BY hour
`

type GetUsageByHourRow struct {
	Hour         int64 `json:"hour"`
	SessionCount int64 `json:"session_count"`
}

func (q *Queries) GetUsageByHour(ctx context.Context) ([]GetUsageByHourRow, error) {
	rows, err := q.query(ctx, q.getUsageByHourStmt, getUsageByHour)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []GetUsageByHourRow{}
	for rows.Next() {
		var i GetUsageByHourRow
		if err := rows.Scan(&i.Hour, &i.SessionCount); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getUsageByModel = `-- name: GetUsageByModel :many
SELECT
    COALESCE(model, 'unknown') as model,
    COALESCE(provider, 'unknown') as provider,
    COUNT(*) as message_count
FROM messages
WHERE role = 'assistant'
GROUP BY model, provider
ORDER BY message_count DESC
`

type GetUsageByModelRow struct {
	Model        string `json:"model"`
	Provider     string `json:"provider"`
	MessageCount int64  `json:"message_count"`
}

func (q *Queries) GetUsageByModel(ctx context.Context) ([]GetUsageByModelRow, error) {
	rows, err := q.query(ctx, q.getUsageByModelStmt, getUsageByModel)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []GetUsageByModelRow{}
	for rows.Next() {
		var i GetUsageByModelRow
		if err := rows.Scan(&i.Model, &i.Provider, &i.MessageCount); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}
