"""Modelo de código de invitación reutilizable para registro."""

from datetime import datetime
from typing import Optional

from api.v1.common.base_models import BaseTimestampMixin
from core.database import Base
from sqlalchemy import Boolean, DateTime, Integer, String
from sqlalchemy.orm import Mapped, mapped_column


class InviteCode(Base, BaseTimestampMixin):
    """
    Código corto multiuso para invitar usuarios a un tenant/empresa.
    A diferencia de InviteToken (único por email), un InviteCode es
    compartible: se distribuye como cadena de 8 chars y puede
    ser canjeado por múltiples usuarios hasta agotar max_uses.
    """

    __tablename__ = "invite_codes"
    __table_args__ = {"schema": "core", "extend_existing": True}

    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)

    # Código legible generado automáticamente (8 chars, sin ambigüedad 0/O/I/l)
    code: Mapped[str] = mapped_column(String(16), unique=True, nullable=False, index=True)

    # Tenant destino — el usuario debe unirse a este workspace en el Hub
    tenant_slug: Mapped[str] = mapped_column(String(100), nullable=False, index=True)

    # Empresa destino específica (None = cualquier empresa del tenant)
    company_id: Mapped[Optional[int]] = mapped_column(Integer, nullable=True, index=True)

    # Rol con el que se provisiona el usuario al canjear
    role: Mapped[str] = mapped_column(String(50), nullable=False, server_default="user")

    # Control de uso
    max_uses: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
    uses_count: Mapped[int] = mapped_column(Integer, nullable=False, server_default="0", default=0)

    # Expiración (None = sin expiración)
    expires_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)

    # keycloak_user_id del admin que generó el código
    created_by: Mapped[str] = mapped_column(String(255), nullable=False)

    is_active: Mapped[bool] = mapped_column(
        Boolean, nullable=False, server_default="true", default=True
    )
