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

package db

import (
	"context"

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

const countIssuesByProject = `-- name: CountIssuesByProject :one
SELECT count(*) FROM issue
WHERE project_id = $1
`

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

const createProject = `-- name: CreateProject :one
INSERT INTO project (
    workspace_id, title, description, icon, status,
    lead_type, lead_id, priority
) VALUES (
    $1, $2, $3, $4, $5, $6, $7, $8
) RETURNING id, workspace_id, title, description, icon, status, lead_type, lead_id, created_at, updated_at, priority
`

type CreateProjectParams struct {
	WorkspaceID pgtype.UUID `json:"workspace_id"`
	Title       string      `json:"title"`
	Description pgtype.Text `json:"description"`
	Icon        pgtype.Text `json:"icon"`
	Status      string      `json:"status"`
	LeadType    pgtype.Text `json:"lead_type"`
	LeadID      pgtype.UUID `json:"lead_id"`
	Priority    string      `json:"priority"`
}

func (q *Queries) CreateProject(ctx context.Context, arg CreateProjectParams) (Project, error) {
	row := q.db.QueryRow(ctx, createProject,
		arg.WorkspaceID,
		arg.Title,
		arg.Description,
		arg.Icon,
		arg.Status,
		arg.LeadType,
		arg.LeadID,
		arg.Priority,
	)
	var i Project
	err := row.Scan(
		&i.ID,
		&i.WorkspaceID,
		&i.Title,
		&i.Description,
		&i.Icon,
		&i.Status,
		&i.LeadType,
		&i.LeadID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Priority,
	)
	return i, err
}

const deleteProject = `-- name: DeleteProject :exec
DELETE FROM project WHERE id = $1 AND workspace_id = $2
`

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

// Defense-in-depth: workspace_id is a SQL-layer tenant guard. See DeleteIssue.
func (q *Queries) DeleteProject(ctx context.Context, arg DeleteProjectParams) error {
	_, err := q.db.Exec(ctx, deleteProject, arg.ID, arg.WorkspaceID)
	return err
}

const getProject = `-- name: GetProject :one
SELECT id, workspace_id, title, description, icon, status, lead_type, lead_id, created_at, updated_at, priority FROM project
WHERE id = $1
`

func (q *Queries) GetProject(ctx context.Context, id pgtype.UUID) (Project, error) {
	row := q.db.QueryRow(ctx, getProject, id)
	var i Project
	err := row.Scan(
		&i.ID,
		&i.WorkspaceID,
		&i.Title,
		&i.Description,
		&i.Icon,
		&i.Status,
		&i.LeadType,
		&i.LeadID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Priority,
	)
	return i, err
}

const getProjectInWorkspace = `-- name: GetProjectInWorkspace :one
SELECT id, workspace_id, title, description, icon, status, lead_type, lead_id, created_at, updated_at, priority FROM project
WHERE id = $1 AND workspace_id = $2
`

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

func (q *Queries) GetProjectInWorkspace(ctx context.Context, arg GetProjectInWorkspaceParams) (Project, error) {
	row := q.db.QueryRow(ctx, getProjectInWorkspace, arg.ID, arg.WorkspaceID)
	var i Project
	err := row.Scan(
		&i.ID,
		&i.WorkspaceID,
		&i.Title,
		&i.Description,
		&i.Icon,
		&i.Status,
		&i.LeadType,
		&i.LeadID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Priority,
	)
	return i, err
}

const getProjectIssueStats = `-- name: GetProjectIssueStats :many
SELECT project_id,
       count(*)::bigint AS total_count,
       count(*) FILTER (WHERE status IN ('done', 'cancelled'))::bigint AS done_count
FROM issue
WHERE project_id = ANY($1::uuid[])
GROUP BY project_id
`

type GetProjectIssueStatsRow struct {
	ProjectID  pgtype.UUID `json:"project_id"`
	TotalCount int64       `json:"total_count"`
	DoneCount  int64       `json:"done_count"`
}

func (q *Queries) GetProjectIssueStats(ctx context.Context, projectIds []pgtype.UUID) ([]GetProjectIssueStatsRow, error) {
	rows, err := q.db.Query(ctx, getProjectIssueStats, projectIds)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []GetProjectIssueStatsRow{}
	for rows.Next() {
		var i GetProjectIssueStatsRow
		if err := rows.Scan(&i.ProjectID, &i.TotalCount, &i.DoneCount); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listProjects = `-- name: ListProjects :many
SELECT id, workspace_id, title, description, icon, status, lead_type, lead_id, created_at, updated_at, priority FROM project
WHERE workspace_id = $1
  AND ($2::text IS NULL OR status = $2)
  AND ($3::text IS NULL OR priority = $3)
ORDER BY created_at DESC
`

type ListProjectsParams struct {
	WorkspaceID pgtype.UUID `json:"workspace_id"`
	Status      pgtype.Text `json:"status"`
	Priority    pgtype.Text `json:"priority"`
}

func (q *Queries) ListProjects(ctx context.Context, arg ListProjectsParams) ([]Project, error) {
	rows, err := q.db.Query(ctx, listProjects, arg.WorkspaceID, arg.Status, arg.Priority)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []Project{}
	for rows.Next() {
		var i Project
		if err := rows.Scan(
			&i.ID,
			&i.WorkspaceID,
			&i.Title,
			&i.Description,
			&i.Icon,
			&i.Status,
			&i.LeadType,
			&i.LeadID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.Priority,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const updateProject = `-- name: UpdateProject :one
UPDATE project SET
    title = COALESCE($2, title),
    description = $3,
    icon = $4,
    status = COALESCE($5, status),
    priority = COALESCE($6, priority),
    lead_type = $7,
    lead_id = $8,
    updated_at = now()
WHERE id = $1
RETURNING id, workspace_id, title, description, icon, status, lead_type, lead_id, created_at, updated_at, priority
`

type UpdateProjectParams struct {
	ID          pgtype.UUID `json:"id"`
	Title       pgtype.Text `json:"title"`
	Description pgtype.Text `json:"description"`
	Icon        pgtype.Text `json:"icon"`
	Status      pgtype.Text `json:"status"`
	Priority    pgtype.Text `json:"priority"`
	LeadType    pgtype.Text `json:"lead_type"`
	LeadID      pgtype.UUID `json:"lead_id"`
}

func (q *Queries) UpdateProject(ctx context.Context, arg UpdateProjectParams) (Project, error) {
	row := q.db.QueryRow(ctx, updateProject,
		arg.ID,
		arg.Title,
		arg.Description,
		arg.Icon,
		arg.Status,
		arg.Priority,
		arg.LeadType,
		arg.LeadID,
	)
	var i Project
	err := row.Scan(
		&i.ID,
		&i.WorkspaceID,
		&i.Title,
		&i.Description,
		&i.Icon,
		&i.Status,
		&i.LeadType,
		&i.LeadID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Priority,
	)
	return i, err
}
