from pydantic import BaseModel, EmailStr, validator
from datetime import datetime
from typing import Optional
from enum import Enum


class PPRStatus(str, Enum):
    NEW = "NEW"
    CONFIRMED = "CONFIRMED"
    CANCELED = "CANCELED"
    LANDED = "LANDED"
    DELETED = "DELETED"
    DEPARTED = "DEPARTED"


class UserRole(str, Enum):
    ADMINISTRATOR = "ADMINISTRATOR"
    OPERATOR = "OPERATOR"
    READ_ONLY = "READ_ONLY"


class PPRBase(BaseModel):
    ac_reg: str
    ac_type: str
    ac_call: Optional[str] = None
    captain: str
    fuel: Optional[str] = None
    in_from: str
    eta: datetime
    pob_in: int
    out_to: Optional[str] = None
    etd: Optional[datetime] = None
    pob_out: Optional[int] = None
    email: Optional[EmailStr] = None
    phone: Optional[str] = None
    notes: Optional[str] = None

    @validator('ac_reg')
    def validate_registration(cls, v):
        if not v or len(v.strip()) == 0:
            raise ValueError('Aircraft registration is required')
        return v.strip().upper()

    @validator('pob_in')
    def validate_pob_in(cls, v):
        if v is not None and v < 0:
            raise ValueError('POB inbound must be non-negative')
        return v

    @validator('pob_out')
    def validate_pob_out(cls, v):
        if v is not None and v < 0:
            raise ValueError('POB outbound must be non-negative')
        return v


class PPRCreate(PPRBase):
    pass


class PPRUpdate(BaseModel):
    ac_reg: Optional[str] = None
    ac_type: Optional[str] = None
    ac_call: Optional[str] = None
    captain: Optional[str] = None
    fuel: Optional[str] = None
    in_from: Optional[str] = None
    eta: Optional[datetime] = None
    pob_in: Optional[int] = None
    out_to: Optional[str] = None
    etd: Optional[datetime] = None
    pob_out: Optional[int] = None
    email: Optional[EmailStr] = None
    phone: Optional[str] = None
    notes: Optional[str] = None


class PPRStatusUpdate(BaseModel):
    status: PPRStatus
    timestamp: Optional[datetime] = None


class PPRInDBBase(PPRBase):
    id: int
    status: PPRStatus
    landed_dt: Optional[datetime] = None
    departed_dt: Optional[datetime] = None
    created_by: Optional[str] = None
    submitted_dt: datetime

    class Config:
        from_attributes = True


class PPR(PPRInDBBase):
    pass


class PPRPublic(BaseModel):
    """Public schema for arrivals/departures board - excludes sensitive data"""
    id: int
    status: PPRStatus
    ac_reg: str
    ac_type: str
    ac_call: Optional[str] = None
    in_from: str
    eta: datetime
    out_to: Optional[str] = None
    etd: Optional[datetime] = None
    landed_dt: Optional[datetime] = None
    departed_dt: Optional[datetime] = None
    submitted_dt: datetime
    
    class Config:
        from_attributes = True


class PPRInDB(PPRInDBBase):
    pass


# User schemas
class UserBase(BaseModel):
    username: str
    role: UserRole = UserRole.READ_ONLY


class UserCreate(UserBase):
    password: str


class UserUpdate(BaseModel):
    username: Optional[str] = None
    password: Optional[str] = None
    role: Optional[UserRole] = None


class ChangePassword(BaseModel):
    """Schema for admin-initiated password changes"""
    password: str


class UserInDBBase(UserBase):
    id: int

    class Config:
        from_attributes = True


class User(UserInDBBase):
    pass


class UserInDB(UserInDBBase):
    password: str


# Authentication schemas
class Token(BaseModel):
    access_token: str
    token_type: str
    expires_in: int  # Token expiry in seconds


class TokenData(BaseModel):
    username: Optional[str] = None


# Journal schemas
class JournalBase(BaseModel):
    ppr_id: int
    entry: str
    user: str
    ip: str


class JournalCreate(JournalBase):
    pass


class Journal(JournalBase):
    id: int
    entry_dt: datetime

    class Config:
        from_attributes = True


# Airport schemas
class AirportBase(BaseModel):
    icao: str
    iata: Optional[str] = None
    name: str
    country: str


class Airport(AirportBase):
    class Config:
        from_attributes = True


# Aircraft schemas
class AircraftBase(BaseModel):
    icao24: Optional[str] = None
    registration: Optional[str] = None
    manufacturer_icao: Optional[str] = None
    type_code: Optional[str] = None
    manufacturer_name: Optional[str] = None
    model: Optional[str] = None
    clean_reg: Optional[str] = None


class Aircraft(AircraftBase):
    id: int
    
    class Config:
        from_attributes = True


# User Aircraft schemas
class UserAircraftBase(BaseModel):
    registration: str
    type_code: str
    clean_reg: str
    created_by: str


class UserAircraft(UserAircraftBase):
    id: int
    
    class Config:
        from_attributes = True


class UserAircraftCreate(BaseModel):
    registration: str
    type_code: str