from utilities.animator import Animator
from utilities.tracked_display import tracked_overrides_flights
from setup import colours, fonts, screen
from config import DISTANCE_UNITS

try:
    from config import DISPLAY_FIELDS
except Exception:
    DISPLAY_FIELDS = {}

try:
    from config import _cfg
    SHOW_FLIGHT_INDEX = bool(_cfg.get("display", {}).get("show_flight_index", False))
except Exception:
    SHOW_FLIGHT_INDEX = False

from rgbmatrix import graphics

FLIGHT_NO_DISTANCE_FROM_TOP = 24
FLIGHT_NO_TEXT_HEIGHT = 8
FLIGHT_NO_FONT = fonts.small

FLIGHT_NUMBER_ALPHA_COLOUR = colours.LIGHT_PURPLE
FLIGHT_NUMBER_NUMERIC_COLOUR = colours.LIGHT_ORANGE

DATA_INDEX_POSITION = (52, 24)
DATA_INDEX_CLEAR_RIGHT = 64
DATA_INDEX_FONT = fonts.extrasmall
DATA_INDEX_COLOUR = colours.GREY
DEFAULT_FIELDS = ["airline", "flight_number"]


def _dist_unit():
    if DISTANCE_UNITS == "imperial":
        return "mi"
    if DISTANCE_UNITS == "metric":
        return "km"
    return "nm"


def _flight_number(data):
    callsign = data.get("callsign", "")
    owner_icao = data.get("owner_icao", "")
    if callsign and owner_icao and callsign.startswith(owner_icao):
        return callsign[len(owner_icao):]
    return callsign


def _format_altitude(altitude):
    if not altitude:
        return ""
    try:
        altitude = int(float(altitude))
    except (TypeError, ValueError):
        return ""
    if DISTANCE_UNITS == "metric":
        return f"{int(altitude * 0.3048)}m"
    if altitude >= 18000:
        return f"FL{altitude // 100}"
    return f"{altitude}ft"


def _format_field(field, data):
    unit = _dist_unit()
    if field == "flight_number":
        return _flight_number(data)
    if field == "altitude":
        return _format_altitude(data.get("altitude"))
    if field == "ground_speed":
        value = data.get("ground_speed")
        return f"{int(value)}kt" if value not in ("", None) else ""
    if field == "heading":
        value = data.get("heading")
        return f"{int(value)}deg" if value not in ("", None) else ""
    if field == "vertical_speed":
        value = data.get("vertical_speed")
        return f"{int(value)}fpm" if value not in ("", None) else ""
    if field in ("distance", "distance_origin", "distance_destination"):
        value = data.get(field)
        return f"{float(value):.0f}{unit}" if value not in ("", None) else ""
    value = data.get(field)
    return str(value) if value not in ("", None, "N/A") else ""


def _build_flight_text(data):
    fields = DISPLAY_FIELDS.get("flight_details", DEFAULT_FIELDS) or DEFAULT_FIELDS
    parts = [_format_field(field, data) for field in fields]
    return " ".join(part for part in parts if part)


class FlightDetailsScene(object):
    def __init__(self):
        super().__init__()
        self.flight_position = screen.WIDTH
        self.flight_details_complete = False
        self._data_all_looped = False

    @Animator.KeyFrame.add(1)
    def flight_details(self, count):
        if tracked_overrides_flights(self.overhead):
            return

        if len(self._data) == 0:
            return

        if self.flight_details_complete:
            return

        self.draw_square(
            0,
            FLIGHT_NO_DISTANCE_FROM_TOP - FLIGHT_NO_TEXT_HEIGHT,
            screen.WIDTH,
            FLIGHT_NO_DISTANCE_FROM_TOP,
            colours.BLACK,
        )

        flight_no_text_length = 0
        flight_no = _build_flight_text(self._data[self._data_index])

        if flight_no:
            for ch in flight_no:
                ch_length = graphics.DrawText(
                    self.canvas,
                    FLIGHT_NO_FONT,
                    self.flight_position + flight_no_text_length,
                    FLIGHT_NO_DISTANCE_FROM_TOP,
                    FLIGHT_NUMBER_NUMERIC_COLOUR if ch.isnumeric() else FLIGHT_NUMBER_ALPHA_COLOUR,
                    ch,
                )
                flight_no_text_length += ch_length

        if SHOW_FLIGHT_INDEX and len(self._data) > 1:
            self.draw_square(
                DATA_INDEX_POSITION[0],
                FLIGHT_NO_DISTANCE_FROM_TOP - FLIGHT_NO_TEXT_HEIGHT,
                min(DATA_INDEX_CLEAR_RIGHT, screen.WIDTH),
                FLIGHT_NO_DISTANCE_FROM_TOP,
                colours.BLACK,
            )

            text_length = graphics.DrawText(
                self.canvas,
                DATA_INDEX_FONT,
                DATA_INDEX_POSITION[0],
                DATA_INDEX_POSITION[1],
                DATA_INDEX_COLOUR,
                f"{self._data_index + 1}/{len(self._data)}",
            )
            flight_no_text_length += text_length

        self.flight_position -= 1
        if self.flight_position + flight_no_text_length < 0:
            if len(self._data) > 1:
                self.flight_details_complete = True
                self.mark_scroll_complete("flight_details")
            else:
                self.flight_position = screen.WIDTH

    @Animator.KeyFrame.add(0)
    def reset_flight_details_scroll(self):
        self.flight_position = screen.WIDTH
        self.flight_details_complete = False
