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

package database

import (
	"context"

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

const BlockUser = `-- name: BlockUser :exec
UPDATE users SET
    is_blocked = TRUE,
    updated_at = CURRENT_TIMESTAMP
WHERE id = $1
`

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

const GetUserProfile = `-- name: GetUserProfile :one


SELECT
    id,
    email,
    phone,
    first_name,
    last_name,
    avatar_url,
    ST_Y(location::geometry) as latitude,
    ST_X(location::geometry) as longitude,
    address,
    city,
    volunteer_rating,
    completed_requests_count,
    is_verified,
    is_blocked,
    email_verified,
    created_at,
    updated_at,
    last_login_at
FROM users
WHERE id = $1 AND deleted_at IS NULL
`

type GetUserProfileRow struct {
	ID                     int64              `json:"id"`
	Email                  string             `json:"email"`
	Phone                  pgtype.Text        `json:"phone"`
	FirstName              string             `json:"first_name"`
	LastName               string             `json:"last_name"`
	AvatarUrl              pgtype.Text        `json:"avatar_url"`
	Latitude               interface{}        `json:"latitude"`
	Longitude              interface{}        `json:"longitude"`
	Address                pgtype.Text        `json:"address"`
	City                   pgtype.Text        `json:"city"`
	VolunteerRating        pgtype.Numeric     `json:"volunteer_rating"`
	CompletedRequestsCount pgtype.Int4        `json:"completed_requests_count"`
	IsVerified             pgtype.Bool        `json:"is_verified"`
	IsBlocked              pgtype.Bool        `json:"is_blocked"`
	EmailVerified          pgtype.Bool        `json:"email_verified"`
	CreatedAt              pgtype.Timestamptz `json:"created_at"`
	UpdatedAt              pgtype.Timestamptz `json:"updated_at"`
	LastLoginAt            pgtype.Timestamptz `json:"last_login_at"`
}

// Фаза 1C: Управление профилем (КРИТИЧНО)
// Запросы для получения и обновления профилей пользователей
// ============================================================================
// Профиль пользователя
// ============================================================================
func (q *Queries) GetUserProfile(ctx context.Context, id int64) (GetUserProfileRow, error) {
	row := q.db.QueryRow(ctx, GetUserProfile, id)
	var i GetUserProfileRow
	err := row.Scan(
		&i.ID,
		&i.Email,
		&i.Phone,
		&i.FirstName,
		&i.LastName,
		&i.AvatarUrl,
		&i.Latitude,
		&i.Longitude,
		&i.Address,
		&i.City,
		&i.VolunteerRating,
		&i.CompletedRequestsCount,
		&i.IsVerified,
		&i.IsBlocked,
		&i.EmailVerified,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.LastLoginAt,
	)
	return i, err
}

const GetUsersByIDs = `-- name: GetUsersByIDs :many

SELECT
    id,
    email,
    phone,
    password_hash,
    first_name,
    last_name,
    avatar_url,
    ST_Y(location::geometry) as latitude,
    ST_X(location::geometry) as longitude,
    address,
    city,
    volunteer_rating,
    completed_requests_count,
    is_verified,
    is_blocked,
    email_verified,
    created_at,
    updated_at,
    last_login_at,
    deleted_at
FROM users
WHERE id = ANY($1::bigint[])
    AND deleted_at IS NULL
`

type GetUsersByIDsRow struct {
	ID                     int64              `json:"id"`
	Email                  string             `json:"email"`
	Phone                  pgtype.Text        `json:"phone"`
	PasswordHash           string             `json:"password_hash"`
	FirstName              string             `json:"first_name"`
	LastName               string             `json:"last_name"`
	AvatarUrl              pgtype.Text        `json:"avatar_url"`
	Latitude               interface{}        `json:"latitude"`
	Longitude              interface{}        `json:"longitude"`
	Address                pgtype.Text        `json:"address"`
	City                   pgtype.Text        `json:"city"`
	VolunteerRating        pgtype.Numeric     `json:"volunteer_rating"`
	CompletedRequestsCount pgtype.Int4        `json:"completed_requests_count"`
	IsVerified             pgtype.Bool        `json:"is_verified"`
	IsBlocked              pgtype.Bool        `json:"is_blocked"`
	EmailVerified          pgtype.Bool        `json:"email_verified"`
	CreatedAt              pgtype.Timestamptz `json:"created_at"`
	UpdatedAt              pgtype.Timestamptz `json:"updated_at"`
	LastLoginAt            pgtype.Timestamptz `json:"last_login_at"`
	DeletedAt              pgtype.Timestamptz `json:"deleted_at"`
}

// ============================================================================
// Поиск пользователей
// ============================================================================
func (q *Queries) GetUsersByIDs(ctx context.Context, dollar_1 []int64) ([]GetUsersByIDsRow, error) {
	rows, err := q.db.Query(ctx, GetUsersByIDs, dollar_1)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []GetUsersByIDsRow{}
	for rows.Next() {
		var i GetUsersByIDsRow
		if err := rows.Scan(
			&i.ID,
			&i.Email,
			&i.Phone,
			&i.PasswordHash,
			&i.FirstName,
			&i.LastName,
			&i.AvatarUrl,
			&i.Latitude,
			&i.Longitude,
			&i.Address,
			&i.City,
			&i.VolunteerRating,
			&i.CompletedRequestsCount,
			&i.IsVerified,
			&i.IsBlocked,
			&i.EmailVerified,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.LastLoginAt,
			&i.DeletedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const GetVolunteerStatistics = `-- name: GetVolunteerStatistics :one
SELECT
    id,
    first_name,
    last_name,
    volunteer_rating,
    completed_requests_count,
    created_at as member_since
FROM users
WHERE id = $1
    AND deleted_at IS NULL
`

type GetVolunteerStatisticsRow struct {
	ID                     int64              `json:"id"`
	FirstName              string             `json:"first_name"`
	LastName               string             `json:"last_name"`
	VolunteerRating        pgtype.Numeric     `json:"volunteer_rating"`
	CompletedRequestsCount pgtype.Int4        `json:"completed_requests_count"`
	MemberSince            pgtype.Timestamptz `json:"member_since"`
}

func (q *Queries) GetVolunteerStatistics(ctx context.Context, id int64) (GetVolunteerStatisticsRow, error) {
	row := q.db.QueryRow(ctx, GetVolunteerStatistics, id)
	var i GetVolunteerStatisticsRow
	err := row.Scan(
		&i.ID,
		&i.FirstName,
		&i.LastName,
		&i.VolunteerRating,
		&i.CompletedRequestsCount,
		&i.MemberSince,
	)
	return i, err
}

const SearchUsersByName = `-- name: SearchUsersByName :many
SELECT
    id,
    email,
    first_name,
    last_name,
    avatar_url,
    volunteer_rating,
    completed_requests_count,
    is_verified
FROM users
WHERE (first_name ILIKE '%' || $1 || '%' OR last_name ILIKE '%' || $1 || '%' OR (first_name || ' ' || last_name) ILIKE '%' || $1 || '%')
    AND deleted_at IS NULL
    AND is_blocked = FALSE
ORDER BY volunteer_rating DESC NULLS LAST
LIMIT $2 OFFSET $3
`

type SearchUsersByNameParams struct {
	Column1 pgtype.Text `json:"column_1"`
	Limit   int32       `json:"limit"`
	Offset  int32       `json:"offset"`
}

type SearchUsersByNameRow struct {
	ID                     int64          `json:"id"`
	Email                  string         `json:"email"`
	FirstName              string         `json:"first_name"`
	LastName               string         `json:"last_name"`
	AvatarUrl              pgtype.Text    `json:"avatar_url"`
	VolunteerRating        pgtype.Numeric `json:"volunteer_rating"`
	CompletedRequestsCount pgtype.Int4    `json:"completed_requests_count"`
	IsVerified             pgtype.Bool    `json:"is_verified"`
}

func (q *Queries) SearchUsersByName(ctx context.Context, arg SearchUsersByNameParams) ([]SearchUsersByNameRow, error) {
	rows, err := q.db.Query(ctx, SearchUsersByName, arg.Column1, arg.Limit, arg.Offset)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []SearchUsersByNameRow{}
	for rows.Next() {
		var i SearchUsersByNameRow
		if err := rows.Scan(
			&i.ID,
			&i.Email,
			&i.FirstName,
			&i.LastName,
			&i.AvatarUrl,
			&i.VolunteerRating,
			&i.CompletedRequestsCount,
			&i.IsVerified,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const SoftDeleteUser = `-- name: SoftDeleteUser :exec
UPDATE users SET
    deleted_at = CURRENT_TIMESTAMP,
    updated_at = CURRENT_TIMESTAMP
WHERE id = $1
`

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

const UnblockUser = `-- name: UnblockUser :exec
UPDATE users SET
    is_blocked = FALSE,
    updated_at = CURRENT_TIMESTAMP
WHERE id = $1
`

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

const UpdateUserLocation = `-- name: UpdateUserLocation :exec
UPDATE users SET
    location = ST_SetSRID(ST_MakePoint($2, $3), 4326)::geography,
    address = COALESCE($4, address),
    city = COALESCE($5, city),
    updated_at = CURRENT_TIMESTAMP
WHERE id = $1
`

type UpdateUserLocationParams struct {
	ID            int64       `json:"id"`
	StMakepoint   interface{} `json:"st_makepoint"`
	StMakepoint_2 interface{} `json:"st_makepoint_2"`
	Address       pgtype.Text `json:"address"`
	City          pgtype.Text `json:"city"`
}

func (q *Queries) UpdateUserLocation(ctx context.Context, arg UpdateUserLocationParams) error {
	_, err := q.db.Exec(ctx, UpdateUserLocation,
		arg.ID,
		arg.StMakepoint,
		arg.StMakepoint_2,
		arg.Address,
		arg.City,
	)
	return err
}

const UpdateUserPassword = `-- name: UpdateUserPassword :exec
UPDATE users SET
    password_hash = $2,
    updated_at = CURRENT_TIMESTAMP
WHERE id = $1
`

type UpdateUserPasswordParams struct {
	ID           int64  `json:"id"`
	PasswordHash string `json:"password_hash"`
}

func (q *Queries) UpdateUserPassword(ctx context.Context, arg UpdateUserPasswordParams) error {
	_, err := q.db.Exec(ctx, UpdateUserPassword, arg.ID, arg.PasswordHash)
	return err
}

const UpdateUserProfile = `-- name: UpdateUserProfile :exec
UPDATE users SET
    phone = COALESCE($1, phone),
    first_name = COALESCE($2, first_name),
    last_name = COALESCE($3, last_name),
    avatar_url = COALESCE($4, avatar_url),
    address = COALESCE($5, address),
    city = COALESCE($6, city),
    updated_at = CURRENT_TIMESTAMP
WHERE id = $7
`

type UpdateUserProfileParams struct {
	Phone     pgtype.Text `json:"phone"`
	FirstName pgtype.Text `json:"first_name"`
	LastName  pgtype.Text `json:"last_name"`
	AvatarUrl pgtype.Text `json:"avatar_url"`
	Address   pgtype.Text `json:"address"`
	City      pgtype.Text `json:"city"`
	UserID    int64       `json:"user_id"`
}

func (q *Queries) UpdateUserProfile(ctx context.Context, arg UpdateUserProfileParams) error {
	_, err := q.db.Exec(ctx, UpdateUserProfile,
		arg.Phone,
		arg.FirstName,
		arg.LastName,
		arg.AvatarUrl,
		arg.Address,
		arg.City,
		arg.UserID,
	)
	return err
}

const VerifyUserEmail = `-- name: VerifyUserEmail :exec
UPDATE users SET
    email_verified = TRUE,
    updated_at = CURRENT_TIMESTAMP
WHERE id = $1
`

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