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

package database

import (
	"context"

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

const ApproveRequest = `-- name: ApproveRequest :exec
UPDATE requests SET
    status = 'approved',
    moderated_by = $2,
    moderated_at = CURRENT_TIMESTAMP,
    moderation_comment = $3,
    updated_at = CURRENT_TIMESTAMP
WHERE id = $1
    AND status = 'pending_moderation'
    AND deleted_at IS NULL
`

type ApproveRequestParams struct {
	ID                int64       `json:"id"`
	ModeratedBy       pgtype.Int8 `json:"moderated_by"`
	ModerationComment pgtype.Text `json:"moderation_comment"`
}

func (q *Queries) ApproveRequest(ctx context.Context, arg ApproveRequestParams) error {
	_, err := q.db.Exec(ctx, ApproveRequest, arg.ID, arg.ModeratedBy, arg.ModerationComment)
	return err
}

const AssignVolunteerToRequest = `-- name: AssignVolunteerToRequest :exec
UPDATE requests SET
    assigned_volunteer_id = $2,
    status = 'in_progress',
    updated_at = CURRENT_TIMESTAMP
WHERE id = $1
    AND deleted_at IS NULL
`

type AssignVolunteerToRequestParams struct {
	ID                  int64       `json:"id"`
	AssignedVolunteerID pgtype.Int8 `json:"assigned_volunteer_id"`
}

func (q *Queries) AssignVolunteerToRequest(ctx context.Context, arg AssignVolunteerToRequestParams) error {
	_, err := q.db.Exec(ctx, AssignVolunteerToRequest, arg.ID, arg.AssignedVolunteerID)
	return err
}

const CancelRequest = `-- name: CancelRequest :exec
UPDATE requests SET
    status = 'cancelled',
    updated_at = CURRENT_TIMESTAMP
WHERE id = $1
    AND deleted_at IS NULL
`

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

const CompleteRequest = `-- name: CompleteRequest :exec
UPDATE requests SET
    status = 'completed',
    completed_at = CURRENT_TIMESTAMP,
    updated_at = CURRENT_TIMESTAMP
WHERE id = $1
    AND deleted_at IS NULL
`

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

const CountRequestsByRequester = `-- name: CountRequestsByRequester :one

SELECT COUNT(*) FROM requests
WHERE requester_id = $1
    AND deleted_at IS NULL
`

// ============================================================================
// Статистика
// ============================================================================
func (q *Queries) CountRequestsByRequester(ctx context.Context, requesterID int64) (int64, error) {
	row := q.db.QueryRow(ctx, CountRequestsByRequester, requesterID)
	var count int64
	err := row.Scan(&count)
	return count, err
}

const CountRequestsByStatus = `-- name: CountRequestsByStatus :one
SELECT COUNT(*) FROM requests
WHERE status = $1
    AND deleted_at IS NULL
`

func (q *Queries) CountRequestsByStatus(ctx context.Context, status NullRequestStatus) (int64, error) {
	row := q.db.QueryRow(ctx, CountRequestsByStatus, status)
	var count int64
	err := row.Scan(&count)
	return count, err
}

const CreateRequest = `-- name: CreateRequest :one


INSERT INTO requests (
    requester_id,
    request_type_id,
    title,
    description,
    location,
    address,
    city,
    desired_completion_date,
    urgency,
    contact_phone,
    contact_notes
) VALUES (
    $1,
    $2,
    $3,
    $4,
    ST_SetSRID(ST_MakePoint($5, $6), 4326)::geography,
    $7,
    $8,
    $9,
    $10,
    $11,
    $12
) RETURNING
    id,
    requester_id,
    request_type_id,
    title,
    description,
    ST_Y(location::geometry) as latitude,
    ST_X(location::geometry) as longitude,
    address,
    city,
    desired_completion_date,
    urgency,
    contact_phone,
    contact_notes,
    status,
    assigned_volunteer_id,
    created_at,
    updated_at,
    deleted_at
`

type CreateRequestParams struct {
	RequesterID           int64              `json:"requester_id"`
	RequestTypeID         int64              `json:"request_type_id"`
	Title                 string             `json:"title"`
	Description           string             `json:"description"`
	StMakepoint           interface{}        `json:"st_makepoint"`
	StMakepoint_2         interface{}        `json:"st_makepoint_2"`
	Address               string             `json:"address"`
	City                  pgtype.Text        `json:"city"`
	DesiredCompletionDate pgtype.Timestamptz `json:"desired_completion_date"`
	Urgency               pgtype.Text        `json:"urgency"`
	ContactPhone          pgtype.Text        `json:"contact_phone"`
	ContactNotes          pgtype.Text        `json:"contact_notes"`
}

type CreateRequestRow struct {
	ID                    int64              `json:"id"`
	RequesterID           int64              `json:"requester_id"`
	RequestTypeID         int64              `json:"request_type_id"`
	Title                 string             `json:"title"`
	Description           string             `json:"description"`
	Latitude              interface{}        `json:"latitude"`
	Longitude             interface{}        `json:"longitude"`
	Address               string             `json:"address"`
	City                  pgtype.Text        `json:"city"`
	DesiredCompletionDate pgtype.Timestamptz `json:"desired_completion_date"`
	Urgency               pgtype.Text        `json:"urgency"`
	ContactPhone          pgtype.Text        `json:"contact_phone"`
	ContactNotes          pgtype.Text        `json:"contact_notes"`
	Status                NullRequestStatus  `json:"status"`
	AssignedVolunteerID   pgtype.Int8        `json:"assigned_volunteer_id"`
	CreatedAt             pgtype.Timestamptz `json:"created_at"`
	UpdatedAt             pgtype.Timestamptz `json:"updated_at"`
	DeletedAt             pgtype.Timestamptz `json:"deleted_at"`
}

// Фаза 2A: Управление заявками (ВЫСОКИЙ ПРИОРИТЕТ)
// CRUD операции для заявок на помощь
// ============================================================================
// Создание и получение заявок
// ============================================================================
func (q *Queries) CreateRequest(ctx context.Context, arg CreateRequestParams) (CreateRequestRow, error) {
	row := q.db.QueryRow(ctx, CreateRequest,
		arg.RequesterID,
		arg.RequestTypeID,
		arg.Title,
		arg.Description,
		arg.StMakepoint,
		arg.StMakepoint_2,
		arg.Address,
		arg.City,
		arg.DesiredCompletionDate,
		arg.Urgency,
		arg.ContactPhone,
		arg.ContactNotes,
	)
	var i CreateRequestRow
	err := row.Scan(
		&i.ID,
		&i.RequesterID,
		&i.RequestTypeID,
		&i.Title,
		&i.Description,
		&i.Latitude,
		&i.Longitude,
		&i.Address,
		&i.City,
		&i.DesiredCompletionDate,
		&i.Urgency,
		&i.ContactPhone,
		&i.ContactNotes,
		&i.Status,
		&i.AssignedVolunteerID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.DeletedAt,
	)
	return i, err
}

const DeleteRequest = `-- name: DeleteRequest :exec

UPDATE requests SET
    deleted_at = CURRENT_TIMESTAMP,
    updated_at = CURRENT_TIMESTAMP
WHERE id = $1
    AND requester_id = $2
    AND deleted_at IS NULL
`

type DeleteRequestParams struct {
	ID          int64 `json:"id"`
	RequesterID int64 `json:"requester_id"`
}

// ============================================================================
// Удаление заявок
// ============================================================================
func (q *Queries) DeleteRequest(ctx context.Context, arg DeleteRequestParams) error {
	_, err := q.db.Exec(ctx, DeleteRequest, arg.ID, arg.RequesterID)
	return err
}

const GetModeratedRequests = `-- name: GetModeratedRequests :many
SELECT
    r.id,
    r.requester_id,
    r.request_type_id,
    r.title,
    r.description,
    ST_Y(r.location::geometry) as latitude,
    ST_X(r.location::geometry) as longitude,
    r.address,
    r.status,
    r.moderated_by,
    r.moderated_at,
    r.moderation_comment,
    r.created_at,
    rt.name as request_type_name,
    (u.first_name || ' ' || u.last_name) as requester_name,
    (m.first_name || ' ' || m.last_name) as moderator_name
FROM requests r
JOIN request_types rt ON rt.id = r.request_type_id
JOIN users u ON u.id = r.requester_id
LEFT JOIN users m ON m.id = r.moderated_by
WHERE r.moderated_by = $1
    AND r.deleted_at IS NULL
ORDER BY r.moderated_at DESC
LIMIT $2 OFFSET $3
`

type GetModeratedRequestsParams struct {
	ModeratedBy pgtype.Int8 `json:"moderated_by"`
	Limit       int32       `json:"limit"`
	Offset      int32       `json:"offset"`
}

type GetModeratedRequestsRow struct {
	ID                int64              `json:"id"`
	RequesterID       int64              `json:"requester_id"`
	RequestTypeID     int64              `json:"request_type_id"`
	Title             string             `json:"title"`
	Description       string             `json:"description"`
	Latitude          interface{}        `json:"latitude"`
	Longitude         interface{}        `json:"longitude"`
	Address           string             `json:"address"`
	Status            NullRequestStatus  `json:"status"`
	ModeratedBy       pgtype.Int8        `json:"moderated_by"`
	ModeratedAt       pgtype.Timestamptz `json:"moderated_at"`
	ModerationComment pgtype.Text        `json:"moderation_comment"`
	CreatedAt         pgtype.Timestamptz `json:"created_at"`
	RequestTypeName   string             `json:"request_type_name"`
	RequesterName     interface{}        `json:"requester_name"`
	ModeratorName     interface{}        `json:"moderator_name"`
}

func (q *Queries) GetModeratedRequests(ctx context.Context, arg GetModeratedRequestsParams) ([]GetModeratedRequestsRow, error) {
	rows, err := q.db.Query(ctx, GetModeratedRequests, arg.ModeratedBy, arg.Limit, arg.Offset)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []GetModeratedRequestsRow{}
	for rows.Next() {
		var i GetModeratedRequestsRow
		if err := rows.Scan(
			&i.ID,
			&i.RequesterID,
			&i.RequestTypeID,
			&i.Title,
			&i.Description,
			&i.Latitude,
			&i.Longitude,
			&i.Address,
			&i.Status,
			&i.ModeratedBy,
			&i.ModeratedAt,
			&i.ModerationComment,
			&i.CreatedAt,
			&i.RequestTypeName,
			&i.RequesterName,
			&i.ModeratorName,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const GetModeratorActionsByModerator = `-- name: GetModeratorActionsByModerator :many
SELECT
    ma.id, ma.moderator_id, ma.action_type, ma.target_user_id, ma.target_request_id, ma.target_complaint_id, ma.comment, ma.metadata, ma.created_at,
    r.title as request_title,
    r.status as request_status
FROM moderator_actions ma
LEFT JOIN requests r ON r.id = ma.target_request_id
WHERE ma.moderator_id = $1
ORDER BY ma.created_at DESC
LIMIT $2 OFFSET $3
`

type GetModeratorActionsByModeratorParams struct {
	ModeratorID int64 `json:"moderator_id"`
	Limit       int32 `json:"limit"`
	Offset      int32 `json:"offset"`
}

type GetModeratorActionsByModeratorRow struct {
	ID                int64               `json:"id"`
	ModeratorID       int64               `json:"moderator_id"`
	ActionType        ModeratorActionType `json:"action_type"`
	TargetUserID      pgtype.Int8         `json:"target_user_id"`
	TargetRequestID   pgtype.Int8         `json:"target_request_id"`
	TargetComplaintID pgtype.Int8         `json:"target_complaint_id"`
	Comment           pgtype.Text         `json:"comment"`
	Metadata          []byte              `json:"metadata"`
	CreatedAt         pgtype.Timestamptz  `json:"created_at"`
	RequestTitle      pgtype.Text         `json:"request_title"`
	RequestStatus     NullRequestStatus   `json:"request_status"`
}

func (q *Queries) GetModeratorActionsByModerator(ctx context.Context, arg GetModeratorActionsByModeratorParams) ([]GetModeratorActionsByModeratorRow, error) {
	rows, err := q.db.Query(ctx, GetModeratorActionsByModerator, arg.ModeratorID, arg.Limit, arg.Offset)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []GetModeratorActionsByModeratorRow{}
	for rows.Next() {
		var i GetModeratorActionsByModeratorRow
		if err := rows.Scan(
			&i.ID,
			&i.ModeratorID,
			&i.ActionType,
			&i.TargetUserID,
			&i.TargetRequestID,
			&i.TargetComplaintID,
			&i.Comment,
			&i.Metadata,
			&i.CreatedAt,
			&i.RequestTitle,
			&i.RequestStatus,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const GetModeratorActionsByRequest = `-- name: GetModeratorActionsByRequest :many

SELECT
    ma.id, ma.moderator_id, ma.action_type, ma.target_user_id, ma.target_request_id, ma.target_complaint_id, ma.comment, ma.metadata, ma.created_at,
    (u.first_name || ' ' || u.last_name) as moderator_name,
    u.email as moderator_email
FROM moderator_actions ma
JOIN users u ON u.id = ma.moderator_id
WHERE ma.target_request_id = $1
ORDER BY ma.created_at DESC
`

type GetModeratorActionsByRequestRow struct {
	ID                int64               `json:"id"`
	ModeratorID       int64               `json:"moderator_id"`
	ActionType        ModeratorActionType `json:"action_type"`
	TargetUserID      pgtype.Int8         `json:"target_user_id"`
	TargetRequestID   pgtype.Int8         `json:"target_request_id"`
	TargetComplaintID pgtype.Int8         `json:"target_complaint_id"`
	Comment           pgtype.Text         `json:"comment"`
	Metadata          []byte              `json:"metadata"`
	CreatedAt         pgtype.Timestamptz  `json:"created_at"`
	ModeratorName     interface{}         `json:"moderator_name"`
	ModeratorEmail    string              `json:"moderator_email"`
}

// ============================================================================
// Аудит действий модераторов
// ============================================================================
func (q *Queries) GetModeratorActionsByRequest(ctx context.Context, targetRequestID pgtype.Int8) ([]GetModeratorActionsByRequestRow, error) {
	rows, err := q.db.Query(ctx, GetModeratorActionsByRequest, targetRequestID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []GetModeratorActionsByRequestRow{}
	for rows.Next() {
		var i GetModeratorActionsByRequestRow
		if err := rows.Scan(
			&i.ID,
			&i.ModeratorID,
			&i.ActionType,
			&i.TargetUserID,
			&i.TargetRequestID,
			&i.TargetComplaintID,
			&i.Comment,
			&i.Metadata,
			&i.CreatedAt,
			&i.ModeratorName,
			&i.ModeratorEmail,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const GetPendingModerationRequests = `-- name: GetPendingModerationRequests :many

SELECT
    r.id,
    r.requester_id,
    r.request_type_id,
    r.title,
    r.description,
    ST_Y(r.location::geometry) as latitude,
    ST_X(r.location::geometry) as longitude,
    r.address,
    r.city,
    r.desired_completion_date,
    r.urgency,
    r.contact_phone,
    r.contact_notes,
    r.status,
    r.created_at,
    r.updated_at,
    rt.name as request_type_name,
    rt.icon as request_type_icon,
    (u.first_name || ' ' || u.last_name) as requester_name,
    u.email as requester_email,
    u.phone as requester_phone
FROM requests r
JOIN request_types rt ON rt.id = r.request_type_id
JOIN users u ON u.id = r.requester_id
WHERE r.status = 'pending_moderation'
    AND r.deleted_at IS NULL
ORDER BY r.created_at ASC
LIMIT $1 OFFSET $2
`

type GetPendingModerationRequestsParams struct {
	Limit  int32 `json:"limit"`
	Offset int32 `json:"offset"`
}

type GetPendingModerationRequestsRow struct {
	ID                    int64              `json:"id"`
	RequesterID           int64              `json:"requester_id"`
	RequestTypeID         int64              `json:"request_type_id"`
	Title                 string             `json:"title"`
	Description           string             `json:"description"`
	Latitude              interface{}        `json:"latitude"`
	Longitude             interface{}        `json:"longitude"`
	Address               string             `json:"address"`
	City                  pgtype.Text        `json:"city"`
	DesiredCompletionDate pgtype.Timestamptz `json:"desired_completion_date"`
	Urgency               pgtype.Text        `json:"urgency"`
	ContactPhone          pgtype.Text        `json:"contact_phone"`
	ContactNotes          pgtype.Text        `json:"contact_notes"`
	Status                NullRequestStatus  `json:"status"`
	CreatedAt             pgtype.Timestamptz `json:"created_at"`
	UpdatedAt             pgtype.Timestamptz `json:"updated_at"`
	RequestTypeName       string             `json:"request_type_name"`
	RequestTypeIcon       pgtype.Text        `json:"request_type_icon"`
	RequesterName         interface{}        `json:"requester_name"`
	RequesterEmail        string             `json:"requester_email"`
	RequesterPhone        pgtype.Text        `json:"requester_phone"`
}

// ============================================================================
// Модерация заявок
// ============================================================================
func (q *Queries) GetPendingModerationRequests(ctx context.Context, arg GetPendingModerationRequestsParams) ([]GetPendingModerationRequestsRow, error) {
	rows, err := q.db.Query(ctx, GetPendingModerationRequests, arg.Limit, arg.Offset)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []GetPendingModerationRequestsRow{}
	for rows.Next() {
		var i GetPendingModerationRequestsRow
		if err := rows.Scan(
			&i.ID,
			&i.RequesterID,
			&i.RequestTypeID,
			&i.Title,
			&i.Description,
			&i.Latitude,
			&i.Longitude,
			&i.Address,
			&i.City,
			&i.DesiredCompletionDate,
			&i.Urgency,
			&i.ContactPhone,
			&i.ContactNotes,
			&i.Status,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.RequestTypeName,
			&i.RequestTypeIcon,
			&i.RequesterName,
			&i.RequesterEmail,
			&i.RequesterPhone,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const GetRequestByID = `-- name: GetRequestByID :one
SELECT
    r.id,
    r.requester_id,
    r.request_type_id,
    r.title,
    r.description,
    ST_Y(r.location::geometry) as latitude,
    ST_X(r.location::geometry) as longitude,
    r.address,
    r.city,
    r.desired_completion_date,
    r.urgency,
    r.contact_phone,
    r.contact_notes,
    r.status,
    r.assigned_volunteer_id,
    r.created_at,
    r.updated_at,
    r.deleted_at,
    r.completed_at,
    rt.name as request_type_name,
    rt.icon as request_type_icon,
    (u.first_name || ' ' || u.last_name) as requester_name,
    u.phone as requester_phone,
    u.email as requester_email,
    (av.first_name || ' ' || av.last_name) as assigned_volunteer_name,
    av.phone as assigned_volunteer_phone
FROM requests r
JOIN request_types rt ON rt.id = r.request_type_id
JOIN users u ON u.id = r.requester_id
LEFT JOIN users av ON av.id = r.assigned_volunteer_id
WHERE r.id = $1 AND r.deleted_at IS NULL
`

type GetRequestByIDRow struct {
	ID                     int64              `json:"id"`
	RequesterID            int64              `json:"requester_id"`
	RequestTypeID          int64              `json:"request_type_id"`
	Title                  string             `json:"title"`
	Description            string             `json:"description"`
	Latitude               interface{}        `json:"latitude"`
	Longitude              interface{}        `json:"longitude"`
	Address                string             `json:"address"`
	City                   pgtype.Text        `json:"city"`
	DesiredCompletionDate  pgtype.Timestamptz `json:"desired_completion_date"`
	Urgency                pgtype.Text        `json:"urgency"`
	ContactPhone           pgtype.Text        `json:"contact_phone"`
	ContactNotes           pgtype.Text        `json:"contact_notes"`
	Status                 NullRequestStatus  `json:"status"`
	AssignedVolunteerID    pgtype.Int8        `json:"assigned_volunteer_id"`
	CreatedAt              pgtype.Timestamptz `json:"created_at"`
	UpdatedAt              pgtype.Timestamptz `json:"updated_at"`
	DeletedAt              pgtype.Timestamptz `json:"deleted_at"`
	CompletedAt            pgtype.Timestamptz `json:"completed_at"`
	RequestTypeName        string             `json:"request_type_name"`
	RequestTypeIcon        pgtype.Text        `json:"request_type_icon"`
	RequesterName          interface{}        `json:"requester_name"`
	RequesterPhone         pgtype.Text        `json:"requester_phone"`
	RequesterEmail         string             `json:"requester_email"`
	AssignedVolunteerName  interface{}        `json:"assigned_volunteer_name"`
	AssignedVolunteerPhone pgtype.Text        `json:"assigned_volunteer_phone"`
}

func (q *Queries) GetRequestByID(ctx context.Context, id int64) (GetRequestByIDRow, error) {
	row := q.db.QueryRow(ctx, GetRequestByID, id)
	var i GetRequestByIDRow
	err := row.Scan(
		&i.ID,
		&i.RequesterID,
		&i.RequestTypeID,
		&i.Title,
		&i.Description,
		&i.Latitude,
		&i.Longitude,
		&i.Address,
		&i.City,
		&i.DesiredCompletionDate,
		&i.Urgency,
		&i.ContactPhone,
		&i.ContactNotes,
		&i.Status,
		&i.AssignedVolunteerID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.DeletedAt,
		&i.CompletedAt,
		&i.RequestTypeName,
		&i.RequestTypeIcon,
		&i.RequesterName,
		&i.RequesterPhone,
		&i.RequesterEmail,
		&i.AssignedVolunteerName,
		&i.AssignedVolunteerPhone,
	)
	return i, err
}

const GetRequestTypeByID = `-- name: GetRequestTypeByID :one
SELECT id, name, description, icon, is_active, created_at FROM request_types
WHERE id = $1
`

func (q *Queries) GetRequestTypeByID(ctx context.Context, id int64) (RequestType, error) {
	row := q.db.QueryRow(ctx, GetRequestTypeByID, id)
	var i RequestType
	err := row.Scan(
		&i.ID,
		&i.Name,
		&i.Description,
		&i.Icon,
		&i.IsActive,
		&i.CreatedAt,
	)
	return i, err
}

const GetRequestTypeByName = `-- name: GetRequestTypeByName :one
SELECT id, name, description, icon, is_active, created_at FROM request_types
WHERE name = $1
`

func (q *Queries) GetRequestTypeByName(ctx context.Context, name string) (RequestType, error) {
	row := q.db.QueryRow(ctx, GetRequestTypeByName, name)
	var i RequestType
	err := row.Scan(
		&i.ID,
		&i.Name,
		&i.Description,
		&i.Icon,
		&i.IsActive,
		&i.CreatedAt,
	)
	return i, err
}

const GetRequestsByRequester = `-- name: GetRequestsByRequester :many
SELECT
    r.id,
    r.requester_id,
    r.request_type_id,
    r.title,
    r.description,
    ST_Y(r.location::geometry) as latitude,
    ST_X(r.location::geometry) as longitude,
    r.address,
    r.city,
    r.desired_completion_date,
    r.urgency,
    r.contact_phone,
    r.contact_notes,
    r.status,
    r.assigned_volunteer_id,
    r.created_at,
    r.updated_at,
    r.deleted_at,
    rt.name as request_type_name,
    rt.icon as request_type_icon
FROM requests r
JOIN request_types rt ON rt.id = r.request_type_id
WHERE r.requester_id = $1
    AND r.deleted_at IS NULL
ORDER BY r.created_at DESC
LIMIT $2 OFFSET $3
`

type GetRequestsByRequesterParams struct {
	RequesterID int64 `json:"requester_id"`
	Limit       int32 `json:"limit"`
	Offset      int32 `json:"offset"`
}

type GetRequestsByRequesterRow struct {
	ID                    int64              `json:"id"`
	RequesterID           int64              `json:"requester_id"`
	RequestTypeID         int64              `json:"request_type_id"`
	Title                 string             `json:"title"`
	Description           string             `json:"description"`
	Latitude              interface{}        `json:"latitude"`
	Longitude             interface{}        `json:"longitude"`
	Address               string             `json:"address"`
	City                  pgtype.Text        `json:"city"`
	DesiredCompletionDate pgtype.Timestamptz `json:"desired_completion_date"`
	Urgency               pgtype.Text        `json:"urgency"`
	ContactPhone          pgtype.Text        `json:"contact_phone"`
	ContactNotes          pgtype.Text        `json:"contact_notes"`
	Status                NullRequestStatus  `json:"status"`
	AssignedVolunteerID   pgtype.Int8        `json:"assigned_volunteer_id"`
	CreatedAt             pgtype.Timestamptz `json:"created_at"`
	UpdatedAt             pgtype.Timestamptz `json:"updated_at"`
	DeletedAt             pgtype.Timestamptz `json:"deleted_at"`
	RequestTypeName       string             `json:"request_type_name"`
	RequestTypeIcon       pgtype.Text        `json:"request_type_icon"`
}

func (q *Queries) GetRequestsByRequester(ctx context.Context, arg GetRequestsByRequesterParams) ([]GetRequestsByRequesterRow, error) {
	rows, err := q.db.Query(ctx, GetRequestsByRequester, arg.RequesterID, arg.Limit, arg.Offset)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []GetRequestsByRequesterRow{}
	for rows.Next() {
		var i GetRequestsByRequesterRow
		if err := rows.Scan(
			&i.ID,
			&i.RequesterID,
			&i.RequestTypeID,
			&i.Title,
			&i.Description,
			&i.Latitude,
			&i.Longitude,
			&i.Address,
			&i.City,
			&i.DesiredCompletionDate,
			&i.Urgency,
			&i.ContactPhone,
			&i.ContactNotes,
			&i.Status,
			&i.AssignedVolunteerID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.DeletedAt,
			&i.RequestTypeName,
			&i.RequestTypeIcon,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const GetRequestsByStatus = `-- name: GetRequestsByStatus :many
SELECT
    r.id,
    r.requester_id,
    r.request_type_id,
    r.title,
    r.description,
    ST_Y(r.location::geometry) as latitude,
    ST_X(r.location::geometry) as longitude,
    r.address,
    r.city,
    r.desired_completion_date,
    r.urgency,
    r.contact_phone,
    r.contact_notes,
    r.status,
    r.assigned_volunteer_id,
    r.created_at,
    r.updated_at,
    r.deleted_at,
    rt.name as request_type_name,
    (u.first_name || ' ' || u.last_name) as requester_name
FROM requests r
JOIN request_types rt ON rt.id = r.request_type_id
JOIN users u ON u.id = r.requester_id
WHERE r.status = $1
    AND r.deleted_at IS NULL
ORDER BY r.created_at DESC
LIMIT $2 OFFSET $3
`

type GetRequestsByStatusParams struct {
	Status NullRequestStatus `json:"status"`
	Limit  int32             `json:"limit"`
	Offset int32             `json:"offset"`
}

type GetRequestsByStatusRow struct {
	ID                    int64              `json:"id"`
	RequesterID           int64              `json:"requester_id"`
	RequestTypeID         int64              `json:"request_type_id"`
	Title                 string             `json:"title"`
	Description           string             `json:"description"`
	Latitude              interface{}        `json:"latitude"`
	Longitude             interface{}        `json:"longitude"`
	Address               string             `json:"address"`
	City                  pgtype.Text        `json:"city"`
	DesiredCompletionDate pgtype.Timestamptz `json:"desired_completion_date"`
	Urgency               pgtype.Text        `json:"urgency"`
	ContactPhone          pgtype.Text        `json:"contact_phone"`
	ContactNotes          pgtype.Text        `json:"contact_notes"`
	Status                NullRequestStatus  `json:"status"`
	AssignedVolunteerID   pgtype.Int8        `json:"assigned_volunteer_id"`
	CreatedAt             pgtype.Timestamptz `json:"created_at"`
	UpdatedAt             pgtype.Timestamptz `json:"updated_at"`
	DeletedAt             pgtype.Timestamptz `json:"deleted_at"`
	RequestTypeName       string             `json:"request_type_name"`
	RequesterName         interface{}        `json:"requester_name"`
}

func (q *Queries) GetRequestsByStatus(ctx context.Context, arg GetRequestsByStatusParams) ([]GetRequestsByStatusRow, error) {
	rows, err := q.db.Query(ctx, GetRequestsByStatus, arg.Status, arg.Limit, arg.Offset)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []GetRequestsByStatusRow{}
	for rows.Next() {
		var i GetRequestsByStatusRow
		if err := rows.Scan(
			&i.ID,
			&i.RequesterID,
			&i.RequestTypeID,
			&i.Title,
			&i.Description,
			&i.Latitude,
			&i.Longitude,
			&i.Address,
			&i.City,
			&i.DesiredCompletionDate,
			&i.Urgency,
			&i.ContactPhone,
			&i.ContactNotes,
			&i.Status,
			&i.AssignedVolunteerID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.DeletedAt,
			&i.RequestTypeName,
			&i.RequesterName,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const ListRequestTypes = `-- name: ListRequestTypes :many

SELECT id, name, description, icon, is_active, created_at FROM request_types
WHERE is_active = TRUE
ORDER BY name
`

// ============================================================================
// Типы заявок
// ============================================================================
func (q *Queries) ListRequestTypes(ctx context.Context) ([]RequestType, error) {
	rows, err := q.db.Query(ctx, ListRequestTypes)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []RequestType{}
	for rows.Next() {
		var i RequestType
		if err := rows.Scan(
			&i.ID,
			&i.Name,
			&i.Description,
			&i.Icon,
			&i.IsActive,
			&i.CreatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const ModerateRequest = `-- name: ModerateRequest :exec
UPDATE requests SET
    status = $2,
    moderated_by = $3,
    moderated_at = CURRENT_TIMESTAMP,
    moderation_comment = $4,
    updated_at = CURRENT_TIMESTAMP
WHERE id = $1
`

type ModerateRequestParams struct {
	ID                int64             `json:"id"`
	Status            NullRequestStatus `json:"status"`
	ModeratedBy       pgtype.Int8       `json:"moderated_by"`
	ModerationComment pgtype.Text       `json:"moderation_comment"`
}

func (q *Queries) ModerateRequest(ctx context.Context, arg ModerateRequestParams) error {
	_, err := q.db.Exec(ctx, ModerateRequest,
		arg.ID,
		arg.Status,
		arg.ModeratedBy,
		arg.ModerationComment,
	)
	return err
}

const RejectRequest = `-- name: RejectRequest :exec
UPDATE requests SET
    status = 'rejected',
    moderated_by = $2,
    moderated_at = CURRENT_TIMESTAMP,
    moderation_comment = $3,
    updated_at = CURRENT_TIMESTAMP
WHERE id = $1
    AND status = 'pending_moderation'
    AND deleted_at IS NULL
`

type RejectRequestParams struct {
	ID                int64       `json:"id"`
	ModeratedBy       pgtype.Int8 `json:"moderated_by"`
	ModerationComment pgtype.Text `json:"moderation_comment"`
}

func (q *Queries) RejectRequest(ctx context.Context, arg RejectRequestParams) error {
	_, err := q.db.Exec(ctx, RejectRequest, arg.ID, arg.ModeratedBy, arg.ModerationComment)
	return err
}

const UpdateRequestStatus = `-- name: UpdateRequestStatus :exec

UPDATE requests SET
    status = $2,
    updated_at = CURRENT_TIMESTAMP
WHERE id = $1
    AND deleted_at IS NULL
`

type UpdateRequestStatusParams struct {
	ID     int64             `json:"id"`
	Status NullRequestStatus `json:"status"`
}

// ============================================================================
// Обновление заявок
// ============================================================================
func (q *Queries) UpdateRequestStatus(ctx context.Context, arg UpdateRequestStatusParams) error {
	_, err := q.db.Exec(ctx, UpdateRequestStatus, arg.ID, arg.Status)
	return err
}
