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

package db

import (
	"context"

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

const addStoreUser = `-- name: AddStoreUser :exec
INSERT INTO store_users (store_id, user_id, created_at)
VALUES ($1, $2, now())
ON CONFLICT DO NOTHING
`

type AddStoreUserParams struct {
	StoreID int64 `json:"store_id"`
	UserID  int64 `json:"user_id"`
}

func (q *Queries) AddStoreUser(ctx context.Context, arg AddStoreUserParams) error {
	_, err := q.db.Exec(ctx, addStoreUser, arg.StoreID, arg.UserID)
	return err
}

const createStore = `-- name: CreateStore :one
INSERT INTO stores (code, name, address, phone, is_active, warehouse_id, latitude, longitude, created_at, updated_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, now(), now())
RETURNING id, code, name, address, phone, is_active, warehouse_id, latitude, longitude, created_at, updated_at
`

type CreateStoreParams struct {
	Code        string              `json:"code"`
	Name        string              `json:"name"`
	Address     pgtype.Text         `json:"address"`
	Phone       pgtype.Text         `json:"phone"`
	IsActive    bool                `json:"is_active"`
	WarehouseID int64               `json:"warehouse_id"`
	Latitude    decimal.NullDecimal `json:"latitude"`
	Longitude   decimal.NullDecimal `json:"longitude"`
}

type CreateStoreRow struct {
	ID          int64               `json:"id"`
	Code        string              `json:"code"`
	Name        string              `json:"name"`
	Address     pgtype.Text         `json:"address"`
	Phone       pgtype.Text         `json:"phone"`
	IsActive    bool                `json:"is_active"`
	WarehouseID int64               `json:"warehouse_id"`
	Latitude    decimal.NullDecimal `json:"latitude"`
	Longitude   decimal.NullDecimal `json:"longitude"`
	CreatedAt   pgtype.Timestamptz  `json:"created_at"`
	UpdatedAt   pgtype.Timestamptz  `json:"updated_at"`
}

func (q *Queries) CreateStore(ctx context.Context, arg CreateStoreParams) (CreateStoreRow, error) {
	row := q.db.QueryRow(ctx, createStore,
		arg.Code,
		arg.Name,
		arg.Address,
		arg.Phone,
		arg.IsActive,
		arg.WarehouseID,
		arg.Latitude,
		arg.Longitude,
	)
	var i CreateStoreRow
	err := row.Scan(
		&i.ID,
		&i.Code,
		&i.Name,
		&i.Address,
		&i.Phone,
		&i.IsActive,
		&i.WarehouseID,
		&i.Latitude,
		&i.Longitude,
		&i.CreatedAt,
		&i.UpdatedAt,
	)
	return i, err
}

const deleteRolePermission = `-- name: DeleteRolePermission :execrows
DELETE FROM role_permissions WHERE role = $1 AND permission = $2
`

type DeleteRolePermissionParams struct {
	Role       string `json:"role"`
	Permission string `json:"permission"`
}

func (q *Queries) DeleteRolePermission(ctx context.Context, arg DeleteRolePermissionParams) (int64, error) {
	result, err := q.db.Exec(ctx, deleteRolePermission, arg.Role, arg.Permission)
	if err != nil {
		return 0, err
	}
	return result.RowsAffected(), nil
}

const deleteStore = `-- name: DeleteStore :execrows
DELETE FROM stores WHERE id = $1
`

func (q *Queries) DeleteStore(ctx context.Context, id int64) (int64, error) {
	result, err := q.db.Exec(ctx, deleteStore, id)
	if err != nil {
		return 0, err
	}
	return result.RowsAffected(), nil
}

const getStoreByID = `-- name: GetStoreByID :one
SELECT id, code, name, address, phone, is_active, warehouse_id, latitude, longitude, created_at, updated_at
FROM stores WHERE id = $1
`

type GetStoreByIDRow struct {
	ID          int64               `json:"id"`
	Code        string              `json:"code"`
	Name        string              `json:"name"`
	Address     pgtype.Text         `json:"address"`
	Phone       pgtype.Text         `json:"phone"`
	IsActive    bool                `json:"is_active"`
	WarehouseID int64               `json:"warehouse_id"`
	Latitude    decimal.NullDecimal `json:"latitude"`
	Longitude   decimal.NullDecimal `json:"longitude"`
	CreatedAt   pgtype.Timestamptz  `json:"created_at"`
	UpdatedAt   pgtype.Timestamptz  `json:"updated_at"`
}

func (q *Queries) GetStoreByID(ctx context.Context, id int64) (GetStoreByIDRow, error) {
	row := q.db.QueryRow(ctx, getStoreByID, id)
	var i GetStoreByIDRow
	err := row.Scan(
		&i.ID,
		&i.Code,
		&i.Name,
		&i.Address,
		&i.Phone,
		&i.IsActive,
		&i.WarehouseID,
		&i.Latitude,
		&i.Longitude,
		&i.CreatedAt,
		&i.UpdatedAt,
	)
	return i, err
}

const isStoreActive = `-- name: IsStoreActive :one
SELECT EXISTS (
  SELECT 1 FROM stores WHERE id = $1 AND is_active = true
)
`

func (q *Queries) IsStoreActive(ctx context.Context, id int64) (bool, error) {
	row := q.db.QueryRow(ctx, isStoreActive, id)
	var exists bool
	err := row.Scan(&exists)
	return exists, err
}

const isUserInActiveStore = `-- name: IsUserInActiveStore :one
SELECT EXISTS (
  SELECT 1 FROM store_users su
  JOIN stores s ON s.id = su.store_id
  WHERE su.user_id = $1 AND su.store_id = $2 AND s.is_active = true
)
`

type IsUserInActiveStoreParams struct {
	UserID  int64 `json:"user_id"`
	StoreID int64 `json:"store_id"`
}

func (q *Queries) IsUserInActiveStore(ctx context.Context, arg IsUserInActiveStoreParams) (bool, error) {
	row := q.db.QueryRow(ctx, isUserInActiveStore, arg.UserID, arg.StoreID)
	var exists bool
	err := row.Scan(&exists)
	return exists, err
}

const listRolePermissions = `-- name: ListRolePermissions :many
SELECT role, permission FROM role_permissions ORDER BY role, permission
`

type ListRolePermissionsRow struct {
	Role       string `json:"role"`
	Permission string `json:"permission"`
}

func (q *Queries) ListRolePermissions(ctx context.Context) ([]ListRolePermissionsRow, error) {
	rows, err := q.db.Query(ctx, listRolePermissions)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []ListRolePermissionsRow
	for rows.Next() {
		var i ListRolePermissionsRow
		if err := rows.Scan(&i.Role, &i.Permission); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listStoreLocations = `-- name: ListStoreLocations :many
SELECT id, code, name, is_active, latitude, longitude, coordinate_precision FROM stores ORDER BY id
`

type ListStoreLocationsRow struct {
	ID                  int64               `json:"id"`
	Code                string              `json:"code"`
	Name                string              `json:"name"`
	IsActive            bool                `json:"is_active"`
	Latitude            decimal.NullDecimal `json:"latitude"`
	Longitude           decimal.NullDecimal `json:"longitude"`
	CoordinatePrecision pgtype.Text         `json:"coordinate_precision"`
}

func (q *Queries) ListStoreLocations(ctx context.Context) ([]ListStoreLocationsRow, error) {
	rows, err := q.db.Query(ctx, listStoreLocations)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []ListStoreLocationsRow
	for rows.Next() {
		var i ListStoreLocationsRow
		if err := rows.Scan(
			&i.ID,
			&i.Code,
			&i.Name,
			&i.IsActive,
			&i.Latitude,
			&i.Longitude,
			&i.CoordinatePrecision,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listStoreUsers = `-- name: ListStoreUsers :many
SELECT su.store_id, su.user_id, su.created_at,
       u.name AS user_name, u.email AS user_email, u.role::text AS user_role
FROM store_users su
JOIN users u ON u.id = su.user_id
WHERE su.store_id = $1
ORDER BY su.created_at, su.user_id
`

type ListStoreUsersRow struct {
	StoreID   int64              `json:"store_id"`
	UserID    int64              `json:"user_id"`
	CreatedAt pgtype.Timestamptz `json:"created_at"`
	UserName  string             `json:"user_name"`
	UserEmail string             `json:"user_email"`
	UserRole  string             `json:"user_role"`
}

func (q *Queries) ListStoreUsers(ctx context.Context, storeID int64) ([]ListStoreUsersRow, error) {
	rows, err := q.db.Query(ctx, listStoreUsers, storeID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []ListStoreUsersRow
	for rows.Next() {
		var i ListStoreUsersRow
		if err := rows.Scan(
			&i.StoreID,
			&i.UserID,
			&i.CreatedAt,
			&i.UserName,
			&i.UserEmail,
			&i.UserRole,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listStores = `-- name: ListStores :many
SELECT id, code, name, address, phone, is_active, warehouse_id, latitude, longitude, location_note, created_at, updated_at
FROM stores ORDER BY id
`

type ListStoresRow struct {
	ID           int64               `json:"id"`
	Code         string              `json:"code"`
	Name         string              `json:"name"`
	Address      pgtype.Text         `json:"address"`
	Phone        pgtype.Text         `json:"phone"`
	IsActive     bool                `json:"is_active"`
	WarehouseID  int64               `json:"warehouse_id"`
	Latitude     decimal.NullDecimal `json:"latitude"`
	Longitude    decimal.NullDecimal `json:"longitude"`
	LocationNote pgtype.Text         `json:"location_note"`
	CreatedAt    pgtype.Timestamptz  `json:"created_at"`
	UpdatedAt    pgtype.Timestamptz  `json:"updated_at"`
}

func (q *Queries) ListStores(ctx context.Context) ([]ListStoresRow, error) {
	rows, err := q.db.Query(ctx, listStores)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []ListStoresRow
	for rows.Next() {
		var i ListStoresRow
		if err := rows.Scan(
			&i.ID,
			&i.Code,
			&i.Name,
			&i.Address,
			&i.Phone,
			&i.IsActive,
			&i.WarehouseID,
			&i.Latitude,
			&i.Longitude,
			&i.LocationNote,
			&i.CreatedAt,
			&i.UpdatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const removeStoreUser = `-- name: RemoveStoreUser :execrows
DELETE FROM store_users WHERE store_id = $1 AND user_id = $2
`

type RemoveStoreUserParams struct {
	StoreID int64 `json:"store_id"`
	UserID  int64 `json:"user_id"`
}

func (q *Queries) RemoveStoreUser(ctx context.Context, arg RemoveStoreUserParams) (int64, error) {
	result, err := q.db.Exec(ctx, removeStoreUser, arg.StoreID, arg.UserID)
	if err != nil {
		return 0, err
	}
	return result.RowsAffected(), nil
}

const storeDetailsForUser = `-- name: StoreDetailsForUser :many
SELECT s.id, s.code, s.name, s.address, s.phone, s.is_active, s.warehouse_id
FROM store_users su
JOIN stores s ON s.id = su.store_id
WHERE su.user_id = $1 AND s.is_active = true
ORDER BY s.id
`

type StoreDetailsForUserRow struct {
	ID          int64       `json:"id"`
	Code        string      `json:"code"`
	Name        string      `json:"name"`
	Address     pgtype.Text `json:"address"`
	Phone       pgtype.Text `json:"phone"`
	IsActive    bool        `json:"is_active"`
	WarehouseID int64       `json:"warehouse_id"`
}

func (q *Queries) StoreDetailsForUser(ctx context.Context, userID int64) ([]StoreDetailsForUserRow, error) {
	rows, err := q.db.Query(ctx, storeDetailsForUser, userID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []StoreDetailsForUserRow
	for rows.Next() {
		var i StoreDetailsForUserRow
		if err := rows.Scan(
			&i.ID,
			&i.Code,
			&i.Name,
			&i.Address,
			&i.Phone,
			&i.IsActive,
			&i.WarehouseID,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const storesForUser = `-- name: StoresForUser :many
SELECT su.store_id
FROM store_users su
JOIN stores s ON s.id = su.store_id
WHERE su.user_id = $1 AND s.is_active = true
ORDER BY su.store_id
`

func (q *Queries) StoresForUser(ctx context.Context, userID int64) ([]int64, error) {
	rows, err := q.db.Query(ctx, storesForUser, userID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []int64
	for rows.Next() {
		var store_id int64
		if err := rows.Scan(&store_id); err != nil {
			return nil, err
		}
		items = append(items, store_id)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const updateStore = `-- name: UpdateStore :one
UPDATE stores SET
  code = $2, name = $3, address = $4, phone = $5, is_active = $6, latitude = $7, longitude = $8, updated_at = now()
WHERE id = $1
RETURNING id, code, name, address, phone, is_active, warehouse_id, latitude, longitude, created_at, updated_at
`

type UpdateStoreParams struct {
	ID        int64               `json:"id"`
	Code      string              `json:"code"`
	Name      string              `json:"name"`
	Address   pgtype.Text         `json:"address"`
	Phone     pgtype.Text         `json:"phone"`
	IsActive  bool                `json:"is_active"`
	Latitude  decimal.NullDecimal `json:"latitude"`
	Longitude decimal.NullDecimal `json:"longitude"`
}

type UpdateStoreRow struct {
	ID          int64               `json:"id"`
	Code        string              `json:"code"`
	Name        string              `json:"name"`
	Address     pgtype.Text         `json:"address"`
	Phone       pgtype.Text         `json:"phone"`
	IsActive    bool                `json:"is_active"`
	WarehouseID int64               `json:"warehouse_id"`
	Latitude    decimal.NullDecimal `json:"latitude"`
	Longitude   decimal.NullDecimal `json:"longitude"`
	CreatedAt   pgtype.Timestamptz  `json:"created_at"`
	UpdatedAt   pgtype.Timestamptz  `json:"updated_at"`
}

func (q *Queries) UpdateStore(ctx context.Context, arg UpdateStoreParams) (UpdateStoreRow, error) {
	row := q.db.QueryRow(ctx, updateStore,
		arg.ID,
		arg.Code,
		arg.Name,
		arg.Address,
		arg.Phone,
		arg.IsActive,
		arg.Latitude,
		arg.Longitude,
	)
	var i UpdateStoreRow
	err := row.Scan(
		&i.ID,
		&i.Code,
		&i.Name,
		&i.Address,
		&i.Phone,
		&i.IsActive,
		&i.WarehouseID,
		&i.Latitude,
		&i.Longitude,
		&i.CreatedAt,
		&i.UpdatedAt,
	)
	return i, err
}

const upsertRolePermission = `-- name: UpsertRolePermission :exec
INSERT INTO role_permissions (role, permission) VALUES ($1, $2)
ON CONFLICT DO NOTHING
`

type UpsertRolePermissionParams struct {
	Role       string `json:"role"`
	Permission string `json:"permission"`
}

func (q *Queries) UpsertRolePermission(ctx context.Context, arg UpsertRolePermissionParams) error {
	_, err := q.db.Exec(ctx, upsertRolePermission, arg.Role, arg.Permission)
	return err
}

const warehouseForStore = `-- name: WarehouseForStore :one
SELECT warehouse_id FROM stores WHERE id = $1 AND is_active = true
`

func (q *Queries) WarehouseForStore(ctx context.Context, id int64) (int64, error) {
	row := q.db.QueryRow(ctx, warehouseForStore, id)
	var warehouse_id int64
	err := row.Scan(&warehouse_id)
	return warehouse_id, err
}

const warehousesForStores = `-- name: WarehousesForStores :many
SELECT DISTINCT warehouse_id FROM stores
WHERE id = ANY($1::bigint[])
ORDER BY warehouse_id
`

func (q *Queries) WarehousesForStores(ctx context.Context, dollar_1 []int64) ([]int64, error) {
	rows, err := q.db.Query(ctx, warehousesForStores, dollar_1)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []int64
	for rows.Next() {
		var warehouse_id int64
		if err := rows.Scan(&warehouse_id); err != nil {
			return nil, err
		}
		items = append(items, warehouse_id)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}
