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

package db

import (
	"context"

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

const addSquadMember = `-- name: AddSquadMember :one
INSERT INTO squad_member (squad_id, member_type, member_id, role)
VALUES ($1, $2, $3, $4)
RETURNING id, squad_id, member_type, member_id, role, created_at
`

type AddSquadMemberParams struct {
	SquadID    pgtype.UUID `json:"squad_id"`
	MemberType string      `json:"member_type"`
	MemberID   pgtype.UUID `json:"member_id"`
	Role       string      `json:"role"`
}

func (q *Queries) AddSquadMember(ctx context.Context, arg AddSquadMemberParams) (SquadMember, error) {
	row := q.db.QueryRow(ctx, addSquadMember,
		arg.SquadID,
		arg.MemberType,
		arg.MemberID,
		arg.Role,
	)
	var i SquadMember
	err := row.Scan(
		&i.ID,
		&i.SquadID,
		&i.MemberType,
		&i.MemberID,
		&i.Role,
		&i.CreatedAt,
	)
	return i, err
}

const archiveSquad = `-- name: ArchiveSquad :one
UPDATE squad SET archived_at = now(), archived_by = $2, updated_at = now()
WHERE id = $1
RETURNING id, workspace_id, name, description, leader_id, creator_id, created_at, updated_at, archived_at, archived_by, avatar_url, instructions
`

type ArchiveSquadParams struct {
	ID         pgtype.UUID `json:"id"`
	ArchivedBy pgtype.UUID `json:"archived_by"`
}

func (q *Queries) ArchiveSquad(ctx context.Context, arg ArchiveSquadParams) (Squad, error) {
	row := q.db.QueryRow(ctx, archiveSquad, arg.ID, arg.ArchivedBy)
	var i Squad
	err := row.Scan(
		&i.ID,
		&i.WorkspaceID,
		&i.Name,
		&i.Description,
		&i.LeaderID,
		&i.CreatorID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.ArchivedAt,
		&i.ArchivedBy,
		&i.AvatarUrl,
		&i.Instructions,
	)
	return i, err
}

const countSquadMembers = `-- name: CountSquadMembers :one
SELECT count(*) FROM squad_member WHERE squad_id = $1
`

func (q *Queries) CountSquadMembers(ctx context.Context, squadID pgtype.UUID) (int64, error) {
	row := q.db.QueryRow(ctx, countSquadMembers, squadID)
	var count int64
	err := row.Scan(&count)
	return count, err
}

const createSquad = `-- name: CreateSquad :one
INSERT INTO squad (workspace_id, name, description, leader_id, creator_id, avatar_url)
VALUES ($1, $2, $3, $4, $5, $6)
RETURNING id, workspace_id, name, description, leader_id, creator_id, created_at, updated_at, archived_at, archived_by, avatar_url, instructions
`

type CreateSquadParams struct {
	WorkspaceID pgtype.UUID `json:"workspace_id"`
	Name        string      `json:"name"`
	Description string      `json:"description"`
	LeaderID    pgtype.UUID `json:"leader_id"`
	CreatorID   pgtype.UUID `json:"creator_id"`
	AvatarUrl   pgtype.Text `json:"avatar_url"`
}

func (q *Queries) CreateSquad(ctx context.Context, arg CreateSquadParams) (Squad, error) {
	row := q.db.QueryRow(ctx, createSquad,
		arg.WorkspaceID,
		arg.Name,
		arg.Description,
		arg.LeaderID,
		arg.CreatorID,
		arg.AvatarUrl,
	)
	var i Squad
	err := row.Scan(
		&i.ID,
		&i.WorkspaceID,
		&i.Name,
		&i.Description,
		&i.LeaderID,
		&i.CreatorID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.ArchivedAt,
		&i.ArchivedBy,
		&i.AvatarUrl,
		&i.Instructions,
	)
	return i, err
}

const getSquad = `-- name: GetSquad :one
SELECT id, workspace_id, name, description, leader_id, creator_id, created_at, updated_at, archived_at, archived_by, avatar_url, instructions FROM squad WHERE id = $1
`

func (q *Queries) GetSquad(ctx context.Context, id pgtype.UUID) (Squad, error) {
	row := q.db.QueryRow(ctx, getSquad, id)
	var i Squad
	err := row.Scan(
		&i.ID,
		&i.WorkspaceID,
		&i.Name,
		&i.Description,
		&i.LeaderID,
		&i.CreatorID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.ArchivedAt,
		&i.ArchivedBy,
		&i.AvatarUrl,
		&i.Instructions,
	)
	return i, err
}

const getSquadByAssignee = `-- name: GetSquadByAssignee :one
SELECT s.id, s.workspace_id, s.name, s.description, s.leader_id, s.creator_id, s.created_at, s.updated_at, s.archived_at, s.archived_by, s.avatar_url, s.instructions FROM squad s WHERE s.id = $1 AND s.workspace_id = $2
`

type GetSquadByAssigneeParams struct {
	ID          pgtype.UUID `json:"id"`
	WorkspaceID pgtype.UUID `json:"workspace_id"`
}

// Look up the squad when an issue is assigned to a squad.
func (q *Queries) GetSquadByAssignee(ctx context.Context, arg GetSquadByAssigneeParams) (Squad, error) {
	row := q.db.QueryRow(ctx, getSquadByAssignee, arg.ID, arg.WorkspaceID)
	var i Squad
	err := row.Scan(
		&i.ID,
		&i.WorkspaceID,
		&i.Name,
		&i.Description,
		&i.LeaderID,
		&i.CreatorID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.ArchivedAt,
		&i.ArchivedBy,
		&i.AvatarUrl,
		&i.Instructions,
	)
	return i, err
}

const getSquadInWorkspace = `-- name: GetSquadInWorkspace :one
SELECT id, workspace_id, name, description, leader_id, creator_id, created_at, updated_at, archived_at, archived_by, avatar_url, instructions FROM squad WHERE id = $1 AND workspace_id = $2
`

type GetSquadInWorkspaceParams struct {
	ID          pgtype.UUID `json:"id"`
	WorkspaceID pgtype.UUID `json:"workspace_id"`
}

func (q *Queries) GetSquadInWorkspace(ctx context.Context, arg GetSquadInWorkspaceParams) (Squad, error) {
	row := q.db.QueryRow(ctx, getSquadInWorkspace, arg.ID, arg.WorkspaceID)
	var i Squad
	err := row.Scan(
		&i.ID,
		&i.WorkspaceID,
		&i.Name,
		&i.Description,
		&i.LeaderID,
		&i.CreatorID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.ArchivedAt,
		&i.ArchivedBy,
		&i.AvatarUrl,
		&i.Instructions,
	)
	return i, err
}

const isSquadMember = `-- name: IsSquadMember :one
SELECT EXISTS(
    SELECT 1 FROM squad_member
    WHERE squad_id = $1 AND member_type = $2 AND member_id = $3
) AS is_member
`

type IsSquadMemberParams struct {
	SquadID    pgtype.UUID `json:"squad_id"`
	MemberType string      `json:"member_type"`
	MemberID   pgtype.UUID `json:"member_id"`
}

func (q *Queries) IsSquadMember(ctx context.Context, arg IsSquadMemberParams) (bool, error) {
	row := q.db.QueryRow(ctx, isSquadMember, arg.SquadID, arg.MemberType, arg.MemberID)
	var is_member bool
	err := row.Scan(&is_member)
	return is_member, err
}

const listAllSquads = `-- name: ListAllSquads :many
SELECT id, workspace_id, name, description, leader_id, creator_id, created_at, updated_at, archived_at, archived_by, avatar_url, instructions FROM squad WHERE workspace_id = $1 ORDER BY created_at ASC
`

func (q *Queries) ListAllSquads(ctx context.Context, workspaceID pgtype.UUID) ([]Squad, error) {
	rows, err := q.db.Query(ctx, listAllSquads, workspaceID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []Squad{}
	for rows.Next() {
		var i Squad
		if err := rows.Scan(
			&i.ID,
			&i.WorkspaceID,
			&i.Name,
			&i.Description,
			&i.LeaderID,
			&i.CreatorID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.ArchivedAt,
			&i.ArchivedBy,
			&i.AvatarUrl,
			&i.Instructions,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listSquadMemberPreviewRows = `-- name: ListSquadMemberPreviewRows :many
SELECT
    sm.squad_id,
    sm.member_type,
    sm.member_id,
    sm.role
FROM squad_member sm
JOIN squad s ON s.id = sm.squad_id
WHERE s.workspace_id = $1 AND s.archived_at IS NULL
ORDER BY
    sm.squad_id ASC,
    (sm.member_type = 'agent' AND sm.member_id = s.leader_id) DESC,
    sm.created_at ASC
`

type ListSquadMemberPreviewRowsRow struct {
	SquadID    pgtype.UUID `json:"squad_id"`
	MemberType string      `json:"member_type"`
	MemberID   pgtype.UUID `json:"member_id"`
	Role       string      `json:"role"`
}

// Static squad membership summary for list/hover previews. This deliberately
// excludes derived runtime/task status; the squad detail members-status
// endpoint owns live state.
func (q *Queries) ListSquadMemberPreviewRows(ctx context.Context, workspaceID pgtype.UUID) ([]ListSquadMemberPreviewRowsRow, error) {
	rows, err := q.db.Query(ctx, listSquadMemberPreviewRows, workspaceID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []ListSquadMemberPreviewRowsRow{}
	for rows.Next() {
		var i ListSquadMemberPreviewRowsRow
		if err := rows.Scan(
			&i.SquadID,
			&i.MemberType,
			&i.MemberID,
			&i.Role,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listSquadMemberPreviewRowsBySquad = `-- name: ListSquadMemberPreviewRowsBySquad :many
SELECT
    sm.squad_id,
    sm.member_type,
    sm.member_id,
    sm.role
FROM squad_member sm
JOIN squad s ON s.id = sm.squad_id
WHERE sm.squad_id = $1
ORDER BY
    (sm.member_type = 'agent' AND sm.member_id = s.leader_id) DESC,
    sm.created_at ASC
`

type ListSquadMemberPreviewRowsBySquadRow struct {
	SquadID    pgtype.UUID `json:"squad_id"`
	MemberType string      `json:"member_type"`
	MemberID   pgtype.UUID `json:"member_id"`
	Role       string      `json:"role"`
}

func (q *Queries) ListSquadMemberPreviewRowsBySquad(ctx context.Context, squadID pgtype.UUID) ([]ListSquadMemberPreviewRowsBySquadRow, error) {
	rows, err := q.db.Query(ctx, listSquadMemberPreviewRowsBySquad, squadID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []ListSquadMemberPreviewRowsBySquadRow{}
	for rows.Next() {
		var i ListSquadMemberPreviewRowsBySquadRow
		if err := rows.Scan(
			&i.SquadID,
			&i.MemberType,
			&i.MemberID,
			&i.Role,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listSquadMemberStatusRows = `-- name: ListSquadMemberStatusRows :many
SELECT
    sm.id              AS squad_member_id,
    sm.member_type     AS member_type,
    sm.member_id       AS member_id,
    a.archived_at      AS agent_archived_at,
    ar.status          AS runtime_status,
    ar.last_seen_at    AS runtime_last_seen_at,
    atq.id             AS task_id,
    atq.status         AS task_status,
    atq.issue_id       AS task_issue_id,
    atq.dispatched_at  AS task_dispatched_at,
    i.number           AS issue_number,
    i.title            AS issue_title,
    i.status           AS issue_status
FROM squad_member sm
LEFT JOIN agent a
       ON sm.member_type = 'agent' AND a.id = sm.member_id
LEFT JOIN agent_runtime ar
       ON ar.id = a.runtime_id
LEFT JOIN agent_task_queue atq
       ON sm.member_type = 'agent'
      AND atq.agent_id = sm.member_id
      AND atq.status IN ('dispatched', 'running', 'waiting_local_directory')
LEFT JOIN issue i
       ON i.id = atq.issue_id
WHERE sm.squad_id = $1
ORDER BY sm.created_at ASC, atq.dispatched_at DESC NULLS LAST
`

type ListSquadMemberStatusRowsRow struct {
	SquadMemberID     pgtype.UUID        `json:"squad_member_id"`
	MemberType        string             `json:"member_type"`
	MemberID          pgtype.UUID        `json:"member_id"`
	AgentArchivedAt   pgtype.Timestamptz `json:"agent_archived_at"`
	RuntimeStatus     pgtype.Text        `json:"runtime_status"`
	RuntimeLastSeenAt pgtype.Timestamptz `json:"runtime_last_seen_at"`
	TaskID            pgtype.UUID        `json:"task_id"`
	TaskStatus        pgtype.Text        `json:"task_status"`
	TaskIssueID       pgtype.UUID        `json:"task_issue_id"`
	TaskDispatchedAt  pgtype.Timestamptz `json:"task_dispatched_at"`
	IssueNumber       pgtype.Int4        `json:"issue_number"`
	IssueTitle        pgtype.Text        `json:"issue_title"`
	IssueStatus       pgtype.Text        `json:"issue_status"`
}

// Per-row join used to build the squad-members status view. One row per
// (squad_member × active_task); members with no active task return a
// single row with NULL task_* columns. Human members and agent members
// with no agent row also return one row with NULL agent_/runtime_ columns.
// The handler aggregates rows by member_id.
func (q *Queries) ListSquadMemberStatusRows(ctx context.Context, squadID pgtype.UUID) ([]ListSquadMemberStatusRowsRow, error) {
	rows, err := q.db.Query(ctx, listSquadMemberStatusRows, squadID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []ListSquadMemberStatusRowsRow{}
	for rows.Next() {
		var i ListSquadMemberStatusRowsRow
		if err := rows.Scan(
			&i.SquadMemberID,
			&i.MemberType,
			&i.MemberID,
			&i.AgentArchivedAt,
			&i.RuntimeStatus,
			&i.RuntimeLastSeenAt,
			&i.TaskID,
			&i.TaskStatus,
			&i.TaskIssueID,
			&i.TaskDispatchedAt,
			&i.IssueNumber,
			&i.IssueTitle,
			&i.IssueStatus,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listSquadMembers = `-- name: ListSquadMembers :many
SELECT id, squad_id, member_type, member_id, role, created_at FROM squad_member WHERE squad_id = $1 ORDER BY created_at ASC
`

func (q *Queries) ListSquadMembers(ctx context.Context, squadID pgtype.UUID) ([]SquadMember, error) {
	rows, err := q.db.Query(ctx, listSquadMembers, squadID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []SquadMember{}
	for rows.Next() {
		var i SquadMember
		if err := rows.Scan(
			&i.ID,
			&i.SquadID,
			&i.MemberType,
			&i.MemberID,
			&i.Role,
			&i.CreatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listSquads = `-- name: ListSquads :many
SELECT id, workspace_id, name, description, leader_id, creator_id, created_at, updated_at, archived_at, archived_by, avatar_url, instructions FROM squad WHERE workspace_id = $1 AND archived_at IS NULL ORDER BY created_at ASC
`

func (q *Queries) ListSquads(ctx context.Context, workspaceID pgtype.UUID) ([]Squad, error) {
	rows, err := q.db.Query(ctx, listSquads, workspaceID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []Squad{}
	for rows.Next() {
		var i Squad
		if err := rows.Scan(
			&i.ID,
			&i.WorkspaceID,
			&i.Name,
			&i.Description,
			&i.LeaderID,
			&i.CreatorID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.ArchivedAt,
			&i.ArchivedBy,
			&i.AvatarUrl,
			&i.Instructions,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listSquadsByMember = `-- name: ListSquadsByMember :many
SELECT s.id, s.workspace_id, s.name, s.description, s.leader_id, s.creator_id, s.created_at, s.updated_at, s.archived_at, s.archived_by, s.avatar_url, s.instructions FROM squad s
JOIN squad_member sm ON sm.squad_id = s.id
WHERE s.workspace_id = $1 AND sm.member_type = $2 AND sm.member_id = $3
ORDER BY s.created_at ASC
`

type ListSquadsByMemberParams struct {
	WorkspaceID pgtype.UUID `json:"workspace_id"`
	MemberType  string      `json:"member_type"`
	MemberID    pgtype.UUID `json:"member_id"`
}

// Find all squads a given entity belongs to in a workspace.
func (q *Queries) ListSquadsByMember(ctx context.Context, arg ListSquadsByMemberParams) ([]Squad, error) {
	rows, err := q.db.Query(ctx, listSquadsByMember, arg.WorkspaceID, arg.MemberType, arg.MemberID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []Squad{}
	for rows.Next() {
		var i Squad
		if err := rows.Scan(
			&i.ID,
			&i.WorkspaceID,
			&i.Name,
			&i.Description,
			&i.LeaderID,
			&i.CreatorID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.ArchivedAt,
			&i.ArchivedBy,
			&i.AvatarUrl,
			&i.Instructions,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const removeSquadMember = `-- name: RemoveSquadMember :execrows
DELETE FROM squad_member
WHERE squad_id = $1 AND member_type = $2 AND member_id = $3
`

type RemoveSquadMemberParams struct {
	SquadID    pgtype.UUID `json:"squad_id"`
	MemberType string      `json:"member_type"`
	MemberID   pgtype.UUID `json:"member_id"`
}

func (q *Queries) RemoveSquadMember(ctx context.Context, arg RemoveSquadMemberParams) (int64, error) {
	result, err := q.db.Exec(ctx, removeSquadMember, arg.SquadID, arg.MemberType, arg.MemberID)
	if err != nil {
		return 0, err
	}
	return result.RowsAffected(), nil
}

const transferSquadAssignees = `-- name: TransferSquadAssignees :exec
UPDATE issue SET assignee_type = 'agent', assignee_id = $2, updated_at = now()
WHERE assignee_type = 'squad' AND assignee_id = $1
`

type TransferSquadAssigneesParams struct {
	AssigneeID   pgtype.UUID `json:"assignee_id"`
	AssigneeID_2 pgtype.UUID `json:"assignee_id_2"`
}

// Transfer all issues assigned to a squad to the squad's leader agent.
func (q *Queries) TransferSquadAssignees(ctx context.Context, arg TransferSquadAssigneesParams) error {
	_, err := q.db.Exec(ctx, transferSquadAssignees, arg.AssigneeID, arg.AssigneeID_2)
	return err
}

const transferSquadAutopilotsToLeader = `-- name: TransferSquadAutopilotsToLeader :exec
UPDATE autopilot
SET assignee_type = 'agent',
    assignee_id = $2,
    updated_at = now()
WHERE assignee_type = 'squad' AND assignee_id = $1
`

type TransferSquadAutopilotsToLeaderParams struct {
	AssigneeID   pgtype.UUID `json:"assignee_id"`
	AssigneeID_2 pgtype.UUID `json:"assignee_id_2"`
}

// Mirrors TransferSquadAssignees for autopilot rows: when a squad is archived,
// any autopilot still pointing at the squad would otherwise dangle and the
// admission gate would skip every subsequent dispatch with "assignee squad
// cannot be resolved". Rewrite the assignee in place to the leader agent so
// the autopilot keeps firing under the same leader-only execution semantics
// it had a moment before the archive (Path A from MUL-2429).
func (q *Queries) TransferSquadAutopilotsToLeader(ctx context.Context, arg TransferSquadAutopilotsToLeaderParams) error {
	_, err := q.db.Exec(ctx, transferSquadAutopilotsToLeader, arg.AssigneeID, arg.AssigneeID_2)
	return err
}

const updateSquad = `-- name: UpdateSquad :one
UPDATE squad SET
    name = COALESCE($2, name),
    description = COALESCE($3, description),
    leader_id = COALESCE($4, leader_id),
    avatar_url = COALESCE($5, avatar_url),
    instructions = COALESCE($6, instructions),
    updated_at = now()
WHERE id = $1
RETURNING id, workspace_id, name, description, leader_id, creator_id, created_at, updated_at, archived_at, archived_by, avatar_url, instructions
`

type UpdateSquadParams struct {
	ID           pgtype.UUID `json:"id"`
	Name         pgtype.Text `json:"name"`
	Description  pgtype.Text `json:"description"`
	LeaderID     pgtype.UUID `json:"leader_id"`
	AvatarUrl    pgtype.Text `json:"avatar_url"`
	Instructions pgtype.Text `json:"instructions"`
}

func (q *Queries) UpdateSquad(ctx context.Context, arg UpdateSquadParams) (Squad, error) {
	row := q.db.QueryRow(ctx, updateSquad,
		arg.ID,
		arg.Name,
		arg.Description,
		arg.LeaderID,
		arg.AvatarUrl,
		arg.Instructions,
	)
	var i Squad
	err := row.Scan(
		&i.ID,
		&i.WorkspaceID,
		&i.Name,
		&i.Description,
		&i.LeaderID,
		&i.CreatorID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.ArchivedAt,
		&i.ArchivedBy,
		&i.AvatarUrl,
		&i.Instructions,
	)
	return i, err
}

const updateSquadMemberRole = `-- name: UpdateSquadMemberRole :one
UPDATE squad_member SET role = $4
WHERE squad_id = $1 AND member_type = $2 AND member_id = $3
RETURNING id, squad_id, member_type, member_id, role, created_at
`

type UpdateSquadMemberRoleParams struct {
	SquadID    pgtype.UUID `json:"squad_id"`
	MemberType string      `json:"member_type"`
	MemberID   pgtype.UUID `json:"member_id"`
	Role       string      `json:"role"`
}

func (q *Queries) UpdateSquadMemberRole(ctx context.Context, arg UpdateSquadMemberRoleParams) (SquadMember, error) {
	row := q.db.QueryRow(ctx, updateSquadMemberRole,
		arg.SquadID,
		arg.MemberType,
		arg.MemberID,
		arg.Role,
	)
	var i SquadMember
	err := row.Scan(
		&i.ID,
		&i.SquadID,
		&i.MemberType,
		&i.MemberID,
		&i.Role,
		&i.CreatedAt,
	)
	return i, err
}
