"""User model for the rental platform."""
import uuid
from datetime import datetime
from enum import Enum
from werkzeug.security import generate_password_hash, check_password_hash
from sqlalchemy.dialects.postgresql import UUID
from app import db


class UserRole(Enum):
    """User role enumeration."""
    CUSTOMER = 'customer'
    OWNER = 'owner'
    ADMIN = 'admin'


class User(db.Model):
    """User model for authentication and profile management."""
    
    __tablename__ = 'users'
    
    # Primary Key
    id = db.Column(db.String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    
    # Personal Information
    first_name = db.Column(db.String(50), nullable=False)
    last_name = db.Column(db.String(50), nullable=False)
    username = db.Column(db.String(50), unique=True, nullable=False, index=True)
    email = db.Column(db.String(120), unique=True, nullable=False, index=True)
    phone_number = db.Column(db.String(20), unique=True, nullable=True)
    date_of_birth = db.Column(db.Date, nullable=True)
    
    # Address Information
    address = db.Column(db.Text, nullable=True)
    city = db.Column(db.String(100), nullable=True)
    country = db.Column(db.String(100), nullable=True)
    
    # Authentication & Security
    password_hash = db.Column(db.String(255), nullable=False)
    is_email_verified = db.Column(db.Boolean, default=False)
    
    # Profile & Role
    role = db.Column(db.Enum(UserRole), default=UserRole.CUSTOMER, nullable=False)
    profile_image = db.Column(db.String(255), nullable=True)
    
    # Status Flags
    is_active = db.Column(db.Boolean, default=True)
    is_verified = db.Column(db.Boolean, default=False)  # For owner verification
    
    # Timestamps
    created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
    
    # Relationships
    owned_houses = db.relationship('House', backref='owner', lazy='dynamic')
    owned_cars = db.relationship('Car', backref='owner', lazy='dynamic')
    
    def set_password(self, password):
        """Hash and set the user password."""
        self.password_hash = generate_password_hash(password)
    
    def check_password(self, password):
        """Verify password against hash."""
        return check_password_hash(self.password_hash, password)
    
    @property
    def get_full_name(self):
        """Return user's full name."""
        return f"{self.first_name} {self.last_name}"
    
    def to_dict_public(self):
        """Public user data - safe for display to other users."""
        return {
            'id': str(self.id),
            'username': self.username,
            'first_name': self.first_name,
            'profile_image': self.profile_image,
            'role': self.role.value,
            'is_verified': self.is_verified
        }
    
    def to_dict_auth(self):
        """Authentication data - used after login/registration."""
        return {
            'id': str(self.id),
            'username': self.username,
            'email': self.email,
            'role': self.role.value,
            'is_active': self.is_active,
            'is_verified': self.is_verified,
            'is_email_verified': self.is_email_verified
        }
    
    def to_dict_private(self):
        """Private user data - full profile for authenticated user."""
        return {
            'id': str(self.id),
            'first_name': self.first_name,
            'last_name': self.last_name,
            'username': self.username,
            'email': self.email,
            'phone_number': self.phone_number,
            'date_of_birth': self.date_of_birth.isoformat() if self.date_of_birth else None,
            'address': self.address,
            'city': self.city,
            'country': self.country,
            'profile_image': self.profile_image,
            'role': self.role.value,
            'is_email_verified': self.is_email_verified,
            'is_verified': self.is_verified,
            'created_at': self.created_at.isoformat(),
            'updated_at': self.updated_at.isoformat()
        }
    
    def to_dict_admin(self):
        """Admin view - everything except password hash."""
        return {
            'id': str(self.id),
            'first_name': self.first_name,
            'last_name': self.last_name,
            'username': self.username,
            'email': self.email,
            'phone_number': self.phone_number,
            'date_of_birth': self.date_of_birth.isoformat() if self.date_of_birth else None,
            'address': self.address,
            'city': self.city,
            'country': self.country,
            'profile_image': self.profile_image,
            'role': self.role.value,
            'is_email_verified': self.is_email_verified,
            'is_active': self.is_active,
            'is_verified': self.is_verified,
            'created_at': self.created_at.isoformat(),
            'updated_at': self.updated_at.isoformat()
        }
    
    def __repr__(self):
        """String representation of User."""
        return f'<User {self.username}>'