#!/usr/bin/env python3
import cgi, sys
sys.path.insert(0, '/opt/ngon/apps')
from managers.auth_manager import AuthManager, generate_login_page_html

_form = cgi.FieldStorage()
_auth = AuthManager('flowmeter')
_auth_required, _should_exit, _headers = _auth.require_auth(_form)

if _should_exit:
    print("Content-Type: application/json")
    if _headers:
        print(_headers)
    print("")
    print('{"success": false, "error": "Authentication required"}' if _auth_required
          else '{"success": true}')
    sys.exit(0)

if _auth_required:
    print("Content-Type: text/html")
    print("")
    print(generate_login_page_html("Flowmeter Data"))
    sys.exit(0)

# ---------------------------------------------------------------------------
import cgitb
import html
import json
import time
from datetime import date, timedelta

cgitb.enable()
sys.path.insert(0, '/var/www/html/ngon')
from links import generate_dropdown_html, generate_dropdown_css, generate_dropdown_js
from gas import flow_store

FRESH_SEC = 120  # meter polls ~60s; flag a site live within 2 missed pushes

sites = flow_store.sites_with_data()

site = _form.getvalue('site', '') or (sites[0] if sites else '')
if site and site not in sites:
    site = sites[0] if sites else ''

today = date.today()
date_to = _form.getvalue('to', '') or today.isoformat()
date_from = _form.getvalue('from', '') or (today - timedelta(days=30)).isoformat()


def _reading_age(r):
    if not r or r.get('ts') is None:
        return None
    return time.time() - float(r['ts'])


# --- AJAX: live tile refresh -----------------------------------------------
if _form.getvalue('ajax', '') == 'live':
    print("Content-Type: application/json\n")
    r = flow_store.latest(site) if site else None
    age = _reading_age(r)
    out = {"has_data": bool(r), "site": site}
    if r:
        out.update({
            "age_sec": round(age, 1) if age is not None else None,
            "fresh": age is not None and age < FRESH_SEC,
            "flow_mcfd": r.get("flow_mcfd"),
            "sp_psia": r.get("sp_psia"),
            "dp_inh2o": r.get("dp_inh2o"),
            "temp_f": r.get("temp_f"),
            "vol_today_mcf": r.get("vol_today_mcf"),
            "vol_yesterday_mcf": r.get("vol_yesterday_mcf"),
        })
    print(json.dumps(out))
    sys.exit(0)

# --- CSV export ------------------------------------------------------------
if _form.getvalue('export', '') == 'csv' and site:
    rows = flow_store.daily_range(site, date_from, date_to)
    fname = f"flowmeter_{site}_{date_from}_to_{date_to}.csv".replace(' ', '_')
    print("Content-Type: text/csv")
    print(f"Content-Disposition: attachment; filename={fname}")
    print("")
    print("site,date,volume_mcf")
    for r in rows:
        print(f"{site},{r['day']},{r['vol_mcf']}")
    sys.exit(0)

# --- HTML page -------------------------------------------------------------
rows = flow_store.daily_range(site, date_from, date_to) if site else []
total_mcf = sum((r['vol_mcf'] or 0) for r in rows)
avg_mcf = (total_mcf / len(rows)) if rows else 0
live = flow_store.latest(site) if site else None
live_age = _reading_age(live)
live_fresh = live_age is not None and live_age < FRESH_SEC

esc = html.escape
print("Content-Type: text/html\n")

site_options = "".join(
    f'<option value="{esc(s)}"{" selected" if s == site else ""}>{esc(s)}</option>'
    for s in sites
) or '<option value="">(no data yet)</option>'

table_rows = "".join(
    f'<tr><td>{esc(r["day"])}</td><td class="num">{(r["vol_mcf"] or 0):,.2f}</td></tr>'
    for r in rows
) or '<tr><td colspan="2" class="empty">No daily totals in this range.</td></tr>'

print(f"""<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>NGON Flowmeter Data</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        * {{ box-sizing: border-box; margin: 0; padding: 0; }}
        body {{ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
                background: #1a1a1a; color: #e0e0e0; line-height: 1.4; }}
        ::-webkit-scrollbar {{ width: 6px; height: 6px; }}
        ::-webkit-scrollbar-thumb {{ background: #666; border-radius: 3px; }}
        .header {{
            background-color: rgba(255,255,255,0.05) !important;
            border-radius: 8px !important;
            padding: 30px !important;
            margin: 20px !important;
            border: 1px solid rgba(255,255,255,0.1) !important;
            border-bottom: none !important;
            display: flex !important;
            justify-content: space-between !important;
            align-items: flex-start !important;
        }}
        .content {{ margin: 0 20px 40px; }}
        .live-card {{
            background: #222; border: 1px solid #333; border-radius: 8px;
            padding: 16px 20px; margin-bottom: 20px;
        }}
        .live-head {{ display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }}
        .live-head h3 {{ color: #e0e0e0; font-size: 15px; margin: 0; }}
        .live-badge {{ font-size: 12px; padding: 2px 8px; border-radius: 10px; font-weight: bold; }}
        .live-badge.on  {{ background: rgba(0,255,0,.12); color: #00ff00; }}
        .live-badge.off {{ background: rgba(136,136,136,.15); color: #888; }}
        .live-grid {{ display: flex; flex-wrap: wrap; gap: 12px; }}
        .metric {{ background: #2a2a2a; border: 1px solid #3a3a3a; border-radius: 8px;
                   padding: 12px 16px; min-width: 130px; text-align: center; }}
        .metric .v {{ font-size: 20px; font-weight: bold; color: #fff; }}
        .metric .v.flow {{ color: #00ff00; }}
        .metric .l {{ font-size: 11px; color: #888; margin-top: 4px; text-transform: uppercase; letter-spacing: .5px; }}
        .filter-bar {{ display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-bottom: 14px; }}
        .filter-bar label {{ color: #888; font-size: 12px; }}
        .filter-bar select, .filter-bar input {{
            background: #2a2a2a; border: 1px solid #3a3a3a; color: #e0e0e0;
            padding: 6px 10px; border-radius: 4px; font-size: 13px;
        }}
        .filter-bar select:focus, .filter-bar input:focus {{ border-color: #00ff00; outline: none; }}
        .filter-group {{ display: flex; align-items: center; gap: 5px; }}
        .btn {{ background: #2a2a2a; border: 1px solid #3a3a3a; color: #e0e0e0; padding: 6px 14px;
                border-radius: 4px; font-size: 13px; cursor: pointer; }}
        .btn:hover {{ border-color: #00ff00; color: #00ff00; }}
        table {{ width: 100%; max-width: 560px; border-collapse: collapse; background: #222;
                 border: 1px solid #333; border-radius: 8px; overflow: hidden; }}
        th, td {{ padding: 9px 14px; text-align: left; border-bottom: 1px solid #2e2e2e; font-size: 14px; }}
        th {{ background: #262626; color: #888; font-size: 12px; text-transform: uppercase; letter-spacing: .5px; }}
        td.num {{ text-align: right; font-variant-numeric: tabular-nums; }}
        td.empty {{ text-align: center; color: #888; padding: 22px; }}
        tr:last-child td {{ border-bottom: none; }}
        .totals {{ display: flex; gap: 24px; margin-top: 12px; color: #888; font-size: 13px; }}
        .totals b {{ color: #e0e0e0; }}
        .section-title {{ color: #e0e0e0; font-size: 16px; margin: 6px 0 10px; }}
        {generate_dropdown_css()}
    </style>
</head>
<body>
<div class="header">
    <div class="dropdown">
        <h1 class="dropdown-title">NGON Mining - Flowmeter Data</h1>
        <div class="dropdown-content">{generate_dropdown_html(AuthManager.get_user_access())}</div>
    </div>
</div>

<div class="content">
    <form method="get" id="filterForm" class="filter-bar">
        <div class="filter-group">
            <label>Site</label>
            <select name="site" onchange="document.getElementById('filterForm').submit()">{site_options}</select>
        </div>
        <div class="filter-group">
            <label>From</label>
            <input type="date" name="from" value="{esc(date_from)}">
        </div>
        <div class="filter-group">
            <label>To</label>
            <input type="date" name="to" value="{esc(date_to)}">
        </div>
        <button type="submit" class="btn">Apply</button>
        <button type="button" class="btn" onclick="exportCsv()"><i class="fas fa-download"></i> CSV</button>
    </form>

    <div class="live-card" id="liveCard" data-site="{esc(site)}">
        <div class="live-head">
            <h3>Live — {esc(site) or '(no site)'}</h3>
            <span class="live-badge {'on' if live_fresh else 'off'}" id="liveBadge">
                {('<i class="fas fa-wifi"></i> LIVE · ' + (f'{int(live_age)}s ago' if live_age is not None else '')) if live_fresh else 'no live data'}
            </span>
        </div>
        <div class="live-grid" id="liveGrid">
            <div class="metric"><div class="v">…</div><div class="l">loading</div></div>
        </div>
    </div>

    <div class="section-title">Daily Usage (accumulated volume per day)</div>
    <table>
        <thead><tr><th>Date</th><th style="text-align:right">Volume (MCF)</th></tr></thead>
        <tbody>{table_rows}</tbody>
    </table>
    <div class="totals">
        <span>Days: <b>{len(rows)}</b></span>
        <span>Total: <b>{total_mcf:,.2f} MCF</b></span>
        <span>Avg/day: <b>{avg_mcf:,.2f} MCF</b></span>
    </div>
</div>

<script>
{generate_dropdown_js()}

function fmt(v, dp) {{ return (v === null || v === undefined) ? '—' : Number(v).toLocaleString(undefined, {{minimumFractionDigits: dp, maximumFractionDigits: dp}}); }}

function renderLive(d) {{
    const grid = document.getElementById('liveGrid');
    const badge = document.getElementById('liveBadge');
    if (!d || !d.has_data) {{
        badge.className = 'live-badge off'; badge.textContent = 'no live data';
        grid.innerHTML = '<div class="metric"><div class="v">—</div><div class="l">no readings</div></div>';
        return;
    }}
    if (d.fresh) {{
        badge.className = 'live-badge on';
        badge.innerHTML = '<i class="fas fa-wifi"></i> LIVE · ' + Math.round(d.age_sec) + 's ago';
    }} else {{
        badge.className = 'live-badge off';
        badge.textContent = 'stale (' + Math.round(d.age_sec) + 's ago)';
    }}
    grid.innerHTML = `
        <div class="metric"><div class="v flow">${{fmt(d.flow_mcfd,0)}}</div><div class="l">Flow MCF/d</div></div>
        <div class="metric"><div class="v">${{fmt(d.sp_psia,1)}}</div><div class="l">Static PSIA</div></div>
        <div class="metric"><div class="v">${{fmt(d.dp_inh2o,1)}}</div><div class="l">Diff inH₂O</div></div>
        <div class="metric"><div class="v">${{fmt(d.temp_f,1)}}</div><div class="l">Temp °F</div></div>
        <div class="metric"><div class="v">${{fmt(d.vol_today_mcf,1)}}</div><div class="l">Today MCF</div></div>
        <div class="metric"><div class="v">${{fmt(d.vol_yesterday_mcf,1)}}</div><div class="l">Yesterday MCF</div></div>`;
}}

function refreshLive() {{
    const site = document.getElementById('liveCard').dataset.site;
    if (!site) return;
    fetch('flowmeter_data.py?ajax=live&site=' + encodeURIComponent(site))
        .then(r => r.json()).then(renderLive).catch(() => {{}});
}}

function exportCsv() {{
    const f = document.getElementById('filterForm');
    const q = new URLSearchParams({{
        site: f.site.value, from: f.from.value, to: f.to.value, export: 'csv'
    }});
    window.location = 'flowmeter_data.py?' + q.toString();
}}

refreshLive();
setInterval(refreshLive, 30000);
</script>
</body>
</html>""")
