"""House model for rental properties."""
import uuid
from datetime import datetime
from enum import Enum
from sqlalchemy.dialects.postgresql import UUID
from app import db


class HouseStatus(Enum):
    """House status enumeration."""
    ACTIVE = 'active'
    INACTIVE = 'inactive'
    UNDER_REVIEW = 'under_review'


class House(db.Model):
    """House rental property model."""
    
    __tablename__ = 'houses'
    
    # Primary Key
    id = db.Column(db.String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    
    # Owner Relationship
    owner_id = db.Column(db.String(36), db.ForeignKey('users.id'), nullable=False, index=True)

    # Core Information
    title = db.Column(db.String(200), nullable=False)
    description = db.Column(db.Text, nullable=False)
    category = db.Column(db.String(50), nullable=True)  # Villa, Apartment, Studio, Townhouse
    
    # Pricing
    price_per_day = db.Column(db.Numeric(10, 2), nullable=False)
    price_per_week = db.Column(db.Numeric(10, 2), nullable=True)
    price_per_month = db.Column(db.Numeric(10, 2), nullable=True)
    price_per_year = db.Column(db.Numeric(10, 2), nullable=True)
    currency = db.Column(db.String(3), default='KSH', nullable=False)
    
    # Location
    address = db.Column(db.Text, nullable=False)
    city = db.Column(db.String(100), nullable=False, index=True)
    country = db.Column(db.String(100), nullable=False, index=True)
    latitude = db.Column(db.Float, nullable=True)
    longitude = db.Column(db.Float, nullable=True)
    
    # House Details
    bedrooms = db.Column(db.Integer, nullable=False)
    bathrooms = db.Column(db.Integer, nullable=False)
    max_guests = db.Column(db.Integer, nullable=False)
    square_feet = db.Column(db.Integer, nullable=True)
    floor_number = db.Column(db.Integer, nullable=True)
    
    # Features & Amenities (JSON)
    features = db.Column(db.JSON, default=list)
    house_rules = db.Column(db.Text, nullable=True)
    
    # Status & Ratings
    is_available = db.Column(db.Boolean, default=True, nullable=False)
    is_verified = db.Column(db.Boolean, default=False, nullable=False)
    status = db.Column(db.Enum(HouseStatus), default=HouseStatus.ACTIVE, nullable=False)
    rating_average = db.Column(db.Float, default=0.0, nullable=False)
    review_count = db.Column(db.Integer, default=0, nullable=False)
    
    # 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
    images = db.relationship('HouseImage', backref='house', lazy='dynamic', cascade='all, delete-orphan')
    
    def get_primary_image(self):
        """Get primary image URL or first image."""
        primary = self.images.filter_by(is_primary=True).first()
        if primary:
            return primary.image_url
        first = self.images.order_by('display_order').first()
        return first.image_url if first else None
    
    def to_dict_public(self):
        """Public listing data - for search/browse pages."""
        return {
            'id': str(self.id),
            'title': self.title,
            'category': self.category,
            'price_per_day': float(self.price_per_day) if self.price_per_day else None,
            'price_per_week': float(self.price_per_week) if self.price_per_week else None,
            'price_per_month': float(self.price_per_month) if self.price_per_month else None,
            'currency': self.currency,
            'city': self.city,
            'country': self.country,
            'bedrooms': self.bedrooms,
            'bathrooms': self.bathrooms,
            'max_guests': self.max_guests,
            'rating_average': self.rating_average,
            'review_count': self.review_count,
            'is_available': self.is_available,
            'primary_image': self.get_primary_image()
        }
    
    def to_dict_detail(self):
        """Detailed view - for single house page."""
        return {
            'id': str(self.id),
            'title': self.title,
            'description': self.description,
            'category': self.category,
            'price_per_day': float(self.price_per_day) if self.price_per_day else None,
            'price_per_week': float(self.price_per_week) if self.price_per_week else None,
            'price_per_month': float(self.price_per_month) if self.price_per_month else None,
            'price_per_year': float(self.price_per_year) if self.price_per_year else None,
            'currency': self.currency,
            'address': self.address,
            'city': self.city,
            'country': self.country,
            'latitude': self.latitude,
            'longitude': self.longitude,
            'bedrooms': self.bedrooms,
            'bathrooms': self.bathrooms,
            'max_guests': self.max_guests,
            'square_feet': self.square_feet,
            'floor_number': self.floor_number,
            'features': self.features or [],
            'house_rules': self.house_rules,
            'rating_average': self.rating_average,
            'review_count': self.review_count,
            'is_available': self.is_available,
            'images': [img.to_dict() for img in self.images.order_by('display_order')],
            'owner': {
                'username': self.owner.username,
                'profile_image': self.owner.profile_image
            }
        }
    
    def to_dict_owner(self):
        """Owner view - for property management."""
        data = self.to_dict_detail()
        data.update({
            'owner_id': str(self.owner_id),
            'status': self.status.value,
            'is_verified': self.is_verified,
            'created_at': self.created_at.isoformat(),
            'updated_at': self.updated_at.isoformat()
        })
        return data
    
    def to_dict_admin(self):
        """Admin view - full details."""
        data = self.to_dict_owner()
        data['owner'] = self.owner.to_dict_admin()
        return data
    
    def __repr__(self):
        """String representation of House."""
        return f'<House {self.title}>'