"""Car model for rental vehicles."""
import uuid
from datetime import datetime
from enum import Enum
from sqlalchemy.dialects.postgresql import UUID
from app import db


class CarStatus(Enum):
    """Car status enumeration."""
    ACTIVE = 'active'
    INACTIVE = 'inactive'
    UNDER_REVIEW = 'under_review'
    MAINTENANCE = 'maintenance'


class TransmissionType(Enum):
    """Transmission type enumeration."""
    MANUAL = 'manual'
    AUTOMATIC = 'automatic'


class FuelType(Enum):
    """Fuel type enumeration."""
    PETROL = 'petrol'
    DIESEL = 'diesel'
    ELECTRIC = 'electric'
    HYBRID = 'hybrid'


class Car(db.Model):
    """Car rental vehicle model."""
    
    __tablename__ = 'cars'
    
    # 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)
    
    # Car Details
    make = db.Column(db.String(50), nullable=False, index=True)  # Toyota, Honda, BMW
    model = db.Column(db.String(50), nullable=False)  # Camry, Civic, X5
    year = db.Column(db.Integer, nullable=False, index=True)
    category = db.Column(db.String(50), nullable=True)  # SUV, Sedan, Hatchback, Sports
    color = db.Column(db.String(30), nullable=True)
    license_plate = db.Column(db.String(20), nullable=False, unique=True, index=True)
    
    # Car Specifications
    seats = db.Column(db.Integer, nullable=False)
    transmission = db.Column(db.Enum(TransmissionType), nullable=False)
    fuel_type = db.Column(db.Enum(FuelType), nullable=False)
    mileage = db.Column(db.Integer, nullable=True)  # Current mileage in km
    engine_capacity = db.Column(db.String(20), nullable=True)  # e.g., "2.0L", "1500cc"
    
    # 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)
    security_deposit = db.Column(db.Numeric(10, 2), nullable=True)
    
    # Location
    city = db.Column(db.String(100), nullable=False, index=True)
    country = db.Column(db.String(100), nullable=False, index=True)
    pickup_location = db.Column(db.Text, nullable=True)
    latitude = db.Column(db.Float, nullable=True)
    longitude = db.Column(db.Float, nullable=True)
    
    # Features (JSON)
    features = db.Column(db.JSON, default=list)  # GPS, Bluetooth, Backup Camera, etc.
    insurance_included = db.Column(db.Boolean, default=False, nullable=False)
    fuel_policy = db.Column(db.String(50), nullable=True)  # Full-to-Full, Same-to-Same
    
    # Requirements & Rules
    minimum_age = db.Column(db.Integer, default=21, nullable=False)
    driving_license_required = db.Column(db.Boolean, default=True, nullable=False)
    rental_terms = 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(CarStatus), default=CarStatus.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('CarImage', backref='car', 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,
            'make': self.make,
            'model': self.model,
            'year': self.year,
            '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,
            'seats': self.seats,
            'transmission': self.transmission.value,
            'fuel_type': self.fuel_type.value,
            '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 car page."""
        return {
            'id': str(self.id),
            'title': self.title,
            'description': self.description,
            'make': self.make,
            'model': self.model,
            'year': self.year,
            'category': self.category,
            'color': self.color,
            '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,
            'security_deposit': float(self.security_deposit) if self.security_deposit else None,
            'city': self.city,
            'country': self.country,
            'pickup_location': self.pickup_location,
            'latitude': self.latitude,
            'longitude': self.longitude,
            'seats': self.seats,
            'transmission': self.transmission.value,
            'fuel_type': self.fuel_type.value,
            'mileage': self.mileage,
            'engine_capacity': self.engine_capacity,
            'features': self.features or [],
            'insurance_included': self.insurance_included,
            'fuel_policy': self.fuel_policy,
            'minimum_age': self.minimum_age,
            'driving_license_required': self.driving_license_required,
            'rental_terms': self.rental_terms,
            '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 vehicle management."""
        data = self.to_dict_detail()
        data.update({
            'owner_id': str(self.owner_id),
            'license_plate': self.license_plate,
            '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 Car."""
        return f'<Car {self.make} {self.model} ({self.year})>'