from __future__ import annotations

import uuid
from datetime import datetime
from typing import Any

from sqlalchemy import Boolean, JSON, MetaData, String, Text
from sqlalchemy.types import DateTime
from sqlalchemy.engine import Engine
from sqlalchemy.orm import Mapped, mapped_column, registry

from govoplan_core.db.base import NAMING_CONVENTION, utcnow

scope_registry = registry(metadata=MetaData(naming_convention=NAMING_CONVENTION))


def new_uuid() -> str:
    return str(uuid.uuid4())


@scope_registry.mapped
class Tenant:
    """Core-owned scope row used when the tenancy module is not installed.

    The table was historically named ``tenancy_tenants``. It is now owned by
    core as ``core_scopes`` so access, auth and policy code can use a stable
    scope identifier without importing or requiring the tenancy module.
    """

    __tablename__ = "core_scopes"

    id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid)
    slug: Mapped[str] = mapped_column(String(100), unique=True, nullable=False, index=True)
    name: Mapped[str] = mapped_column(String(255), nullable=False)
    description: Mapped[str | None] = mapped_column(Text)
    default_locale: Mapped[str] = mapped_column(String(20), default="en", nullable=False)
    settings: Mapped[dict[str, Any]] = mapped_column(JSON, default=dict, nullable=False)
    allow_custom_groups: Mapped[bool | None] = mapped_column(Boolean, nullable=True)
    allow_custom_roles: Mapped[bool | None] = mapped_column(Boolean, nullable=True)
    allow_api_keys: Mapped[bool | None] = mapped_column(Boolean, nullable=True)
    is_active: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utcnow, nullable=False)
    updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utcnow, onupdate=utcnow, nullable=False)


def create_scope_tables(engine: Engine) -> None:
    scope_registry.metadata.create_all(bind=engine, checkfirst=True)


__all__ = ["Tenant", "create_scope_tables", "new_uuid", "scope_registry"]
