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

package repository

import (
	"context"

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

const checkEventOverlap = `-- name: CheckEventOverlap :one
SELECT EXISTS(
    SELECT 1 FROM events
    WHERE calendar_id = $1
      AND deleted_at IS NULL
      AND start_time < $3
      AND end_time > $2
) AS overlap
`

type CheckEventOverlapParams struct {
	CalendarID pgtype.UUID        `json:"calendar_id"`
	EndTime    pgtype.Timestamptz `json:"end_time"`
	StartTime  pgtype.Timestamptz `json:"start_time"`
}

func (q *Queries) CheckEventOverlap(ctx context.Context, arg CheckEventOverlapParams) (bool, error) {
	row := q.db.QueryRow(ctx, checkEventOverlap, arg.CalendarID, arg.EndTime, arg.StartTime)
	var overlap bool
	err := row.Scan(&overlap)
	return overlap, err
}

const checkEventOverlapForUpdate = `-- name: CheckEventOverlapForUpdate :one
SELECT EXISTS(
    SELECT 1 FROM events
    WHERE calendar_id = $1
      AND deleted_at IS NULL
      AND start_time < $3
      AND end_time > $2
    FOR UPDATE
) AS overlap
`

type CheckEventOverlapForUpdateParams struct {
	CalendarID pgtype.UUID        `json:"calendar_id"`
	EndTime    pgtype.Timestamptz `json:"end_time"`
	StartTime  pgtype.Timestamptz `json:"start_time"`
}

func (q *Queries) CheckEventOverlapForUpdate(ctx context.Context, arg CheckEventOverlapForUpdateParams) (bool, error) {
	row := q.db.QueryRow(ctx, checkEventOverlapForUpdate, arg.CalendarID, arg.EndTime, arg.StartTime)
	var overlap bool
	err := row.Scan(&overlap)
	return overlap, err
}

const createEvent = `-- name: CreateEvent :one
INSERT INTO events (id, calendar_id, title, description, location, start_time, end_time, timezone, all_day, recurrence_rule, tags, created_by, updated_by)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)
RETURNING id, calendar_id, title, description, location, start_time, end_time, timezone, all_day, recurrence_rule, tags, created_by, updated_by, created_at, updated_at, deleted_at
`

type CreateEventParams struct {
	ID             pgtype.UUID        `json:"id"`
	CalendarID     pgtype.UUID        `json:"calendar_id"`
	Title          string             `json:"title"`
	Description    pgtype.Text        `json:"description"`
	Location       pgtype.Text        `json:"location"`
	StartTime      pgtype.Timestamptz `json:"start_time"`
	EndTime        pgtype.Timestamptz `json:"end_time"`
	Timezone       string             `json:"timezone"`
	AllDay         bool               `json:"all_day"`
	RecurrenceRule pgtype.Text        `json:"recurrence_rule"`
	Tags           []string           `json:"tags"`
	CreatedBy      pgtype.UUID        `json:"created_by"`
	UpdatedBy      pgtype.UUID        `json:"updated_by"`
}

func (q *Queries) CreateEvent(ctx context.Context, arg CreateEventParams) (Event, error) {
	row := q.db.QueryRow(ctx, createEvent,
		arg.ID,
		arg.CalendarID,
		arg.Title,
		arg.Description,
		arg.Location,
		arg.StartTime,
		arg.EndTime,
		arg.Timezone,
		arg.AllDay,
		arg.RecurrenceRule,
		arg.Tags,
		arg.CreatedBy,
		arg.UpdatedBy,
	)
	var i Event
	err := row.Scan(
		&i.ID,
		&i.CalendarID,
		&i.Title,
		&i.Description,
		&i.Location,
		&i.StartTime,
		&i.EndTime,
		&i.Timezone,
		&i.AllDay,
		&i.RecurrenceRule,
		&i.Tags,
		&i.CreatedBy,
		&i.UpdatedBy,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.DeletedAt,
	)
	return i, err
}

const getEventByID = `-- name: GetEventByID :one
SELECT id, calendar_id, title, description, location, start_time, end_time, timezone, all_day, recurrence_rule, tags, created_by, updated_by, created_at, updated_at, deleted_at FROM events
WHERE id = $1 AND deleted_at IS NULL
`

func (q *Queries) GetEventByID(ctx context.Context, id pgtype.UUID) (Event, error) {
	row := q.db.QueryRow(ctx, getEventByID, id)
	var i Event
	err := row.Scan(
		&i.ID,
		&i.CalendarID,
		&i.Title,
		&i.Description,
		&i.Location,
		&i.StartTime,
		&i.EndTime,
		&i.Timezone,
		&i.AllDay,
		&i.RecurrenceRule,
		&i.Tags,
		&i.CreatedBy,
		&i.UpdatedBy,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.DeletedAt,
	)
	return i, err
}

const listEventsByCalendarInRange = `-- name: ListEventsByCalendarInRange :many
SELECT id, calendar_id, title, description, location, start_time, end_time, timezone, all_day, recurrence_rule, tags, created_by, updated_by, created_at, updated_at, deleted_at FROM events
WHERE calendar_id = $1
  AND deleted_at IS NULL
  AND start_time < $3
  AND end_time > $2
ORDER BY start_time ASC
`

type ListEventsByCalendarInRangeParams struct {
	CalendarID pgtype.UUID        `json:"calendar_id"`
	EndTime    pgtype.Timestamptz `json:"end_time"`
	StartTime  pgtype.Timestamptz `json:"start_time"`
}

func (q *Queries) ListEventsByCalendarInRange(ctx context.Context, arg ListEventsByCalendarInRangeParams) ([]Event, error) {
	rows, err := q.db.Query(ctx, listEventsByCalendarInRange, arg.CalendarID, arg.EndTime, arg.StartTime)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []Event{}
	for rows.Next() {
		var i Event
		if err := rows.Scan(
			&i.ID,
			&i.CalendarID,
			&i.Title,
			&i.Description,
			&i.Location,
			&i.StartTime,
			&i.EndTime,
			&i.Timezone,
			&i.AllDay,
			&i.RecurrenceRule,
			&i.Tags,
			&i.CreatedBy,
			&i.UpdatedBy,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.DeletedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listEventsInRange = `-- name: ListEventsInRange :many
SELECT e.id, e.calendar_id, e.title, e.description, e.location, e.start_time, e.end_time, e.timezone, e.all_day, e.recurrence_rule, e.tags, e.created_by, e.updated_by, e.created_at, e.updated_at, e.deleted_at FROM events e
JOIN calendar_members cm ON cm.calendar_id = e.calendar_id
WHERE cm.user_id = $1
  AND e.deleted_at IS NULL
  AND e.start_time < $2
  AND e.end_time > $3
  AND ($4::UUID IS NULL OR e.calendar_id = $4::UUID)
  AND ($5::TEXT IS NULL OR (e.title ILIKE '%' || $5::TEXT || '%' OR e.description ILIKE '%' || $5::TEXT || '%'))
  AND ($6::TEXT IS NULL OR $6::TEXT = ANY(e.tags))
  AND (
    $7::TIMESTAMPTZ IS NULL
    OR (e.start_time, e.id) > ($7::TIMESTAMPTZ, $8::UUID)
  )
ORDER BY e.start_time ASC, e.id ASC
LIMIT $9
`

type ListEventsInRangeParams struct {
	UserID     pgtype.UUID        `json:"user_id"`
	RangeEnd   pgtype.Timestamptz `json:"range_end"`
	RangeStart pgtype.Timestamptz `json:"range_start"`
	CalendarID pgtype.UUID        `json:"calendar_id"`
	Search     pgtype.Text        `json:"search"`
	Tag        pgtype.Text        `json:"tag"`
	CursorTime pgtype.Timestamptz `json:"cursor_time"`
	CursorID   pgtype.UUID        `json:"cursor_id"`
	Lim        int32              `json:"lim"`
}

func (q *Queries) ListEventsInRange(ctx context.Context, arg ListEventsInRangeParams) ([]Event, error) {
	rows, err := q.db.Query(ctx, listEventsInRange,
		arg.UserID,
		arg.RangeEnd,
		arg.RangeStart,
		arg.CalendarID,
		arg.Search,
		arg.Tag,
		arg.CursorTime,
		arg.CursorID,
		arg.Lim,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []Event{}
	for rows.Next() {
		var i Event
		if err := rows.Scan(
			&i.ID,
			&i.CalendarID,
			&i.Title,
			&i.Description,
			&i.Location,
			&i.StartTime,
			&i.EndTime,
			&i.Timezone,
			&i.AllDay,
			&i.RecurrenceRule,
			&i.Tags,
			&i.CreatedBy,
			&i.UpdatedBy,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.DeletedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listRecurringEventsByCalendar = `-- name: ListRecurringEventsByCalendar :many
SELECT id, calendar_id, title, description, location, start_time, end_time, timezone, all_day, recurrence_rule, tags, created_by, updated_by, created_at, updated_at, deleted_at FROM events
WHERE calendar_id = $1
  AND deleted_at IS NULL
  AND recurrence_rule IS NOT NULL
  AND start_time <= $2
ORDER BY start_time ASC
`

type ListRecurringEventsByCalendarParams struct {
	CalendarID pgtype.UUID        `json:"calendar_id"`
	StartTime  pgtype.Timestamptz `json:"start_time"`
}

func (q *Queries) ListRecurringEventsByCalendar(ctx context.Context, arg ListRecurringEventsByCalendarParams) ([]Event, error) {
	rows, err := q.db.Query(ctx, listRecurringEventsByCalendar, arg.CalendarID, arg.StartTime)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []Event{}
	for rows.Next() {
		var i Event
		if err := rows.Scan(
			&i.ID,
			&i.CalendarID,
			&i.Title,
			&i.Description,
			&i.Location,
			&i.StartTime,
			&i.EndTime,
			&i.Timezone,
			&i.AllDay,
			&i.RecurrenceRule,
			&i.Tags,
			&i.CreatedBy,
			&i.UpdatedBy,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.DeletedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listRecurringEventsInRange = `-- name: ListRecurringEventsInRange :many
SELECT e.id, e.calendar_id, e.title, e.description, e.location, e.start_time, e.end_time, e.timezone, e.all_day, e.recurrence_rule, e.tags, e.created_by, e.updated_by, e.created_at, e.updated_at, e.deleted_at FROM events e
JOIN calendar_members cm ON cm.calendar_id = e.calendar_id
WHERE cm.user_id = $1
  AND e.deleted_at IS NULL
  AND e.recurrence_rule IS NOT NULL
  AND e.start_time <= $2
  AND ($3::UUID IS NULL OR e.calendar_id = $3::UUID)
ORDER BY e.start_time ASC
`

type ListRecurringEventsInRangeParams struct {
	UserID     pgtype.UUID        `json:"user_id"`
	RangeEnd   pgtype.Timestamptz `json:"range_end"`
	CalendarID pgtype.UUID        `json:"calendar_id"`
}

func (q *Queries) ListRecurringEventsInRange(ctx context.Context, arg ListRecurringEventsInRangeParams) ([]Event, error) {
	rows, err := q.db.Query(ctx, listRecurringEventsInRange, arg.UserID, arg.RangeEnd, arg.CalendarID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []Event{}
	for rows.Next() {
		var i Event
		if err := rows.Scan(
			&i.ID,
			&i.CalendarID,
			&i.Title,
			&i.Description,
			&i.Location,
			&i.StartTime,
			&i.EndTime,
			&i.Timezone,
			&i.AllDay,
			&i.RecurrenceRule,
			&i.Tags,
			&i.CreatedBy,
			&i.UpdatedBy,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.DeletedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const softDeleteEvent = `-- name: SoftDeleteEvent :exec
UPDATE events SET deleted_at = now(), updated_at = now()
WHERE id = $1 AND deleted_at IS NULL
`

func (q *Queries) SoftDeleteEvent(ctx context.Context, id pgtype.UUID) error {
	_, err := q.db.Exec(ctx, softDeleteEvent, id)
	return err
}

const softDeleteEventsByCalendar = `-- name: SoftDeleteEventsByCalendar :exec
UPDATE events SET deleted_at = now(), updated_at = now()
WHERE calendar_id = $1 AND deleted_at IS NULL
`

func (q *Queries) SoftDeleteEventsByCalendar(ctx context.Context, calendarID pgtype.UUID) error {
	_, err := q.db.Exec(ctx, softDeleteEventsByCalendar, calendarID)
	return err
}

const softDeleteEventsByCreator = `-- name: SoftDeleteEventsByCreator :exec
UPDATE events SET deleted_at = now(), updated_at = now()
WHERE created_by = $1 AND deleted_at IS NULL
`

func (q *Queries) SoftDeleteEventsByCreator(ctx context.Context, createdBy pgtype.UUID) error {
	_, err := q.db.Exec(ctx, softDeleteEventsByCreator, createdBy)
	return err
}

const updateEvent = `-- name: UpdateEvent :one
UPDATE events
SET title = COALESCE($1, title),
    description = COALESCE($2, description),
    location = COALESCE($3, location),
    start_time = COALESCE($4, start_time),
    end_time = COALESCE($5, end_time),
    timezone = COALESCE($6, timezone),
    all_day = COALESCE($7, all_day),
    recurrence_rule = $8,
    tags = COALESCE($9, tags),
    updated_by = $10,
    updated_at = now()
WHERE id = $11 AND deleted_at IS NULL
RETURNING id, calendar_id, title, description, location, start_time, end_time, timezone, all_day, recurrence_rule, tags, created_by, updated_by, created_at, updated_at, deleted_at
`

type UpdateEventParams struct {
	Title          pgtype.Text        `json:"title"`
	Description    pgtype.Text        `json:"description"`
	Location       pgtype.Text        `json:"location"`
	StartTime      pgtype.Timestamptz `json:"start_time"`
	EndTime        pgtype.Timestamptz `json:"end_time"`
	Timezone       pgtype.Text        `json:"timezone"`
	AllDay         pgtype.Bool        `json:"all_day"`
	RecurrenceRule pgtype.Text        `json:"recurrence_rule"`
	Tags           []string           `json:"tags"`
	UpdatedBy      pgtype.UUID        `json:"updated_by"`
	ID             pgtype.UUID        `json:"id"`
}

func (q *Queries) UpdateEvent(ctx context.Context, arg UpdateEventParams) (Event, error) {
	row := q.db.QueryRow(ctx, updateEvent,
		arg.Title,
		arg.Description,
		arg.Location,
		arg.StartTime,
		arg.EndTime,
		arg.Timezone,
		arg.AllDay,
		arg.RecurrenceRule,
		arg.Tags,
		arg.UpdatedBy,
		arg.ID,
	)
	var i Event
	err := row.Scan(
		&i.ID,
		&i.CalendarID,
		&i.Title,
		&i.Description,
		&i.Location,
		&i.StartTime,
		&i.EndTime,
		&i.Timezone,
		&i.AllDay,
		&i.RecurrenceRule,
		&i.Tags,
		&i.CreatedBy,
		&i.UpdatedBy,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.DeletedAt,
	)
	return i, err
}
