# Code generated by sqlc. DO NOT EDIT.
# versions:
#   sqlc v1.29.0
# source: user.sql
import datetime
from typing import Optional

import sqlalchemy
import sqlalchemy.ext.asyncio

from mcpuniverse.app.db.sqlc import models


CREATE_USER = """-- name: create_user \\:one
INSERT INTO "user" (username,
                    email,
                    hashed_password,
                    permission)
VALUES (:p1, :p2, :p3, :p4)
RETURNING id, username, email, hashed_password, permission, is_email_verified, password_changed_at, created_at, updated_at
"""


GET_USER_BY_EMAIL = """-- name: get_user_by_email \\:one
SELECT id, username, email, hashed_password, permission, is_email_verified, password_changed_at, created_at, updated_at
FROM "user"
WHERE email = :p1
LIMIT 1
"""


GET_USER_BY_ID = """-- name: get_user_by_id \\:one
SELECT id, username, email, hashed_password, permission, is_email_verified, password_changed_at, created_at, updated_at
FROM "user"
WHERE id = :p1
LIMIT 1
"""


GET_USER_BY_NAME = """-- name: get_user_by_name \\:one
SELECT id, username, email, hashed_password, permission, is_email_verified, password_changed_at, created_at, updated_at
FROM "user"
WHERE username = :p1
LIMIT 1
"""


UPDATE_USER = """-- name: update_user \\:one
UPDATE "user"
SET hashed_password     = COALESCE(:p1, hashed_password),
    password_changed_at = COALESCE(:p2, password_changed_at),
    email               = COALESCE(:p3, email),
    is_email_verified   = COALESCE(:p4, is_email_verified)
WHERE email = :p3
RETURNING id, username, email, hashed_password, permission, is_email_verified, password_changed_at, created_at, updated_at
"""


class Querier:
    def __init__(self, conn: sqlalchemy.engine.Connection):
        self._conn = conn

    def create_user(self, *, username: str, email: str, hashed_password: str, permission: models.UserPerm) -> Optional[models.User]:
        row = self._conn.execute(sqlalchemy.text(CREATE_USER), {
            "p1": username,
            "p2": email,
            "p3": hashed_password,
            "p4": permission,
        }).first()
        if row is None:
            return None
        return models.User(
            id=row[0],
            username=row[1],
            email=row[2],
            hashed_password=row[3],
            permission=row[4],
            is_email_verified=row[5],
            password_changed_at=row[6],
            created_at=row[7],
            updated_at=row[8],
        )

    def get_user_by_email(self, *, email: str) -> Optional[models.User]:
        row = self._conn.execute(sqlalchemy.text(GET_USER_BY_EMAIL), {"p1": email}).first()
        if row is None:
            return None
        return models.User(
            id=row[0],
            username=row[1],
            email=row[2],
            hashed_password=row[3],
            permission=row[4],
            is_email_verified=row[5],
            password_changed_at=row[6],
            created_at=row[7],
            updated_at=row[8],
        )

    def get_user_by_id(self, *, id: int) -> Optional[models.User]:
        row = self._conn.execute(sqlalchemy.text(GET_USER_BY_ID), {"p1": id}).first()
        if row is None:
            return None
        return models.User(
            id=row[0],
            username=row[1],
            email=row[2],
            hashed_password=row[3],
            permission=row[4],
            is_email_verified=row[5],
            password_changed_at=row[6],
            created_at=row[7],
            updated_at=row[8],
        )

    def get_user_by_name(self, *, username: str) -> Optional[models.User]:
        row = self._conn.execute(sqlalchemy.text(GET_USER_BY_NAME), {"p1": username}).first()
        if row is None:
            return None
        return models.User(
            id=row[0],
            username=row[1],
            email=row[2],
            hashed_password=row[3],
            permission=row[4],
            is_email_verified=row[5],
            password_changed_at=row[6],
            created_at=row[7],
            updated_at=row[8],
        )

    def update_user(self, *, hashed_password: Optional[str], password_changed_at: Optional[datetime.datetime], email: Optional[str], is_email_verified: Optional[bool]) -> Optional[models.User]:
        row = self._conn.execute(sqlalchemy.text(UPDATE_USER), {
            "p1": hashed_password,
            "p2": password_changed_at,
            "p3": email,
            "p4": is_email_verified,
        }).first()
        if row is None:
            return None
        return models.User(
            id=row[0],
            username=row[1],
            email=row[2],
            hashed_password=row[3],
            permission=row[4],
            is_email_verified=row[5],
            password_changed_at=row[6],
            created_at=row[7],
            updated_at=row[8],
        )


class AsyncQuerier:
    def __init__(self, conn: sqlalchemy.ext.asyncio.AsyncConnection):
        self._conn = conn

    async def create_user(self, *, username: str, email: str, hashed_password: str, permission: models.UserPerm) -> Optional[models.User]:
        row = (await self._conn.execute(sqlalchemy.text(CREATE_USER), {
            "p1": username,
            "p2": email,
            "p3": hashed_password,
            "p4": permission,
        })).first()
        if row is None:
            return None
        return models.User(
            id=row[0],
            username=row[1],
            email=row[2],
            hashed_password=row[3],
            permission=row[4],
            is_email_verified=row[5],
            password_changed_at=row[6],
            created_at=row[7],
            updated_at=row[8],
        )

    async def get_user_by_email(self, *, email: str) -> Optional[models.User]:
        row = (await self._conn.execute(sqlalchemy.text(GET_USER_BY_EMAIL), {"p1": email})).first()
        if row is None:
            return None
        return models.User(
            id=row[0],
            username=row[1],
            email=row[2],
            hashed_password=row[3],
            permission=row[4],
            is_email_verified=row[5],
            password_changed_at=row[6],
            created_at=row[7],
            updated_at=row[8],
        )

    async def get_user_by_id(self, *, id: int) -> Optional[models.User]:
        row = (await self._conn.execute(sqlalchemy.text(GET_USER_BY_ID), {"p1": id})).first()
        if row is None:
            return None
        return models.User(
            id=row[0],
            username=row[1],
            email=row[2],
            hashed_password=row[3],
            permission=row[4],
            is_email_verified=row[5],
            password_changed_at=row[6],
            created_at=row[7],
            updated_at=row[8],
        )

    async def get_user_by_name(self, *, username: str) -> Optional[models.User]:
        row = (await self._conn.execute(sqlalchemy.text(GET_USER_BY_NAME), {"p1": username})).first()
        if row is None:
            return None
        return models.User(
            id=row[0],
            username=row[1],
            email=row[2],
            hashed_password=row[3],
            permission=row[4],
            is_email_verified=row[5],
            password_changed_at=row[6],
            created_at=row[7],
            updated_at=row[8],
        )

    async def update_user(self, *, hashed_password: Optional[str], password_changed_at: Optional[datetime.datetime], email: Optional[str], is_email_verified: Optional[bool]) -> Optional[models.User]:
        row = (await self._conn.execute(sqlalchemy.text(UPDATE_USER), {
            "p1": hashed_password,
            "p2": password_changed_at,
            "p3": email,
            "p4": is_email_verified,
        })).first()
        if row is None:
            return None
        return models.User(
            id=row[0],
            username=row[1],
            email=row[2],
            hashed_password=row[3],
            permission=row[4],
            is_email_verified=row[5],
            password_changed_at=row[6],
            created_at=row[7],
            updated_at=row[8],
        )
