from __future__ import annotations

from typing import Generic, Iterable, Optional, Sequence, Type, TypeVar

import sqlalchemy as sa
from sqlalchemy.orm import Session

from backend.app.db.models import Base

ModelT = TypeVar("ModelT", bound=Base)


class BaseRepository(Generic[ModelT]):
    """Provide common CRUD helpers for SQLAlchemy models."""

    model: Type[ModelT]

    def __init__(self, session: Session) -> None:
        self.session = session

    def get(self, identifier: object) -> Optional[ModelT]:
        return self.session.get(self.model, identifier)

    def list(self) -> Sequence[ModelT]:
        statement = sa.select(self.model)
        return list(self.session.scalars(statement))

    def add(self, instance: ModelT) -> ModelT:
        self.session.add(instance)
        return instance

    def add_all(self, instances: Iterable[ModelT]) -> None:
        self.session.add_all(instances)

    def delete(self, instance: ModelT) -> None:
        self.session.delete(instance)

    def flush(self) -> None:
        self.session.flush()
