"""
Modelo de relación entre usuarios (Keycloak) y tenants
"""

from datetime import datetime
from typing import TYPE_CHECKING, Optional

from api.v1.common.base_models import TenantScopedMixin, TimestampMixin
from core.database import Base
from sqlalchemy import (
    Boolean,
    ForeignKeyConstraint,
    JSON,
    String,
    Text,
    UniqueConstraint,
    DateTime,
)
from sqlalchemy.orm import Mapped, mapped_column, relationship

if TYPE_CHECKING:
    from api.v1.modules.core.tenants.models import Tenant


class UserTenant(Base, TenantScopedMixin, TimestampMixin):
    """
    Relación muchos-a-muchos entre usuarios de Keycloak y tenants

    Un usuario puede pertenecer a múltiples tenants
    Un tenant puede tener múltiples usuarios
    """

    __tablename__ = "user_tenants"
    __table_args__ = (
        UniqueConstraint(
            "keycloak_user_id", "tenant_id", "company_id", name="uq_user_tenant"
        ),
        {"schema": "core", "extend_existing": True},
    )

    # Primary Key
    id: Mapped[int] = mapped_column(primary_key=True, index=True)

    # ID del usuario en Keycloak (UUID string)
    keycloak_user_id: Mapped[str] = mapped_column(
        String(255), nullable=False, index=True
    )

    # Estado de la relación
    is_active: Mapped[bool] = mapped_column(
        Boolean, default=True, server_default="true", nullable=False
    )

    # Información adicional - Rol del usuario en este tenant (opcional)
    role: Mapped[Optional[str]] = mapped_column(String(50), nullable=True)

    # Campos de perfil de usuario
    avatar_url: Mapped[Optional[str]] = mapped_column(
        String(500), nullable=True, comment="URL de la imagen de perfil"
    )
    workspace_user_id: Mapped[Optional[str]] = mapped_column(
        String(255), nullable=True, comment="User ID (sub) proveniente de Workspace"
    )
    workspace_avatar_url: Mapped[Optional[str]] = mapped_column(
        String(500), nullable=True, comment="Avatar URL sincronizado desde Workspace"
    )
    workspace_profile_synced_at: Mapped[Optional[datetime]] = mapped_column(
        DateTime(timezone=True),
        nullable=True,
        comment="Última sincronización de perfil con Workspace",
    )
    # Caché local de nombre/apellido (fuente de verdad = Keycloak vía Hub;
    # se sincroniza al editar perfil desde Anexo76)
    first_name: Mapped[Optional[str]] = mapped_column(
        String(100), nullable=True, comment="Nombre (caché local de Keycloak)"
    )
    last_name: Mapped[Optional[str]] = mapped_column(
        String(100), nullable=True, comment="Apellido (caché local de Keycloak)"
    )
    phone: Mapped[Optional[str]] = mapped_column(
        String(20), nullable=True, comment="Teléfono del usuario"
    )
    bio: Mapped[Optional[str]] = mapped_column(
        Text, nullable=True, comment="Biografía del usuario"
    )
    preferences: Mapped[Optional[dict]] = mapped_column(
        JSON, nullable=True, comment="Preferencias del usuario (tema, idioma, etc.)"
    )

    # Relación con Tenant
    tenant: Mapped["Tenant"] = relationship("Tenant", back_populates="user_relations")
