// Code generated by sqlc. DO NOT EDIT.
// versions:
//   sqlc v1.29.0
// source: user.sql

package dbgen

import (
	"context"

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

const CheckPhoneEmailExist = `-- name: CheckPhoneEmailExist :one
SELECT EXISTS (
        SELECT 1
        FROM users
        WHERE users.phone_number = $1
            AND users.phone_number IS NOT NULL
    ) AS phone_exists,
    EXISTS (
        SELECT 1
        FROM users
        WHERE users.email = $2
            AND users.email IS NOT NULL
    ) AS email_exists
`

type CheckPhoneEmailExistParams struct {
	PhoneNumber pgtype.Text `json:"phone_number"`
	Email       pgtype.Text `json:"email"`
}

type CheckPhoneEmailExistRow struct {
	PhoneExists bool `json:"phone_exists"`
	EmailExists bool `json:"email_exists"`
}

func (q *Queries) CheckPhoneEmailExist(ctx context.Context, arg CheckPhoneEmailExistParams) (CheckPhoneEmailExistRow, error) {
	row := q.db.QueryRow(ctx, CheckPhoneEmailExist, arg.PhoneNumber, arg.Email)
	var i CheckPhoneEmailExistRow
	err := row.Scan(&i.PhoneExists, &i.EmailExists)
	return i, err
}

const CreateUser = `-- name: CreateUser :one
INSERT INTO users (
    first_name,
    last_name,
    email,
    phone_number,
    role,
    password,
    email_verified,
    phone_verified,
    created_at,
    updated_at,
    suspended,
    company_id
)
VALUES (
    $1, $2, $3, $4, $5, $6,
    $7, $8, $9, $10, $11, $12
)
RETURNING id,
    first_name,
    last_name,
    email,
    phone_number,
    role,
    email_verified,
    phone_verified,
    created_at,
    updated_at,
    suspended,
    company_id
`

type CreateUserParams struct {
	FirstName     string             `json:"first_name"`
	LastName      string             `json:"last_name"`
	Email         pgtype.Text        `json:"email"`
	PhoneNumber   pgtype.Text        `json:"phone_number"`
	Role          string             `json:"role"`
	Password      []byte             `json:"password"`
	EmailVerified bool               `json:"email_verified"`
	PhoneVerified bool               `json:"phone_verified"`
	CreatedAt     pgtype.Timestamptz `json:"created_at"`
	UpdatedAt     pgtype.Timestamptz `json:"updated_at"`
	Suspended     bool               `json:"suspended"`
	CompanyID     pgtype.Int8        `json:"company_id"`
}

type CreateUserRow struct {
	ID            int64              `json:"id"`
	FirstName     string             `json:"first_name"`
	LastName      string             `json:"last_name"`
	Email         pgtype.Text        `json:"email"`
	PhoneNumber   pgtype.Text        `json:"phone_number"`
	Role          string             `json:"role"`
	EmailVerified bool               `json:"email_verified"`
	PhoneVerified bool               `json:"phone_verified"`
	CreatedAt     pgtype.Timestamptz `json:"created_at"`
	UpdatedAt     pgtype.Timestamptz `json:"updated_at"`
	Suspended     bool               `json:"suspended"`
	CompanyID     pgtype.Int8        `json:"company_id"`
}

func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) (CreateUserRow, error) {
	row := q.db.QueryRow(ctx, CreateUser,
		arg.FirstName,
		arg.LastName,
		arg.Email,
		arg.PhoneNumber,
		arg.Role,
		arg.Password,
		arg.EmailVerified,
		arg.PhoneVerified,
		arg.CreatedAt,
		arg.UpdatedAt,
		arg.Suspended,
		arg.CompanyID,
	)
	var i CreateUserRow
	err := row.Scan(
		&i.ID,
		&i.FirstName,
		&i.LastName,
		&i.Email,
		&i.PhoneNumber,
		&i.Role,
		&i.EmailVerified,
		&i.PhoneVerified,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Suspended,
		&i.CompanyID,
	)
	return i, err
}

const DeleteUser = `-- name: DeleteUser :exec
DELETE FROM users
WHERE id = $1
`

func (q *Queries) DeleteUser(ctx context.Context, id int64) error {
	_, err := q.db.Exec(ctx, DeleteUser, id)
	return err
}

const GetAllUsers = `-- name: GetAllUsers :many
SELECT id,
    first_name,
    last_name,
    email,
    phone_number,
    role,
    email_verified,
    phone_verified,
    created_at,
    updated_at,
    suspended,
    suspended_at,
    company_id
FROM users
wHERE (
        role = $1
        OR $1 IS NULL
    )
    AND (
        company_id = $2
        OR $2 IS NULL
    )
LIMIT $4 OFFSET $3
`

type GetAllUsersParams struct {
	Role      string      `json:"role"`
	CompanyID pgtype.Int8 `json:"company_id"`
	Offset    pgtype.Int4 `json:"offset"`
	Limit     pgtype.Int4 `json:"limit"`
}

type GetAllUsersRow struct {
	ID            int64              `json:"id"`
	FirstName     string             `json:"first_name"`
	LastName      string             `json:"last_name"`
	Email         pgtype.Text        `json:"email"`
	PhoneNumber   pgtype.Text        `json:"phone_number"`
	Role          string             `json:"role"`
	EmailVerified bool               `json:"email_verified"`
	PhoneVerified bool               `json:"phone_verified"`
	CreatedAt     pgtype.Timestamptz `json:"created_at"`
	UpdatedAt     pgtype.Timestamptz `json:"updated_at"`
	Suspended     bool               `json:"suspended"`
	SuspendedAt   pgtype.Timestamptz `json:"suspended_at"`
	CompanyID     pgtype.Int8        `json:"company_id"`
}

func (q *Queries) GetAllUsers(ctx context.Context, arg GetAllUsersParams) ([]GetAllUsersRow, error) {
	rows, err := q.db.Query(ctx, GetAllUsers,
		arg.Role,
		arg.CompanyID,
		arg.Offset,
		arg.Limit,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []GetAllUsersRow
	for rows.Next() {
		var i GetAllUsersRow
		if err := rows.Scan(
			&i.ID,
			&i.FirstName,
			&i.LastName,
			&i.Email,
			&i.PhoneNumber,
			&i.Role,
			&i.EmailVerified,
			&i.PhoneVerified,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.Suspended,
			&i.SuspendedAt,
			&i.CompanyID,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const GetTotalUsers = `-- name: GetTotalUsers :one
SELECT COUNT(*)
FROM users
wHERE (
        role = $1
        OR $1 IS NULL
    )
    AND (
        company_id = $2
        OR $2 IS NULL
    )
`

type GetTotalUsersParams struct {
	Role      string      `json:"role"`
	CompanyID pgtype.Int8 `json:"company_id"`
}

func (q *Queries) GetTotalUsers(ctx context.Context, arg GetTotalUsersParams) (int64, error) {
	row := q.db.QueryRow(ctx, GetTotalUsers, arg.Role, arg.CompanyID)
	var count int64
	err := row.Scan(&count)
	return count, err
}

const GetUserByEmail = `-- name: GetUserByEmail :one
SELECT id,
    first_name,
    last_name,
    email,
    phone_number,
    role,
    email_verified,
    phone_verified,
    created_at,
    updated_at,
    suspended,
    suspended_at,
    company_id
FROM users
WHERE email = $1
`

type GetUserByEmailRow struct {
	ID            int64              `json:"id"`
	FirstName     string             `json:"first_name"`
	LastName      string             `json:"last_name"`
	Email         pgtype.Text        `json:"email"`
	PhoneNumber   pgtype.Text        `json:"phone_number"`
	Role          string             `json:"role"`
	EmailVerified bool               `json:"email_verified"`
	PhoneVerified bool               `json:"phone_verified"`
	CreatedAt     pgtype.Timestamptz `json:"created_at"`
	UpdatedAt     pgtype.Timestamptz `json:"updated_at"`
	Suspended     bool               `json:"suspended"`
	SuspendedAt   pgtype.Timestamptz `json:"suspended_at"`
	CompanyID     pgtype.Int8        `json:"company_id"`
}

func (q *Queries) GetUserByEmail(ctx context.Context, email pgtype.Text) (GetUserByEmailRow, error) {
	row := q.db.QueryRow(ctx, GetUserByEmail, email)
	var i GetUserByEmailRow
	err := row.Scan(
		&i.ID,
		&i.FirstName,
		&i.LastName,
		&i.Email,
		&i.PhoneNumber,
		&i.Role,
		&i.EmailVerified,
		&i.PhoneVerified,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Suspended,
		&i.SuspendedAt,
		&i.CompanyID,
	)
	return i, err
}

const GetUserByID = `-- name: GetUserByID :one
SELECT id, first_name, last_name, email, phone_number, role, password, email_verified, phone_verified, created_at, updated_at, company_id, suspended_at, suspended, referral_code, referred_by
FROM users
WHERE id = $1
`

func (q *Queries) GetUserByID(ctx context.Context, id int64) (User, error) {
	row := q.db.QueryRow(ctx, GetUserByID, id)
	var i User
	err := row.Scan(
		&i.ID,
		&i.FirstName,
		&i.LastName,
		&i.Email,
		&i.PhoneNumber,
		&i.Role,
		&i.Password,
		&i.EmailVerified,
		&i.PhoneVerified,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.CompanyID,
		&i.SuspendedAt,
		&i.Suspended,
		&i.ReferralCode,
		&i.ReferredBy,
	)
	return i, err
}

const GetUserByPhone = `-- name: GetUserByPhone :one
SELECT id,
    first_name,
    last_name,
    email,
    phone_number,
    role,
    email_verified,
    phone_verified,
    created_at,
    updated_at,
    suspended,
    suspended_at,
    company_id
FROM users
WHERE phone_number = $1
`

type GetUserByPhoneRow struct {
	ID            int64              `json:"id"`
	FirstName     string             `json:"first_name"`
	LastName      string             `json:"last_name"`
	Email         pgtype.Text        `json:"email"`
	PhoneNumber   pgtype.Text        `json:"phone_number"`
	Role          string             `json:"role"`
	EmailVerified bool               `json:"email_verified"`
	PhoneVerified bool               `json:"phone_verified"`
	CreatedAt     pgtype.Timestamptz `json:"created_at"`
	UpdatedAt     pgtype.Timestamptz `json:"updated_at"`
	Suspended     bool               `json:"suspended"`
	SuspendedAt   pgtype.Timestamptz `json:"suspended_at"`
	CompanyID     pgtype.Int8        `json:"company_id"`
}

func (q *Queries) GetUserByPhone(ctx context.Context, phoneNumber pgtype.Text) (GetUserByPhoneRow, error) {
	row := q.db.QueryRow(ctx, GetUserByPhone, phoneNumber)
	var i GetUserByPhoneRow
	err := row.Scan(
		&i.ID,
		&i.FirstName,
		&i.LastName,
		&i.Email,
		&i.PhoneNumber,
		&i.Role,
		&i.EmailVerified,
		&i.PhoneVerified,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Suspended,
		&i.SuspendedAt,
		&i.CompanyID,
	)
	return i, err
}

const SearchUserByNameOrPhone = `-- name: SearchUserByNameOrPhone :many
SELECT id,
    first_name,
    last_name,
    email,
    phone_number,
    role,
    email_verified,
    phone_verified,
    created_at,
    updated_at,
    suspended,
    suspended_at,
    company_id
FROM users
WHERE (
        first_name ILIKE '%' || $1 || '%'
        OR last_name ILIKE '%' || $1 || '%'
        OR phone_number LIKE '%' || $1 || '%'
    )
    AND (
        role = $2
        OR $2 IS NULL
    )
    AND (
        company_id = $3
        OR $3 IS NULL
    )
`

type SearchUserByNameOrPhoneParams struct {
	Column1   pgtype.Text `json:"column_1"`
	Role      pgtype.Text `json:"role"`
	CompanyID pgtype.Int8 `json:"company_id"`
}

type SearchUserByNameOrPhoneRow struct {
	ID            int64              `json:"id"`
	FirstName     string             `json:"first_name"`
	LastName      string             `json:"last_name"`
	Email         pgtype.Text        `json:"email"`
	PhoneNumber   pgtype.Text        `json:"phone_number"`
	Role          string             `json:"role"`
	EmailVerified bool               `json:"email_verified"`
	PhoneVerified bool               `json:"phone_verified"`
	CreatedAt     pgtype.Timestamptz `json:"created_at"`
	UpdatedAt     pgtype.Timestamptz `json:"updated_at"`
	Suspended     bool               `json:"suspended"`
	SuspendedAt   pgtype.Timestamptz `json:"suspended_at"`
	CompanyID     pgtype.Int8        `json:"company_id"`
}

func (q *Queries) SearchUserByNameOrPhone(ctx context.Context, arg SearchUserByNameOrPhoneParams) ([]SearchUserByNameOrPhoneRow, error) {
	rows, err := q.db.Query(ctx, SearchUserByNameOrPhone, arg.Column1, arg.Role, arg.CompanyID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []SearchUserByNameOrPhoneRow
	for rows.Next() {
		var i SearchUserByNameOrPhoneRow
		if err := rows.Scan(
			&i.ID,
			&i.FirstName,
			&i.LastName,
			&i.Email,
			&i.PhoneNumber,
			&i.Role,
			&i.EmailVerified,
			&i.PhoneVerified,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.Suspended,
			&i.SuspendedAt,
			&i.CompanyID,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const SuspendUser = `-- name: SuspendUser :exec
UPDATE users
SET suspended = $1,
    suspended_at = $2,
    updated_at = CURRENT_TIMESTAMP
WHERE id = $3
`

type SuspendUserParams struct {
	Suspended   bool               `json:"suspended"`
	SuspendedAt pgtype.Timestamptz `json:"suspended_at"`
	ID          int64              `json:"id"`
}

func (q *Queries) SuspendUser(ctx context.Context, arg SuspendUserParams) error {
	_, err := q.db.Exec(ctx, SuspendUser, arg.Suspended, arg.SuspendedAt, arg.ID)
	return err
}

const UpdatePassword = `-- name: UpdatePassword :exec
UPDATE users
SET password = $1,
    updated_at = $4
WHERE (
        email = $2
        OR phone_number = $3
    )
`

type UpdatePasswordParams struct {
	Password    []byte             `json:"password"`
	Email       pgtype.Text        `json:"email"`
	PhoneNumber pgtype.Text        `json:"phone_number"`
	UpdatedAt   pgtype.Timestamptz `json:"updated_at"`
}

func (q *Queries) UpdatePassword(ctx context.Context, arg UpdatePasswordParams) error {
	_, err := q.db.Exec(ctx, UpdatePassword,
		arg.Password,
		arg.Email,
		arg.PhoneNumber,
		arg.UpdatedAt,
	)
	return err
}

const UpdateUser = `-- name: UpdateUser :exec
UPDATE users
SET first_name = $1,
    last_name = $2,
    suspended = $3,
    updated_at = CURRENT_TIMESTAMP
WHERE id = $4
`

type UpdateUserParams struct {
	FirstName string `json:"first_name"`
	LastName  string `json:"last_name"`
	Suspended bool   `json:"suspended"`
	ID        int64  `json:"id"`
}

func (q *Queries) UpdateUser(ctx context.Context, arg UpdateUserParams) error {
	_, err := q.db.Exec(ctx, UpdateUser,
		arg.FirstName,
		arg.LastName,
		arg.Suspended,
		arg.ID,
	)
	return err
}

const UpdateUserCompany = `-- name: UpdateUserCompany :exec
UPDATE users
SET company_id = $1
WHERE id = $2
`

type UpdateUserCompanyParams struct {
	CompanyID pgtype.Int8 `json:"company_id"`
	ID        int64       `json:"id"`
}

func (q *Queries) UpdateUserCompany(ctx context.Context, arg UpdateUserCompanyParams) error {
	_, err := q.db.Exec(ctx, UpdateUserCompany, arg.CompanyID, arg.ID)
	return err
}
