from woezel import urequests
import display
import wifi
import easydraw
import time
import json
import sys
import io
import custom_shapes


def _cache_image(file):
    with open(file, "rb") as image:
        return image.read()


APP_NAME = __file__.split("/")[-2]
APP_PATH = "/".join(__file__.split("/")[:-1])

if APP_NAME.lower() == "citycontrol":
    BACKEND_URL = "http://prod.cc.hackyholidays.io"
elif APP_NAME.lower() == "citycontroltest":
    BACKEND_URL = "http://test.cc.hackyholidays.io"
else:
    BACKEND_URL = "http://DEV_CHANGEME:4433"


TEXT_HIGHLIGHT = 0x9CFF08
TEXT_MAIN = 0xD9CFEB
TEXT_GRAY = 0xAAAAAA
HIGHLIGHT = TEXT_HIGHLIGHT
COLOR_SECONDARY = 0x524075
COLOR_BORDER = 0x241740
ARCADE_FONT = {
    6: "press_start_2p6",
    8: "press_start_2p8",
    9: "press_start_2p9",
    12: "press_start_2p12",
    18: "press_start_2p18",
    22: "press_start_2p22",
}
BACKGROUND = _cache_image("%s/background.png" % APP_PATH)
ICON_LARGE = _cache_image("%s/logo.png" % APP_PATH)
ICON_SMALL = "%s/icon.png" % APP_PATH
DOWNTOWN = "%s/District_1.png" % APP_PATH
SCIENCE_PARK = "%s/District_2.png" % APP_PATH
SCIENCE_PARK_OFF = "%s/District_2_off.png" % APP_PATH
COMMERCIAL_AVENUE = "%s/District_3.png" % APP_PATH
COMMERCIAL_AVENUE_OFF = "%s/District_3_off.png" % APP_PATH
HACKY_HARBOUR = "%s/District_4.png" % APP_PATH
HACKY_HARBOUR_OFF = "%s/District_4_off.png" % APP_PATH
DISPLAY_SIZE = display.size()
LOGO_OFFSET = (DISPLAY_SIZE[0] - display.pngInfo(ICON_LARGE)[0]) // 2

BG_DARK = 0x0F0A1F
BG_LIGHT = 0xD7CDE9
PROGRESS_RED = 0xFF1D25
PROGRESS_GREEN = HIGHLIGHT
SLIDER_PURPLE = 0x5E29BF

# Control screen sprites
JOYSTICK_DARK_OFF = _cache_image("%s/Joystick_Dark_Off.png" % APP_PATH)
JOYSTICK_DARK_ON = _cache_image("%s/Joystick_Dark_On.png" % APP_PATH)
JOYSTICK_LIGHT_OFF = _cache_image("%s/Joystick_Light_Off.png" % APP_PATH)
JOYSTICK_LIGHT_ON = _cache_image("%s/Joystick_Light_On.png" % APP_PATH)

PROGRESS_ARROW_RED = _cache_image("%s/ProgressBar_Arrow_Red.png" % APP_PATH)

SLIDER_HANDLE_DARK = _cache_image("%s/SliderHandle_Dark.png" % APP_PATH)
SLIDER_HANDLE_LIGHT = _cache_image("%s/SliderHandle_Light.png" % APP_PATH)

LEVEL_TRANSITION_ENCOURAGEMENTS = [
    "Good job!",
    "Well done!",
    "Our saviors!",
    "Our heroes!",
    "Awesome!",
    "Good stuff!",
]
LEVEL_TRANSITION_NARRATIVES = [
    ["You bought us some", "time, but the city", "is still in trouble!"],
    ["The AI is upping", "their game, can you", "please help us?"],
    ["The algorithm seems", "to evolve, we need", "some more help!"],
]
LEVEL_TRANSITION_PREPARE = [
    "Here we go!",
    "Prepare yourselves!",
    "Are you ready?",
    "Get on it!",
]

GAME_OVER_PRIMARY = [
    "It's time to find more capable controllers.",
    "Our controllers were not up to the task.",
    "Was this the best you could do?",
    "Honestly, that was rather embarrassing.",
    "Unfortunately, your best was not good enough.",
]
GAME_OVER_SECONDARY = [
    "The smart algorithm managed to remain in control of the city.",
    "The smart algorithm is still torturing the city.",
    "The smart algorithm was smarter than our controllers.",
    "Our city is still under control of the smart algorithm.",
]

ROTARY_CONTROL = (
    lambda n, l: f"{APP_PATH}/RotaryControl_{'Dark' if l else 'Light'}_{n}.png"
)


def draw_background(wifi_indicator=True, logo=True):
    display.drawFill(0)
    display.drawPng(0, 0, BACKGROUND)
    if logo:
        display.drawPng(LOGO_OFFSET, 10, ICON_LARGE)
        pass
    if wifi_indicator:
        custom_shapes.draw_wifi_indicator(
            DISPLAY_SIZE[0] - 40, 5, COLOR_SECONDARY, COLOR_BORDER
        )


def check_version():
    if not wifi.status():
        # We can't check version status without internet.
        print("Version check failed, no WiFi")
        return False

    draw_background()
    easydraw.lineCentered(170, "Checking game", ARCADE_FONT[12], TEXT_MAIN)
    easydraw.lineCentered(190, "version...", ARCADE_FONT[12], TEXT_MAIN)
    display.flush()
    # Get newest version from badge team API.
    try:
        url = f"http://mch2022.badge.team/eggs/get/{APP_NAME}/json"
        print(f"Checking {url} for updated version")
        new_version_text = urequests.get(url).text
    except Exception as e:
        # We have lost wifi while making the request.
        # I assume there will be some other code to reconnect / handle this somewhere else.
        print("Version check failed:\n%s" % str(e))
        draw_background()
        easydraw.lineCentered(160, "Failed to check version", ARCADE_FONT[9], TEXT_MAIN)
        easydraw.lineCentered(180, "Check serial logs", ARCADE_FONT[9], TEXT_MAIN)
        easydraw.lineCentered(200, "for details.", ARCADE_FONT[9], TEXT_MAIN)
        display.flush()
        return False

    new_version_parsed = json.loads(new_version_text)
    new_version = int(new_version_parsed["info"]["version"])

    # Get current version from json file.
    with open("%s/metadata.json" % APP_PATH, "r") as metadata_file:
        json_string = "".join(line.strip() for line in metadata_file)
    current_version = int(json.loads(json_string)["version"])

    if current_version != new_version:
        print(
            f"Running version '%s' of {APP_NAME} while version '%s' is available"
            % (current_version, new_version)
        )
        draw_background()
        easydraw.lineCentered(160, "Please update to", ARCADE_FONT[12], TEXT_MAIN)
        easydraw.lineCentered(180, "the latest version", ARCADE_FONT[12], TEXT_MAIN)
        easydraw.lineCentered(200, "to play", ARCADE_FONT[12], TEXT_MAIN)
        display.flush()
        return False
    else:
        print("Running latest version '%s'" % current_version)
        return True


def connect_wifi():
    if wifi.status():
        return True

    draw_background()
    easydraw.lineCentered(180, "Connecting to WiFi", ARCADE_FONT[12], TEXT_MAIN)
    display.flush()

    wifi.connect()
    wifi.wait()

    if not wifi.status():
        draw_background()
        easydraw.lineCentered(180, "Connecting to WiFi", ARCADE_FONT[12], TEXT_MAIN)
        easydraw.lineCentered(200, "failed", ARCADE_FONT[12], TEXT_MAIN)
        display.flush()
        time.sleep(3)

    return wifi.status()


def code_string_to_code(code_string):
    code = []
    for c in code_string:
        if c == "u":
            code.append("UP")
        elif c == "l":
            code.append("LEFT")
        elif c == "d":
            code.append("DOWN")
        elif c == "r":
            code.append("RIGHT")
        elif c == "a":
            code.append("A")
        elif c == "b":
            code.append("B")
    return code


def code_to_code_string(code):
    code_list = []
    for c in code:
        if c == "UP":
            code_list.append("u")
        elif c == "LEFT":
            code_list.append("l")
        elif c == "DOWN":
            code_list.append("d")
        elif c == "RIGHT":
            code_list.append("r")
        elif c == "A":
            code_list.append("a")
        elif c == "B":
            code_list.append("b")
    return "".join(code_list)


def draw_lines(text, y_start, vertical_padding, width, font, color=TEXT_MAIN):
    lines = easydraw.lineSplit(text, width=width, font=font)
    text_height = display.getTextHeight(text, font)
    y = y_start
    for line in lines:
        easydraw.lineCentered(y, line, font, color)
        y += text_height + vertical_padding

    return y


def get_exception_string(exception):
    file = io.StringIO()
    sys.print_exception(exception, file)
    return file.getvalue()
