# app/crud.py
import datetime, time
from typing import Optional, Type, TypeVar
from pydantic import BaseModel
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.future import select
from sqlalchemy.orm import declarative_base

# NOTE: Base is a declarative base for the ORM models
Base = declarative_base()
BaseModelType = TypeVar("BaseModelType", bound=Base)

async def get_by_unique_id(db: AsyncSession, model: Type[BaseModelType], unique_id_column: str, unique_id_value: str):
    """
    Asynchronously retrieves a record by its unique ID using the new async syntax.
    """
    column = getattr(model, unique_id_column)
    # The .query() method is synchronous. We use .execute(select()) instead.
    result = await db.execute(select(model).where(column == unique_id_value))
    return result.scalars().first()

async def create(db: AsyncSession, model: Type[BaseModelType], schema: BaseModel):
    """
    Asynchronously creates a new record with auto timestamps.
    """
    data = schema.model_dump()
    now_ts = int(time.time())
    if hasattr(model, "created_at") and "created_at" not in data:
        data["created_at"] = now_ts
    if hasattr(model, "updated_at") and "updated_at" not in data:
        data["updated_at"] = now_ts

    db_record = model(**data)
    db.add(db_record)
    # Use await for asynchronous commit
    await db.commit()
    await db.refresh(db_record)
    return db_record

async def update(db: AsyncSession, db_record: BaseModelType, updated_data: BaseModel):
    """
    Asynchronously updates an existing record.
    """
    update_data_dict = updated_data.model_dump(exclude_unset=True)

    for key, value in update_data_dict.items():
        setattr(db_record, key, value)

    if hasattr(db_record, "updated_at"):
        setattr(db_record, "updated_at", int(time.time()))

    # Use await for asynchronous commit
    await db.commit()
    await db.refresh(db_record)
    return db_record

async def delete(db: AsyncSession, db_record: BaseModelType):
    """
    Asynchronously deletes a record.
    """
    await db.delete(db_record)
    await db.commit()

