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

package database

import (
	"context"
	"database/sql"
	"time"

	"github.com/sqlc-dev/pqtype"
)

const createNewNotification = `-- name: CreateNewNotification :one
INSERT INTO notifications (
    user_id, 
    message, 
    notification_type, 
    status, 
    expires_at,
    meta, 
    redis_key
)VALUES ($1, $2, $3, $4, $5, $6, $7)
RETURNING id, created_at, updated_at
`

type CreateNewNotificationParams struct {
	UserID           int64
	Message          string
	NotificationType string
	Status           NotificationStatus
	ExpiresAt        sql.NullTime
	Meta             pqtype.NullRawMessage
	RedisKey         sql.NullString
}

type CreateNewNotificationRow struct {
	ID        int64
	CreatedAt time.Time
	UpdatedAt time.Time
}

func (q *Queries) CreateNewNotification(ctx context.Context, arg CreateNewNotificationParams) (CreateNewNotificationRow, error) {
	row := q.db.QueryRowContext(ctx, createNewNotification,
		arg.UserID,
		arg.Message,
		arg.NotificationType,
		arg.Status,
		arg.ExpiresAt,
		arg.Meta,
		arg.RedisKey,
	)
	var i CreateNewNotificationRow
	err := row.Scan(&i.ID, &i.CreatedAt, &i.UpdatedAt)
	return i, err
}

const deleteAllNotificationsByUserId = `-- name: DeleteAllNotificationsByUserId :exec
DELETE FROM notifications
WHERE user_id = $1
`

func (q *Queries) DeleteAllNotificationsByUserId(ctx context.Context, userID int64) error {
	_, err := q.db.ExecContext(ctx, deleteAllNotificationsByUserId, userID)
	return err
}

const deleteNotificationById = `-- name: DeleteNotificationById :one
DELETE FROM notifications
WHERE id = $1 AND user_id = $2
RETURNING id
`

type DeleteNotificationByIdParams struct {
	ID     int64
	UserID int64
}

func (q *Queries) DeleteNotificationById(ctx context.Context, arg DeleteNotificationByIdParams) (int64, error) {
	row := q.db.QueryRowContext(ctx, deleteNotificationById, arg.ID, arg.UserID)
	var id int64
	err := row.Scan(&id)
	return id, err
}

const getAllExpiredNotifications = `-- name: GetAllExpiredNotifications :many
SELECT
    COUNT(*) OVER() AS total_count,
    id,
    user_id,
    message,
    notification_type,
    status,
    created_at,
    updated_at,
    read_at,
    expires_at,
    meta,
    redis_key
FROM notifications
WHERE expires_at < NOW()
AND status = 'pending'
ORDER BY created_at DESC
LIMIT $1 OFFSET $2
`

type GetAllExpiredNotificationsParams struct {
	Limit  int32
	Offset int32
}

type GetAllExpiredNotificationsRow struct {
	TotalCount       int64
	ID               int64
	UserID           int64
	Message          string
	NotificationType string
	Status           NotificationStatus
	CreatedAt        time.Time
	UpdatedAt        time.Time
	ReadAt           sql.NullTime
	ExpiresAt        sql.NullTime
	Meta             pqtype.NullRawMessage
	RedisKey         sql.NullString
}

func (q *Queries) GetAllExpiredNotifications(ctx context.Context, arg GetAllExpiredNotificationsParams) ([]GetAllExpiredNotificationsRow, error) {
	rows, err := q.db.QueryContext(ctx, getAllExpiredNotifications, arg.Limit, arg.Offset)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []GetAllExpiredNotificationsRow
	for rows.Next() {
		var i GetAllExpiredNotificationsRow
		if err := rows.Scan(
			&i.TotalCount,
			&i.ID,
			&i.UserID,
			&i.Message,
			&i.NotificationType,
			&i.Status,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.ReadAt,
			&i.ExpiresAt,
			&i.Meta,
			&i.RedisKey,
		); 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 getAllNotificationsByUserId = `-- name: GetAllNotificationsByUserId :many
SELECT
    COUNT(*) OVER() AS total_count,
    id,
    user_id,
    message,
    notification_type,
    status,
    created_at,
    updated_at,
    read_at,
    expires_at,
    meta,
    redis_key
FROM notifications
WHERE user_id = $1
AND ($2 = '' OR to_tsvector('simple', notification_type) @@ plainto_tsquery('simple', $2))
ORDER BY created_at DESC
LIMIT $3 OFFSET $4
`

type GetAllNotificationsByUserIdParams struct {
	UserID  int64
	Column2 interface{}
	Limit   int32
	Offset  int32
}

type GetAllNotificationsByUserIdRow struct {
	TotalCount       int64
	ID               int64
	UserID           int64
	Message          string
	NotificationType string
	Status           NotificationStatus
	CreatedAt        time.Time
	UpdatedAt        time.Time
	ReadAt           sql.NullTime
	ExpiresAt        sql.NullTime
	Meta             pqtype.NullRawMessage
	RedisKey         sql.NullString
}

func (q *Queries) GetAllNotificationsByUserId(ctx context.Context, arg GetAllNotificationsByUserIdParams) ([]GetAllNotificationsByUserIdRow, error) {
	rows, err := q.db.QueryContext(ctx, getAllNotificationsByUserId,
		arg.UserID,
		arg.Column2,
		arg.Limit,
		arg.Offset,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []GetAllNotificationsByUserIdRow
	for rows.Next() {
		var i GetAllNotificationsByUserIdRow
		if err := rows.Scan(
			&i.TotalCount,
			&i.ID,
			&i.UserID,
			&i.Message,
			&i.NotificationType,
			&i.Status,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.ReadAt,
			&i.ExpiresAt,
			&i.Meta,
			&i.RedisKey,
		); 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 getUnreadNotifications = `-- name: GetUnreadNotifications :many
SELECT
    id,
    user_id,
    message,
    notification_type,
    status,
    created_at,
    updated_at,
    read_at,
    expires_at,
    meta,
    redis_key
FROM notifications
WHERE user_id = $1 
AND status = 'pending' 
AND (expires_at > NOW() OR expires_at IS NULL)
`

func (q *Queries) GetUnreadNotifications(ctx context.Context, userID int64) ([]Notification, error) {
	rows, err := q.db.QueryContext(ctx, getUnreadNotifications, userID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []Notification
	for rows.Next() {
		var i Notification
		if err := rows.Scan(
			&i.ID,
			&i.UserID,
			&i.Message,
			&i.NotificationType,
			&i.Status,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.ReadAt,
			&i.ExpiresAt,
			&i.Meta,
			&i.RedisKey,
		); 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 updateNotificationReadAtAndStatus = `-- name: UpdateNotificationReadAtAndStatus :one
UPDATE notifications
SET 
    status = $1,
    read_at = $2
WHERE id = $3
RETURNING updated_at
`

type UpdateNotificationReadAtAndStatusParams struct {
	Status NotificationStatus
	ReadAt sql.NullTime
	ID     int64
}

func (q *Queries) UpdateNotificationReadAtAndStatus(ctx context.Context, arg UpdateNotificationReadAtAndStatusParams) (time.Time, error) {
	row := q.db.QueryRowContext(ctx, updateNotificationReadAtAndStatus, arg.Status, arg.ReadAt, arg.ID)
	var updated_at time.Time
	err := row.Scan(&updated_at)
	return updated_at, err
}
