{% extends 'partials/base.html.twig' %}

{% block content %}
{% set trip_page = page.parent() %}
{% set tracker_page = grav.pages.find(trip_page.route ~ '/dailies') %}
{% set all_entries = tracker_page ? tracker_page.children.published() : [] %}

{# Basic counts #}
{% set entry_count = all_entries|length %}

{# Days on road — past trip uses declared date_end; active trip uses first entry to now #}
{% set days_on_road = 0 %}
{% if trip_page.header.date_end is not empty %}
    {# Past trip: use declared end date #}
    {% set start_ts = trip_page.header.date_start|date('U') %}
    {% set end_ts = trip_page.header.date_end|date('U') %}
    {% set days_on_road = ((end_ts - start_ts) / 86400)|round(0, 'ceil') %}
{% else %}
    {# Active trip: first entry to now #}
    {% set first_ts = null %}
    {% for entry in all_entries %}
        {% set ts = entry.date|date('U') %}
        {% if first_ts is null or ts < first_ts %}{% set first_ts = ts %}{% endif %}
    {% endfor %}
    {% if first_ts is not null %}
        {% set diff_seconds = "now"|date('U') - first_ts %}
        {% set days_raw = (diff_seconds / 86400)|round(0, 'floor') %}
        {% set days_on_road = days_raw < 1 ? 1 : days_raw %}
    {% endif %}
{% endif %}

{# Countries — unique, case-insensitive dedup, preserve original casing #}
{% set seen_lower = [] %}
{% set country_display = [] %}
{% for entry in all_entries %}
    {% if entry.header.location_country is not empty %}
        {% set lower = entry.header.location_country|trim|lower %}
        {% if lower not in seen_lower %}
            {% set seen_lower = seen_lower|merge([lower]) %}
            {% set country_display = country_display|merge([entry.header.location_country|trim]) %}
        {% endif %}
    {% endif %}
{% endfor %}

{# Cities — unique, case-insensitive dedup, preserve original casing #}
{% set seen_city_lower = [] %}
{% set city_display = [] %}
{% for entry in all_entries %}
    {% if entry.header.location_city is not empty %}
        {% set lower = entry.header.location_city|trim|lower %}
        {% if lower not in seen_city_lower %}
            {% set seen_city_lower = seen_city_lower|merge([lower]) %}
            {% set city_display = city_display|merge([entry.header.location_city|trim]) %}
        {% endif %}
    {% endif %}
{% endfor %}

{# Temperature range #}
{% set temp_min = null %}
{% set temp_max = null %}
{% for entry in all_entries %}
    {% if entry.header.weather_temp_c is defined and entry.header.weather_temp_c is not empty %}
        {% set t = entry.header.weather_temp_c %}
        {% if temp_min is null or t < temp_min %}{% set temp_min = t %}{% endif %}
        {% if temp_max is null or t > temp_max %}{% set temp_max = t %}{% endif %}
    {% endif %}
{% endfor %}

{# GPS points for distance — collect as JSON for JS computation #}
{% set gps_points = [] %}
{% for entry in all_entries %}
    {% if entry.header.lat is not empty and entry.header.lng is not empty %}
        {% set gps_points = gps_points|merge([[entry.header.lat, entry.header.lng]]) %}
    {% endif %}
{% endfor %}

{# GPX detection — trip has GPX files if any .gpx media exists on the trip page #}
{% set gpx_urls = [] %}
{% for name, media in trip_page.media.all %}
    {% if name|split('.')|last == 'gpx' %}
        {% set gpx_urls = gpx_urls|merge([trip_page.url ~ '/' ~ name]) %}
    {% endif %}
{% endfor %}
{% set has_gpx = gpx_urls|length > 0 %}

<div class="stats-page">
    <h1 class="stats-heading">Trip Statistics</h1>

    <div class="stats-grid">
        <div class="stat-block">
            <span class="stat-value">{{ days_on_road }}</span>
            <span class="stat-label">{{ days_on_road == 1 ? 'day' : 'days' }} on the road</span>
        </div>
        <div class="stat-block">
            <span class="stat-value">{{ entry_count }}</span>
            <span class="stat-label">{{ entry_count == 1 ? 'entry' : 'entries' }} posted</span>
        </div>
        <div class="stat-block">
            <span class="stat-value">{{ country_display|length }}</span>
            <span class="stat-label">{{ country_display|length == 1 ? 'country' : 'countries' }} visited</span>
        </div>
        <div class="stat-block">
            <span class="stat-value">{{ city_display|length }}</span>
            <span class="stat-label">{{ city_display|length == 1 ? 'city' : 'cities' }} visited</span>
        </div>
        <div class="stat-block">
            <span class="stat-value" id="stat-distance">—</span>
            <span class="stat-label">{{ has_gpx ? '🚴 km cycled' : '🧭 km roamed' }}</span>
        </div>
        <div class="stat-block">
            {% if temp_min is not null %}
            <span class="stat-value">{{ temp_min == temp_max ? temp_min : temp_min ~ ' → ' ~ temp_max }}</span>
            {% else %}
            <span class="stat-value">—</span>
            {% endif %}
            <span class="stat-label">°C range</span>
        </div>
    </div>

    {% if country_display|length > 0 %}
    <div class="stats-countries">
        <span class="stats-countries-label">Countries visited</span>
        {{ country_display|join(' · ') }}
    </div>
    {% endif %}

    <p class="stats-note">{{ has_gpx ? 'Distance based on GPS track data.' : 'Distance is approximate — straight lines between entry locations.' }}</p>
</div>

<script>
var GPS_POINTS = {{ gps_points|json_encode|raw }};
var GPX_URLS = {{ gpx_urls|json_encode|raw }};

function haversine(lat1, lng1, lat2, lng2) {
    var R = 6371;
    var dLat = (lat2 - lat1) * Math.PI / 180;
    var dLng = (lng2 - lng1) * Math.PI / 180;
    var a = Math.sin(dLat/2)*Math.sin(dLat/2) +
            Math.cos(lat1*Math.PI/180)*Math.cos(lat2*Math.PI/180)*
            Math.sin(dLng/2)*Math.sin(dLng/2);
    return R * 2 * Math.asin(Math.sqrt(a));
}

var distEl = document.getElementById('stat-distance');

if (GPX_URLS.length > 0) {
    // Mode A: sum haversine between all GPX trackpoints (deterministic order)
    var pending = GPX_URLS.length;
    var fileResults = new Array(GPX_URLS.length);
    GPX_URLS.forEach(function(url, idx) {
        fetch(url)
            .then(function(r) { return r.text(); })
            .then(function(text) {
                var xml = new DOMParser().parseFromString(text, 'text/xml');
                var trkpts = xml.querySelectorAll('trkpt');
                var pts = [];
                trkpts.forEach(function(pt) {
                    pts.push({
                        lat: parseFloat(pt.getAttribute('lat')),
                        lon: parseFloat(pt.getAttribute('lon'))
                    });
                });
                fileResults[idx] = pts;
                pending--;
                if (pending === 0) { computeTotalDistance(); }
            })
            .catch(function(err) {
                console.warn('GPX load failed:', url, err);
                fileResults[idx] = [];
                pending--;
                if (pending === 0) { computeTotalDistance(); }
            });
    });

    function computeTotalDistance() {
        var total = 0;
        fileResults.forEach(function(pts) {
            for (var i = 1; i < pts.length; i++) {
                total += haversine(pts[i-1].lat, pts[i-1].lon, pts[i].lat, pts[i].lon);
            }
        });
        distEl.textContent = total > 0 ? Math.round(total).toLocaleString() : '—';
    }
} else {
    // Mode B: sum haversine between consecutive entry lat/lng points
    var total = 0;
    for (var i = 1; i < GPS_POINTS.length; i++) {
        total += haversine(
            parseFloat(GPS_POINTS[i-1][0]), parseFloat(GPS_POINTS[i-1][1]),
            parseFloat(GPS_POINTS[i][0]), parseFloat(GPS_POINTS[i][1])
        );
    }
    distEl.textContent = GPS_POINTS.length < 2 ? '—' : '~' + Math.round(total).toLocaleString();
}
</script>
{% endblock %}
