import bottle

import datetime
from . import database, parcelsapp

PARCELSAPP_CLIENT: parcelsapp.ParcelsAppClient | None = None

TEMPLATE = """
<doctype HTML>
<html>
<head>
<style type="text/css">

.tracking-grid {
    display: grid;
    grid-template-columns: 1fr;
    grid-gap: 10px;
}

.tracking-item {
    display: grid;
    grid-template-columns: 150px 1fr auto;
    grid-gap: 0.5em;
    padding: 0.5em 0.2em;
    border-radius: 5px;
    border: black solid 1px;
}


.tracking-name {
    grid-column: 1;
}

.tracking-name-inner {
    border: solid black 1px;
    padding: 0.2em;
    border-radius: 3px;
    background-color: #FFF8;
}

a {
    text-decoration: none;
}

.tracking-status {
    grid-column: 2;
}

.tracking-update-date {
    grid-column: 3;
}

.tracking-item.delivered {
    background: #ABFBD6;
}

.tracking-item.transit {
    background: #AEABFB;
}

.tracking-item.unknown {
    background: red;
}

h1 {
    text-align: center;
}
main {
    max-width: 800px;
    margin:auto;
}

body {
    font-family: sans;
}

a {
    color:black;
}

.add-number-form {
    display: grid;
    grid-template: auto 1fr;
    max-width: 300px;
    grid-gap: 2px;
    margin: auto;
}

.add-number-form .add {
    grid-column: 1 / 3;
}

footer {
  margin-top: 10em;
}
</style>
</head>
<body>

% if with_form:
<h1>Parcels</h1>
% end

<main>

% if error_message is not None:
    <div class="error-message">{{error_message}}</div>
% end

<div class="tracking-grid">
% for entry, tracking_data in tracking_results:
    <a target="_blank" href="{{tracking_data.tracking_url if tracking_data else ''}}">
    <div class="tracking-item {{tracking_data.status if tracking_data else 'unknown'}}">
        <div class="tracking-name" title="{{entry.number}}"><span class="tracking-name-inner">{{ entry.name }}</span></div>
        <div class="tracking-status">{{ tracking_data.latest_state().status if tracking_data else 'unknown' }}</div>
        <div class="tracking-update-date">{{ tracking_data.latest_state().date.date() if tracking_data else '???' }}</div>
    </div>
    </a>
% end
% if len(tracking_results) == 0:
    <div style="text-align: center"><b>No Parcels yet...<br>Add some below!</b></div>
% end
</div>

</main>

% if with_form:
<footer>
    <form action="/add" method="POST" class="add-number-form">
        <label for="name">Name</label>
        <input type="text" name="name" id="name" required />
        <label for="tracking-number">Number</label>
        <input type="text" name="tracking-number" id="tracking-number" required />
        <input class="add" type="submit" value="Add Tracking Number!" />
    </form>
</footer>
% end

</body>
</html>
"""

TODAY = datetime.datetime.now(tz=datetime.UTC).date()

def get_packages_from_parcels():
    tracking_entries = database.get_tracking_numbers()
    tracking_numbers = [e.number for e in tracking_entries]

    try:
        tracking_results = list(PARCELSAPP_CLIENT.get_tracking_status(tracking_numbers))
        error_message = None
    except parcelsapp.ParcelsApiError as ex:
        tracking_results = []
        error_message = str(ex)

    tracking_results_by_id = {
        result.tracking_number: result for result in tracking_results
    }

    return [(e, tracking_results_by_id.get(e.number)) for e in tracking_entries]


def render_tracking(tracking_results_with_name, error_message: str | None, with_form: bool):
    tracking_results_with_name = get_packages_from_parcels()
    tracking_results_with_name.sort(key=lambda x: x[1].latest_state().date if x[1] else TODAY, reverse=True)
    return bottle.template(TEMPLATE, error_message=error_message, tracking_results=tracking_results_with_name, with_form=with_form)

@bottle.route('/')
def index():
    return render_tracking(with_form=True)

@bottle.route('/noninteraction')
def inner():
    return render_tracking(with_form=False)



@bottle.route('/add', method='POST')
def add_tracking_number():
    number: str = bottle.request.forms.get('tracking-number')
    name: str = bottle.request.forms.get('name')
    if number is None or name is None:
        bottle.abort(400)
    database.add_tracking_number(database.TrackingNumberEntry(number.strip(), name.strip()))
    return bottle.redirect('/')


def initialize_server(parcelsapp_client: parcelsapp.ParcelsAppClient):
    global PARCELSAPP_CLIENT
    PARCELSAPP_CLIENT = parcelsapp_client
    bottle.run(host='0.0.0.0', port=8080, debug=False)