from typing import List
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from app.api.deps import get_db
from app.crud.crud_ppr import ppr as crud_ppr
from app.crud.crud_local_flight import local_flight as crud_local_flight
from app.crud.crud_departure import departure as crud_departure
from app.crud.crud_arrival import arrival as crud_arrival
from app.schemas.ppr import PPRPublic
from app.models.local_flight import LocalFlightStatus
from app.models.departure import DepartureStatus
from app.models.arrival import ArrivalStatus
from datetime import date, datetime, timedelta
import re

router = APIRouter()


def lighten_color(hex_color, factor=0.3):
    """Lighten a hex color by a factor (0-1)"""
    hex_color = hex_color.lstrip('#')
    if len(hex_color) != 6:
        return hex_color  # Invalid, return as is
    r, g, b = int(hex_color[0:2], 16), int(hex_color[2:4], 16), int(hex_color[4:6], 16)
    r = min(255, int(r + (255 - r) * factor))
    g = min(255, int(g + (255 - g) * factor))
    b = min(255, int(b + (255 - b) * factor))
    return f"#{r:02x}{g:02x}{b:02x}"


def darken_color(hex_color, factor=0.3):
    """Darken a hex color by a factor (0-1)"""
    hex_color = hex_color.lstrip('#')
    if len(hex_color) != 6:
        return hex_color  # Invalid, return as is
    r, g, b = int(hex_color[0:2], 16), int(hex_color[2:4], 16), int(hex_color[4:6], 16)
    r = max(0, int(r * (1 - factor)))
    g = max(0, int(g * (1 - factor)))
    b = max(0, int(b * (1 - factor)))
    return f"#{r:02x}{g:02x}{b:02x}"


@router.get("/arrivals")
async def get_public_arrivals(db: Session = Depends(get_db)):
    """Get today's arrivals for public display (PPR and local flights)"""
    arrivals = crud_ppr.get_arrivals_today(db)
    
    # Convert PPR arrivals to dictionaries
    arrivals_list = []
    for arrival in arrivals:
        arrivals_list.append({
            'ac_call': arrival.ac_call,
            'ac_reg': arrival.ac_reg,
            'ac_type': arrival.ac_type,
            'in_from': arrival.in_from,
            'eta': arrival.eta,
            'landed_dt': arrival.landed_dt,
            'status': arrival.status.value,
            'isLocalFlight': False
        })
    
    # Add local flights with DEPARTED status that were booked out today
    local_flights = crud_local_flight.get_multi(
        db, 
        status=LocalFlightStatus.DEPARTED,
        limit=1000
    )
    
    # Get today's date boundaries
    today = date.today()
    today_start = datetime.combine(today, datetime.min.time())
    today_end = datetime.combine(today + timedelta(days=1), datetime.min.time())
    
    # Convert local flights to match the PPR format for display
    for flight in local_flights:
        # Only include flights booked out today
        if not (today_start <= flight.created_dt < today_end):
            continue
        
        # Calculate ETA from departed_dt + duration (if both are available)
        eta = flight.departed_dt
        if flight.departed_dt and flight.duration:
            eta = flight.departed_dt + timedelta(minutes=flight.duration)
        
        arrivals_list.append({
            'ac_call': flight.callsign or flight.registration,
            'ac_reg': flight.registration,
            'ac_type': flight.type,
            'in_from': None,
            'eta': eta,
            'landed_dt': None,
            'status': 'DEPARTED',
            'isLocalFlight': True,
            'flight_type': flight.flight_type.value
        })
    
    # Add booked-in arrivals
    booked_in_arrivals = crud_arrival.get_multi(db, limit=1000)
    for arrival in booked_in_arrivals:
        # Only include BOOKED_IN and LANDED arrivals
        if arrival.status not in (ArrivalStatus.BOOKED_IN, ArrivalStatus.LANDED):
            continue
        # For BOOKED_IN, only include those created today
        if arrival.status == ArrivalStatus.BOOKED_IN:
            if not (today_start <= arrival.created_dt < today_end):
                continue
        # For LANDED, only include those landed today
        elif arrival.status == ArrivalStatus.LANDED:
            if not arrival.landed_dt or not (today_start <= arrival.landed_dt < today_end):
                continue
        
        arrivals_list.append({
            'registration': arrival.registration,
            'callsign': arrival.callsign,
            'type': arrival.type,
            'in_from': arrival.in_from,
            'eta': arrival.eta,
            'landed_dt': arrival.landed_dt,
            'status': arrival.status.value,
            'isBookedIn': True
        })
    
    return arrivals_list


@router.get("/departures")
async def get_public_departures(db: Session = Depends(get_db)):
    """Get today's departures for public display (PPR, local flights, and departures to other airports)"""
    departures = crud_ppr.get_departures_today(db)
    
    # Convert PPR departures to dictionaries
    departures_list = []
    for departure in departures:
        departures_list.append({
            'ac_call': departure.ac_call,
            'ac_reg': departure.ac_reg,
            'ac_type': departure.ac_type,
            'out_to': departure.out_to,
            'etd': departure.etd,
            'departed_dt': departure.departed_dt,
            'status': departure.status.value,
            'isLocalFlight': False,
            'isDeparture': False
        })
    
    # Add local flights with BOOKED_OUT status that were booked out today
    local_flights = crud_local_flight.get_multi(
        db,
        status=LocalFlightStatus.BOOKED_OUT,
        limit=1000
    )
    
    # Get today's date boundaries
    today = date.today()
    today_start = datetime.combine(today, datetime.min.time())
    today_end = datetime.combine(today + timedelta(days=1), datetime.min.time())
    
    # Convert local flights to match the PPR format for display
    for flight in local_flights:
        # Only include flights booked out today
        if not (today_start <= flight.created_dt < today_end):
            continue
        departures_list.append({
            'ac_call': flight.callsign or flight.registration,
            'ac_reg': flight.registration,
            'ac_type': flight.type,
            'out_to': None,
            'etd': flight.etd or flight.created_dt,
            'departed_dt': None,
            'status': 'BOOKED_OUT',
            'isLocalFlight': True,
            'flight_type': flight.flight_type.value,
            'isDeparture': False
        })
    
    # Add departures to other airports with BOOKED_OUT status
    departures_to_airports = crud_departure.get_multi(
        db,
        status=DepartureStatus.BOOKED_OUT,
        limit=1000
    )
    
    # Get today's date boundaries
    today = date.today()
    today_start = datetime.combine(today, datetime.min.time())
    today_end = datetime.combine(today + timedelta(days=1), datetime.min.time())
    
    # Convert departures to match the format for display
    for dep in departures_to_airports:
        # Only include departures booked out today
        if not (today_start <= dep.created_dt < today_end):
            continue
        departures_list.append({
            'ac_call': dep.callsign or dep.registration,
            'ac_reg': dep.registration,
            'ac_type': dep.type,
            'out_to': dep.out_to,
            'etd': dep.etd or dep.created_dt,
            'departed_dt': None,
            'status': 'BOOKED_OUT',
            'isLocalFlight': False,
            'isDeparture': True
        })
    
    # Add departures to other airports with DEPARTED status (taken off today)
    departed_to_airports = crud_departure.get_multi(
        db,
        status=DepartureStatus.DEPARTED,
        limit=1000
    )
    
    for dep in departed_to_airports:
        # Only include departures that departed today
        if not dep.departed_dt or not (today_start <= dep.departed_dt < today_end):
            continue
        departures_list.append({
            'ac_call': dep.callsign or dep.registration,
            'ac_reg': dep.registration,
            'ac_type': dep.type,
            'out_to': dep.out_to,
            'etd': dep.etd or dep.created_dt,
            'departed_dt': dep.departed_dt,
            'status': 'DEPARTED',
            'isLocalFlight': False,
            'isDeparture': True
        })
    
    return departures_list


@router.get("/config")
async def get_ui_config():
    """Get UI configuration for client-side rendering"""
    from app.core.config import settings
    base_color = settings.top_bar_base_color
    return {
        "tag": settings.tag,
        "top_bar_gradient_start": base_color,
        "top_bar_gradient_end": lighten_color(base_color, 0.4),  # Lighten for gradient end
        "footer_color": darken_color(base_color, 0.2),  # Darken for footer
        "environment": settings.environment
    }