# models/database/user.py - IMPROVED VERSION
"""
User model with authentication support.

ROLE CLARIFICATION:
- User.role should ONLY contain platform-level roles:
  * "admin" - Platform administrator (full system access)
  * "vendor" - Any user who owns or is part of a vendor team

- Vendor-specific roles (manager, staff, etc.) are stored in VendorUser.role
- Customers are NOT in the User table - they use the Customer model
"""

import enum

from sqlalchemy import Boolean, Column, DateTime, Integer, String
from sqlalchemy.orm import relationship

from app.core.database import Base
from models.database.base import TimestampMixin


class UserRole(str, enum.Enum):
    """Platform-level user roles."""

    ADMIN = "admin"  # Platform administrator
    VENDOR = "vendor"  # Vendor owner or team member


class User(Base, TimestampMixin):
    """Represents a platform user (admins and vendors only)."""

    __tablename__ = "users"

    id = Column(Integer, primary_key=True, index=True)
    email = Column(String, unique=True, index=True, nullable=False)
    username = Column(String, unique=True, index=True, nullable=False)
    first_name = Column(String)
    last_name = Column(String)
    hashed_password = Column(String, nullable=False)

    # Platform-level role only (admin or vendor)
    role = Column(String, nullable=False, default=UserRole.VENDOR.value)

    is_active = Column(Boolean, default=True, nullable=False)
    is_email_verified = Column(Boolean, default=False, nullable=False)
    last_login = Column(DateTime, nullable=True)

    # Relationships
    marketplace_import_jobs = relationship(
        "MarketplaceImportJob", back_populates="user"
    )
    owned_companies = relationship("Company", back_populates="owner")
    vendor_memberships = relationship(
        "VendorUser", foreign_keys="[VendorUser.user_id]", back_populates="user"
    )

    def __repr__(self):
        """String representation of the User object."""
        return f"<User(id={self.id}, username='{self.username}', email='{self.email}', role='{self.role}')>"

    @property
    def full_name(self):
        """Returns the full name of the user, combining first and last names if available."""
        if self.first_name and self.last_name:
            return f"{self.first_name} {self.last_name}"
        return self.username

    @property
    def is_admin(self) -> bool:
        """Check if user is a platform admin."""
        return self.role == UserRole.ADMIN.value

    @property
    def is_vendor(self) -> bool:
        """Check if user is a vendor (owner or team member)."""
        return self.role == UserRole.VENDOR.value

    def is_owner_of(self, vendor_id: int) -> bool:
        """
        Check if user is the owner of a specific vendor.

        Ownership is determined via company ownership:
        User owns Company → Company has Vendor → User owns Vendor
        """
        for company in self.owned_companies:
            if any(v.id == vendor_id for v in company.vendors):
                return True
        return False

    def is_member_of(self, vendor_id: int) -> bool:
        """Check if user is a member of a specific vendor (owner or team)."""
        # Check if owner (via company)
        if self.is_owner_of(vendor_id):
            return True
        # Check if team member
        return any(
            vm.vendor_id == vendor_id and vm.is_active for vm in self.vendor_memberships
        )

    def get_vendor_role(self, vendor_id: int) -> str:
        """Get user's role within a specific vendor."""
        # Check if owner (via company)
        if self.is_owner_of(vendor_id):
            return "owner"

        # Check team membership
        for vm in self.vendor_memberships:
            if vm.vendor_id == vendor_id and vm.is_active:
                return vm.role.name if vm.role else "member"

        return None

    def has_vendor_permission(self, vendor_id: int, permission: str) -> bool:
        """Check if user has a specific permission in a vendor."""
        # Owners have all permissions
        if self.is_owner_of(vendor_id):
            return True

        # Check team member permissions
        for vm in self.vendor_memberships:
            if vm.vendor_id == vendor_id and vm.is_active:
                if vm.role and permission in vm.role.permissions:
                    return True

        return False
