// Code generated by sqlc. DO NOT EDIT.
// versions:
//   sqlc v1.27.0
// source: flows.sql

package database

import (
	"context"
	"database/sql"
	"encoding/json"
	"time"
)

const createFlow = `-- name: CreateFlow :one
INSERT INTO flows (
  title, status, model, model_provider_name, model_provider_type, language, tool_call_id_template, functions, user_id
)
VALUES (
  $1, $2, $3, $4, $5, $6, $7, $8, $9
)
RETURNING id, status, title, model, model_provider_name, language, functions, user_id, created_at, updated_at, deleted_at, trace_id, model_provider_type, tool_call_id_template
`

type CreateFlowParams struct {
	Title              string          `json:"title"`
	Status             FlowStatus      `json:"status"`
	Model              string          `json:"model"`
	ModelProviderName  string          `json:"model_provider_name"`
	ModelProviderType  ProviderType    `json:"model_provider_type"`
	Language           string          `json:"language"`
	ToolCallIDTemplate string          `json:"tool_call_id_template"`
	Functions          json.RawMessage `json:"functions"`
	UserID             int64           `json:"user_id"`
}

func (q *Queries) CreateFlow(ctx context.Context, arg CreateFlowParams) (Flow, error) {
	row := q.db.QueryRowContext(ctx, createFlow,
		arg.Title,
		arg.Status,
		arg.Model,
		arg.ModelProviderName,
		arg.ModelProviderType,
		arg.Language,
		arg.ToolCallIDTemplate,
		arg.Functions,
		arg.UserID,
	)
	var i Flow
	err := row.Scan(
		&i.ID,
		&i.Status,
		&i.Title,
		&i.Model,
		&i.ModelProviderName,
		&i.Language,
		&i.Functions,
		&i.UserID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.DeletedAt,
		&i.TraceID,
		&i.ModelProviderType,
		&i.ToolCallIDTemplate,
	)
	return i, err
}

const deleteFlow = `-- name: DeleteFlow :one
UPDATE flows
SET deleted_at = CURRENT_TIMESTAMP
WHERE id = $1
RETURNING id, status, title, model, model_provider_name, language, functions, user_id, created_at, updated_at, deleted_at, trace_id, model_provider_type, tool_call_id_template
`

func (q *Queries) DeleteFlow(ctx context.Context, id int64) (Flow, error) {
	row := q.db.QueryRowContext(ctx, deleteFlow, id)
	var i Flow
	err := row.Scan(
		&i.ID,
		&i.Status,
		&i.Title,
		&i.Model,
		&i.ModelProviderName,
		&i.Language,
		&i.Functions,
		&i.UserID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.DeletedAt,
		&i.TraceID,
		&i.ModelProviderType,
		&i.ToolCallIDTemplate,
	)
	return i, err
}

const getFlow = `-- name: GetFlow :one
SELECT
  f.id, f.status, f.title, f.model, f.model_provider_name, f.language, f.functions, f.user_id, f.created_at, f.updated_at, f.deleted_at, f.trace_id, f.model_provider_type, f.tool_call_id_template
FROM flows f
WHERE f.id = $1 AND f.deleted_at IS NULL
`

func (q *Queries) GetFlow(ctx context.Context, id int64) (Flow, error) {
	row := q.db.QueryRowContext(ctx, getFlow, id)
	var i Flow
	err := row.Scan(
		&i.ID,
		&i.Status,
		&i.Title,
		&i.Model,
		&i.ModelProviderName,
		&i.Language,
		&i.Functions,
		&i.UserID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.DeletedAt,
		&i.TraceID,
		&i.ModelProviderType,
		&i.ToolCallIDTemplate,
	)
	return i, err
}

const getFlowStats = `-- name: GetFlowStats :one

SELECT
  COALESCE(COUNT(DISTINCT t.id), 0)::bigint AS total_tasks_count,
  COALESCE(COUNT(DISTINCT s.id), 0)::bigint AS total_subtasks_count,
  COALESCE(COUNT(DISTINCT a.id), 0)::bigint AS total_assistants_count
FROM flows f
LEFT JOIN tasks t ON f.id = t.flow_id
LEFT JOIN subtasks s ON t.id = s.task_id
LEFT JOIN assistants a ON f.id = a.flow_id AND a.deleted_at IS NULL
WHERE f.id = $1 AND f.deleted_at IS NULL
`

type GetFlowStatsRow struct {
	TotalTasksCount      int64 `json:"total_tasks_count"`
	TotalSubtasksCount   int64 `json:"total_subtasks_count"`
	TotalAssistantsCount int64 `json:"total_assistants_count"`
}

// ==================== Flows Analytics Queries ====================
// Get total count of tasks, subtasks, and assistants for a specific flow
func (q *Queries) GetFlowStats(ctx context.Context, id int64) (GetFlowStatsRow, error) {
	row := q.db.QueryRowContext(ctx, getFlowStats, id)
	var i GetFlowStatsRow
	err := row.Scan(&i.TotalTasksCount, &i.TotalSubtasksCount, &i.TotalAssistantsCount)
	return i, err
}

const getFlows = `-- name: GetFlows :many
SELECT
  f.id, f.status, f.title, f.model, f.model_provider_name, f.language, f.functions, f.user_id, f.created_at, f.updated_at, f.deleted_at, f.trace_id, f.model_provider_type, f.tool_call_id_template
FROM flows f
WHERE f.deleted_at IS NULL
ORDER BY f.created_at DESC
`

func (q *Queries) GetFlows(ctx context.Context) ([]Flow, error) {
	rows, err := q.db.QueryContext(ctx, getFlows)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []Flow
	for rows.Next() {
		var i Flow
		if err := rows.Scan(
			&i.ID,
			&i.Status,
			&i.Title,
			&i.Model,
			&i.ModelProviderName,
			&i.Language,
			&i.Functions,
			&i.UserID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.DeletedAt,
			&i.TraceID,
			&i.ModelProviderType,
			&i.ToolCallIDTemplate,
		); 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 getFlowsStatsByDayLast3Months = `-- name: GetFlowsStatsByDayLast3Months :many
SELECT
  DATE(f.created_at) AS date,
  COALESCE(COUNT(DISTINCT f.id), 0)::bigint AS total_flows_count,
  COALESCE(COUNT(DISTINCT t.id), 0)::bigint AS total_tasks_count,
  COALESCE(COUNT(DISTINCT s.id), 0)::bigint AS total_subtasks_count,
  COALESCE(COUNT(DISTINCT a.id), 0)::bigint AS total_assistants_count
FROM flows f
LEFT JOIN tasks t ON f.id = t.flow_id
LEFT JOIN subtasks s ON t.id = s.task_id
LEFT JOIN assistants a ON f.id = a.flow_id AND a.deleted_at IS NULL
WHERE f.created_at >= NOW() - INTERVAL '90 days' AND f.deleted_at IS NULL AND f.user_id = $1
GROUP BY DATE(f.created_at)
ORDER BY date DESC
`

type GetFlowsStatsByDayLast3MonthsRow struct {
	Date                 time.Time `json:"date"`
	TotalFlowsCount      int64     `json:"total_flows_count"`
	TotalTasksCount      int64     `json:"total_tasks_count"`
	TotalSubtasksCount   int64     `json:"total_subtasks_count"`
	TotalAssistantsCount int64     `json:"total_assistants_count"`
}

// Get flows stats by day for the last 3 months
func (q *Queries) GetFlowsStatsByDayLast3Months(ctx context.Context, userID int64) ([]GetFlowsStatsByDayLast3MonthsRow, error) {
	rows, err := q.db.QueryContext(ctx, getFlowsStatsByDayLast3Months, userID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []GetFlowsStatsByDayLast3MonthsRow
	for rows.Next() {
		var i GetFlowsStatsByDayLast3MonthsRow
		if err := rows.Scan(
			&i.Date,
			&i.TotalFlowsCount,
			&i.TotalTasksCount,
			&i.TotalSubtasksCount,
			&i.TotalAssistantsCount,
		); 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 getFlowsStatsByDayLastMonth = `-- name: GetFlowsStatsByDayLastMonth :many
SELECT
  DATE(f.created_at) AS date,
  COALESCE(COUNT(DISTINCT f.id), 0)::bigint AS total_flows_count,
  COALESCE(COUNT(DISTINCT t.id), 0)::bigint AS total_tasks_count,
  COALESCE(COUNT(DISTINCT s.id), 0)::bigint AS total_subtasks_count,
  COALESCE(COUNT(DISTINCT a.id), 0)::bigint AS total_assistants_count
FROM flows f
LEFT JOIN tasks t ON f.id = t.flow_id
LEFT JOIN subtasks s ON t.id = s.task_id
LEFT JOIN assistants a ON f.id = a.flow_id AND a.deleted_at IS NULL
WHERE f.created_at >= NOW() - INTERVAL '30 days' AND f.deleted_at IS NULL AND f.user_id = $1
GROUP BY DATE(f.created_at)
ORDER BY date DESC
`

type GetFlowsStatsByDayLastMonthRow struct {
	Date                 time.Time `json:"date"`
	TotalFlowsCount      int64     `json:"total_flows_count"`
	TotalTasksCount      int64     `json:"total_tasks_count"`
	TotalSubtasksCount   int64     `json:"total_subtasks_count"`
	TotalAssistantsCount int64     `json:"total_assistants_count"`
}

// Get flows stats by day for the last month
func (q *Queries) GetFlowsStatsByDayLastMonth(ctx context.Context, userID int64) ([]GetFlowsStatsByDayLastMonthRow, error) {
	rows, err := q.db.QueryContext(ctx, getFlowsStatsByDayLastMonth, userID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []GetFlowsStatsByDayLastMonthRow
	for rows.Next() {
		var i GetFlowsStatsByDayLastMonthRow
		if err := rows.Scan(
			&i.Date,
			&i.TotalFlowsCount,
			&i.TotalTasksCount,
			&i.TotalSubtasksCount,
			&i.TotalAssistantsCount,
		); 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 getFlowsStatsByDayLastWeek = `-- name: GetFlowsStatsByDayLastWeek :many
SELECT
  DATE(f.created_at) AS date,
  COALESCE(COUNT(DISTINCT f.id), 0)::bigint AS total_flows_count,
  COALESCE(COUNT(DISTINCT t.id), 0)::bigint AS total_tasks_count,
  COALESCE(COUNT(DISTINCT s.id), 0)::bigint AS total_subtasks_count,
  COALESCE(COUNT(DISTINCT a.id), 0)::bigint AS total_assistants_count
FROM flows f
LEFT JOIN tasks t ON f.id = t.flow_id
LEFT JOIN subtasks s ON t.id = s.task_id
LEFT JOIN assistants a ON f.id = a.flow_id AND a.deleted_at IS NULL
WHERE f.created_at >= NOW() - INTERVAL '7 days' AND f.deleted_at IS NULL AND f.user_id = $1
GROUP BY DATE(f.created_at)
ORDER BY date DESC
`

type GetFlowsStatsByDayLastWeekRow struct {
	Date                 time.Time `json:"date"`
	TotalFlowsCount      int64     `json:"total_flows_count"`
	TotalTasksCount      int64     `json:"total_tasks_count"`
	TotalSubtasksCount   int64     `json:"total_subtasks_count"`
	TotalAssistantsCount int64     `json:"total_assistants_count"`
}

// Get flows stats by day for the last week
func (q *Queries) GetFlowsStatsByDayLastWeek(ctx context.Context, userID int64) ([]GetFlowsStatsByDayLastWeekRow, error) {
	rows, err := q.db.QueryContext(ctx, getFlowsStatsByDayLastWeek, userID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []GetFlowsStatsByDayLastWeekRow
	for rows.Next() {
		var i GetFlowsStatsByDayLastWeekRow
		if err := rows.Scan(
			&i.Date,
			&i.TotalFlowsCount,
			&i.TotalTasksCount,
			&i.TotalSubtasksCount,
			&i.TotalAssistantsCount,
		); 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 getUserFlow = `-- name: GetUserFlow :one
SELECT
  f.id, f.status, f.title, f.model, f.model_provider_name, f.language, f.functions, f.user_id, f.created_at, f.updated_at, f.deleted_at, f.trace_id, f.model_provider_type, f.tool_call_id_template
FROM flows f
INNER JOIN users u ON f.user_id = u.id
WHERE f.id = $1 AND f.user_id = $2 AND f.deleted_at IS NULL
`

type GetUserFlowParams struct {
	ID     int64 `json:"id"`
	UserID int64 `json:"user_id"`
}

func (q *Queries) GetUserFlow(ctx context.Context, arg GetUserFlowParams) (Flow, error) {
	row := q.db.QueryRowContext(ctx, getUserFlow, arg.ID, arg.UserID)
	var i Flow
	err := row.Scan(
		&i.ID,
		&i.Status,
		&i.Title,
		&i.Model,
		&i.ModelProviderName,
		&i.Language,
		&i.Functions,
		&i.UserID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.DeletedAt,
		&i.TraceID,
		&i.ModelProviderType,
		&i.ToolCallIDTemplate,
	)
	return i, err
}

const getUserFlows = `-- name: GetUserFlows :many
SELECT
  f.id, f.status, f.title, f.model, f.model_provider_name, f.language, f.functions, f.user_id, f.created_at, f.updated_at, f.deleted_at, f.trace_id, f.model_provider_type, f.tool_call_id_template
FROM flows f
INNER JOIN users u ON f.user_id = u.id
WHERE f.user_id = $1 AND f.deleted_at IS NULL
ORDER BY f.created_at DESC
`

func (q *Queries) GetUserFlows(ctx context.Context, userID int64) ([]Flow, error) {
	rows, err := q.db.QueryContext(ctx, getUserFlows, userID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []Flow
	for rows.Next() {
		var i Flow
		if err := rows.Scan(
			&i.ID,
			&i.Status,
			&i.Title,
			&i.Model,
			&i.ModelProviderName,
			&i.Language,
			&i.Functions,
			&i.UserID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.DeletedAt,
			&i.TraceID,
			&i.ModelProviderType,
			&i.ToolCallIDTemplate,
		); 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 getUserTotalFlowsStats = `-- name: GetUserTotalFlowsStats :one
SELECT
  COALESCE(COUNT(DISTINCT f.id), 0)::bigint AS total_flows_count,
  COALESCE(COUNT(DISTINCT t.id), 0)::bigint AS total_tasks_count,
  COALESCE(COUNT(DISTINCT s.id), 0)::bigint AS total_subtasks_count,
  COALESCE(COUNT(DISTINCT a.id), 0)::bigint AS total_assistants_count
FROM flows f
LEFT JOIN tasks t ON f.id = t.flow_id
LEFT JOIN subtasks s ON t.id = s.task_id
LEFT JOIN assistants a ON f.id = a.flow_id AND a.deleted_at IS NULL
WHERE f.user_id = $1 AND f.deleted_at IS NULL
`

type GetUserTotalFlowsStatsRow struct {
	TotalFlowsCount      int64 `json:"total_flows_count"`
	TotalTasksCount      int64 `json:"total_tasks_count"`
	TotalSubtasksCount   int64 `json:"total_subtasks_count"`
	TotalAssistantsCount int64 `json:"total_assistants_count"`
}

// Get total count of flows, tasks, subtasks, and assistants for a user
func (q *Queries) GetUserTotalFlowsStats(ctx context.Context, userID int64) (GetUserTotalFlowsStatsRow, error) {
	row := q.db.QueryRowContext(ctx, getUserTotalFlowsStats, userID)
	var i GetUserTotalFlowsStatsRow
	err := row.Scan(
		&i.TotalFlowsCount,
		&i.TotalTasksCount,
		&i.TotalSubtasksCount,
		&i.TotalAssistantsCount,
	)
	return i, err
}

const updateFlow = `-- name: UpdateFlow :one
UPDATE flows
SET title = $1, model = $2, language = $3, tool_call_id_template = $4, functions = $5, trace_id = $6
WHERE id = $7
RETURNING id, status, title, model, model_provider_name, language, functions, user_id, created_at, updated_at, deleted_at, trace_id, model_provider_type, tool_call_id_template
`

type UpdateFlowParams struct {
	Title              string          `json:"title"`
	Model              string          `json:"model"`
	Language           string          `json:"language"`
	ToolCallIDTemplate string          `json:"tool_call_id_template"`
	Functions          json.RawMessage `json:"functions"`
	TraceID            sql.NullString  `json:"trace_id"`
	ID                 int64           `json:"id"`
}

func (q *Queries) UpdateFlow(ctx context.Context, arg UpdateFlowParams) (Flow, error) {
	row := q.db.QueryRowContext(ctx, updateFlow,
		arg.Title,
		arg.Model,
		arg.Language,
		arg.ToolCallIDTemplate,
		arg.Functions,
		arg.TraceID,
		arg.ID,
	)
	var i Flow
	err := row.Scan(
		&i.ID,
		&i.Status,
		&i.Title,
		&i.Model,
		&i.ModelProviderName,
		&i.Language,
		&i.Functions,
		&i.UserID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.DeletedAt,
		&i.TraceID,
		&i.ModelProviderType,
		&i.ToolCallIDTemplate,
	)
	return i, err
}

const updateFlowLanguage = `-- name: UpdateFlowLanguage :one
UPDATE flows
SET language = $1
WHERE id = $2
RETURNING id, status, title, model, model_provider_name, language, functions, user_id, created_at, updated_at, deleted_at, trace_id, model_provider_type, tool_call_id_template
`

type UpdateFlowLanguageParams struct {
	Language string `json:"language"`
	ID       int64  `json:"id"`
}

func (q *Queries) UpdateFlowLanguage(ctx context.Context, arg UpdateFlowLanguageParams) (Flow, error) {
	row := q.db.QueryRowContext(ctx, updateFlowLanguage, arg.Language, arg.ID)
	var i Flow
	err := row.Scan(
		&i.ID,
		&i.Status,
		&i.Title,
		&i.Model,
		&i.ModelProviderName,
		&i.Language,
		&i.Functions,
		&i.UserID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.DeletedAt,
		&i.TraceID,
		&i.ModelProviderType,
		&i.ToolCallIDTemplate,
	)
	return i, err
}

const updateFlowProvider = `-- name: UpdateFlowProvider :one
UPDATE flows
SET model_provider_name = $1, model_provider_type = $2, tool_call_id_template = $3, model = $4
WHERE id = $5
RETURNING id, status, title, model, model_provider_name, language, functions, user_id, created_at, updated_at, deleted_at, trace_id, model_provider_type, tool_call_id_template
`

type UpdateFlowProviderParams struct {
	ModelProviderName  string       `json:"model_provider_name"`
	ModelProviderType  ProviderType `json:"model_provider_type"`
	ToolCallIDTemplate string       `json:"tool_call_id_template"`
	Model              string       `json:"model"`
	ID                 int64        `json:"id"`
}

func (q *Queries) UpdateFlowProvider(ctx context.Context, arg UpdateFlowProviderParams) (Flow, error) {
	row := q.db.QueryRowContext(ctx, updateFlowProvider,
		arg.ModelProviderName,
		arg.ModelProviderType,
		arg.ToolCallIDTemplate,
		arg.Model,
		arg.ID,
	)
	var i Flow
	err := row.Scan(
		&i.ID,
		&i.Status,
		&i.Title,
		&i.Model,
		&i.ModelProviderName,
		&i.Language,
		&i.Functions,
		&i.UserID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.DeletedAt,
		&i.TraceID,
		&i.ModelProviderType,
		&i.ToolCallIDTemplate,
	)
	return i, err
}

const updateFlowStatus = `-- name: UpdateFlowStatus :one
UPDATE flows
SET status = $1
WHERE id = $2
RETURNING id, status, title, model, model_provider_name, language, functions, user_id, created_at, updated_at, deleted_at, trace_id, model_provider_type, tool_call_id_template
`

type UpdateFlowStatusParams struct {
	Status FlowStatus `json:"status"`
	ID     int64      `json:"id"`
}

func (q *Queries) UpdateFlowStatus(ctx context.Context, arg UpdateFlowStatusParams) (Flow, error) {
	row := q.db.QueryRowContext(ctx, updateFlowStatus, arg.Status, arg.ID)
	var i Flow
	err := row.Scan(
		&i.ID,
		&i.Status,
		&i.Title,
		&i.Model,
		&i.ModelProviderName,
		&i.Language,
		&i.Functions,
		&i.UserID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.DeletedAt,
		&i.TraceID,
		&i.ModelProviderType,
		&i.ToolCallIDTemplate,
	)
	return i, err
}

const updateFlowTitle = `-- name: UpdateFlowTitle :one
UPDATE flows
SET title = $1
WHERE id = $2
RETURNING id, status, title, model, model_provider_name, language, functions, user_id, created_at, updated_at, deleted_at, trace_id, model_provider_type, tool_call_id_template
`

type UpdateFlowTitleParams struct {
	Title string `json:"title"`
	ID    int64  `json:"id"`
}

func (q *Queries) UpdateFlowTitle(ctx context.Context, arg UpdateFlowTitleParams) (Flow, error) {
	row := q.db.QueryRowContext(ctx, updateFlowTitle, arg.Title, arg.ID)
	var i Flow
	err := row.Scan(
		&i.ID,
		&i.Status,
		&i.Title,
		&i.Model,
		&i.ModelProviderName,
		&i.Language,
		&i.Functions,
		&i.UserID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.DeletedAt,
		&i.TraceID,
		&i.ModelProviderType,
		&i.ToolCallIDTemplate,
	)
	return i, err
}

const updateFlowToolCallIDTemplate = `-- name: UpdateFlowToolCallIDTemplate :one
UPDATE flows
SET tool_call_id_template = $1
WHERE id = $2
RETURNING id, status, title, model, model_provider_name, language, functions, user_id, created_at, updated_at, deleted_at, trace_id, model_provider_type, tool_call_id_template
`

type UpdateFlowToolCallIDTemplateParams struct {
	ToolCallIDTemplate string `json:"tool_call_id_template"`
	ID                 int64  `json:"id"`
}

func (q *Queries) UpdateFlowToolCallIDTemplate(ctx context.Context, arg UpdateFlowToolCallIDTemplateParams) (Flow, error) {
	row := q.db.QueryRowContext(ctx, updateFlowToolCallIDTemplate, arg.ToolCallIDTemplate, arg.ID)
	var i Flow
	err := row.Scan(
		&i.ID,
		&i.Status,
		&i.Title,
		&i.Model,
		&i.ModelProviderName,
		&i.Language,
		&i.Functions,
		&i.UserID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.DeletedAt,
		&i.TraceID,
		&i.ModelProviderType,
		&i.ToolCallIDTemplate,
	)
	return i, err
}
