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

package dbgen

import (
	"context"

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

const CountRatingsByTarget = `-- name: CountRatingsByTarget :one
SELECT COUNT(*)::BIGINT
FROM ratings
WHERE target_type = $1 AND target_id = $2
`

type CountRatingsByTargetParams struct {
	TargetType string `json:"target_type"`
	TargetID   int64  `json:"target_id"`
}

func (q *Queries) CountRatingsByTarget(ctx context.Context, arg CountRatingsByTargetParams) (int64, error) {
	row := q.db.QueryRow(ctx, CountRatingsByTarget, arg.TargetType, arg.TargetID)
	var column_1 int64
	err := row.Scan(&column_1)
	return column_1, err
}

const DeleteRating = `-- name: DeleteRating :exec
DELETE FROM ratings
WHERE id = $1 AND user_id = $2
`

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

func (q *Queries) DeleteRating(ctx context.Context, arg DeleteRatingParams) error {
	_, err := q.db.Exec(ctx, DeleteRating, arg.ID, arg.UserID)
	return err
}

const GetRatingByUserAndTarget = `-- name: GetRatingByUserAndTarget :one
SELECT id, user_id, target_type, target_id, stars, review, created_at, updated_at
FROM ratings
WHERE user_id = $1 AND target_type = $2 AND target_id = $3
`

type GetRatingByUserAndTargetParams struct {
	UserID     int64  `json:"user_id"`
	TargetType string `json:"target_type"`
	TargetID   int64  `json:"target_id"`
}

func (q *Queries) GetRatingByUserAndTarget(ctx context.Context, arg GetRatingByUserAndTargetParams) (Rating, error) {
	row := q.db.QueryRow(ctx, GetRatingByUserAndTarget, arg.UserID, arg.TargetType, arg.TargetID)
	var i Rating
	err := row.Scan(
		&i.ID,
		&i.UserID,
		&i.TargetType,
		&i.TargetID,
		&i.Stars,
		&i.Review,
		&i.CreatedAt,
		&i.UpdatedAt,
	)
	return i, err
}

const GetRatingSummary = `-- name: GetRatingSummary :one
SELECT
    COUNT(*)::BIGINT AS total_count,
    COALESCE(AVG(stars), 0)::FLOAT AS average_stars
FROM ratings
WHERE target_type = $1 AND target_id = $2
`

type GetRatingSummaryParams struct {
	TargetType string `json:"target_type"`
	TargetID   int64  `json:"target_id"`
}

type GetRatingSummaryRow struct {
	TotalCount   int64   `json:"total_count"`
	AverageStars float64 `json:"average_stars"`
}

func (q *Queries) GetRatingSummary(ctx context.Context, arg GetRatingSummaryParams) (GetRatingSummaryRow, error) {
	row := q.db.QueryRow(ctx, GetRatingSummary, arg.TargetType, arg.TargetID)
	var i GetRatingSummaryRow
	err := row.Scan(&i.TotalCount, &i.AverageStars)
	return i, err
}

const GetRatingsByTarget = `-- name: GetRatingsByTarget :many
SELECT id, user_id, target_type, target_id, stars, review, created_at, updated_at
FROM ratings
WHERE target_type = $1 AND target_id = $2
ORDER BY created_at DESC
LIMIT $4::INT
OFFSET $3::INT
`

type GetRatingsByTargetParams struct {
	TargetType string      `json:"target_type"`
	TargetID   int64       `json:"target_id"`
	Offset     pgtype.Int4 `json:"offset"`
	Limit      pgtype.Int4 `json:"limit"`
}

func (q *Queries) GetRatingsByTarget(ctx context.Context, arg GetRatingsByTargetParams) ([]Rating, error) {
	rows, err := q.db.Query(ctx, GetRatingsByTarget,
		arg.TargetType,
		arg.TargetID,
		arg.Offset,
		arg.Limit,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []Rating
	for rows.Next() {
		var i Rating
		if err := rows.Scan(
			&i.ID,
			&i.UserID,
			&i.TargetType,
			&i.TargetID,
			&i.Stars,
			&i.Review,
			&i.CreatedAt,
			&i.UpdatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const GetUserRatings = `-- name: GetUserRatings :many
SELECT id, user_id, target_type, target_id, stars, review, created_at, updated_at
FROM ratings
WHERE user_id = $1
ORDER BY updated_at DESC
`

func (q *Queries) GetUserRatings(ctx context.Context, userID int64) ([]Rating, error) {
	rows, err := q.db.Query(ctx, GetUserRatings, userID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []Rating
	for rows.Next() {
		var i Rating
		if err := rows.Scan(
			&i.ID,
			&i.UserID,
			&i.TargetType,
			&i.TargetID,
			&i.Stars,
			&i.Review,
			&i.CreatedAt,
			&i.UpdatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const UpsertRating = `-- name: UpsertRating :one
INSERT INTO ratings (user_id, target_type, target_id, stars, review)
VALUES ($1, $2, $3, $4, $5)
ON CONFLICT (user_id, target_type, target_id)
DO UPDATE SET stars = EXCLUDED.stars, review = EXCLUDED.review, updated_at = NOW()
RETURNING id, user_id, target_type, target_id, stars, review, created_at, updated_at
`

type UpsertRatingParams struct {
	UserID     int64       `json:"user_id"`
	TargetType string      `json:"target_type"`
	TargetID   int64       `json:"target_id"`
	Stars      int16       `json:"stars"`
	Review     pgtype.Text `json:"review"`
}

func (q *Queries) UpsertRating(ctx context.Context, arg UpsertRatingParams) (Rating, error) {
	row := q.db.QueryRow(ctx, UpsertRating,
		arg.UserID,
		arg.TargetType,
		arg.TargetID,
		arg.Stars,
		arg.Review,
	)
	var i Rating
	err := row.Scan(
		&i.ID,
		&i.UserID,
		&i.TargetType,
		&i.TargetID,
		&i.Stars,
		&i.Review,
		&i.CreatedAt,
		&i.UpdatedAt,
	)
	return i, err
}
