"""
GA4 Analytics report for Portfolio Journal
Property: 300195945
"""

import os
from datetime import date, timedelta
from google.analytics.data_v1beta import BetaAnalyticsDataClient
from google.analytics.data_v1beta.types import (
    RunReportRequest, Dimension, Metric, DateRange, OrderBy, FilterExpression, Filter
)

PROPERTY_ID = "519342587"

import subprocess, json, tempfile

def _fix_multiline_json(raw):
    result, in_string, escape_next = [], False, False
    for c in raw:
        if escape_next:
            result.append(c); escape_next = False
        elif c == '\\':
            result.append(c); escape_next = True
        elif c == '"':
            in_string = not in_string; result.append(c)
        elif in_string and c == '\n':
            result.append('\\n')
        elif in_string and c == '\r':
            pass
        else:
            result.append(c)
    return ''.join(result)

key_raw = subprocess.check_output(["pass", "show", "google/sirius-service-account"]).decode()
key_json = json.dumps(json.loads(_fix_multiline_json(key_raw)))
_tmp = tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False)
_tmp.write(key_json); _tmp.flush()
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = _tmp.name
client = BetaAnalyticsDataClient()

TODAY = date.today().isoformat()
D7  = (date.today() - timedelta(days=7)).isoformat()
D28 = (date.today() - timedelta(days=28)).isoformat()
D90 = (date.today() - timedelta(days=90)).isoformat()

def run(dimensions, metrics, date_from, date_to=TODAY, order_by=None, limit=20):
    req = RunReportRequest(
        property=f"properties/{PROPERTY_ID}",
        dimensions=[Dimension(name=d) for d in dimensions],
        metrics=[Metric(name=m) for m in metrics],
        date_ranges=[DateRange(start_date=date_from, end_date=date_to)],
        limit=limit,
    )
    if order_by:
        req.order_bys = order_by
    return client.run_report(req)

def run_no_dim(metrics, date_from, date_to=TODAY):
    req = RunReportRequest(
        property=f"properties/{PROPERTY_ID}",
        metrics=[Metric(name=m) for m in metrics],
        date_ranges=[DateRange(start_date=date_from, end_date=date_to)],
    )
    return client.run_report(req)

def header(title):
    print(f"\n{'='*60}")
    print(f"  {title}")
    print('='*60)

def fmt_row(row, widths):
    parts = [str(v.value).ljust(w) for v, w in zip(list(row.dimension_values) + list(row.metric_values), widths)]
    print("  " + "  ".join(parts))

# ── 1. Overview ────────────────────────────────────────────────
header("OVERVIEW — últimos 28 días vs 7 días")

r28 = run_no_dim(["activeUsers", "sessions", "screenPageViews", "averageSessionDuration"], D28)
r7  = run_no_dim(["activeUsers", "sessions", "screenPageViews", "averageSessionDuration"], D7)

def ovw(r):
    row = r.rows[0]
    vals = [v.value for v in row.metric_values]
    return vals

v28 = ovw(r28)
v7  = ovw(r7)
labels = ["Usuarios activos", "Sesiones", "Pantallas vistas", "Duración media (s)"]
print(f"\n  {'Métrica':<30} {'28d':>10} {'7d':>10}")
print("  " + "-"*52)
for l, a, b in zip(labels, v28, v7):
    print(f"  {l:<30} {a:>10} {b:>10}")

# ── 2. Pantallas más visitadas ──────────────────────────────────
header("PANTALLAS MÁS VISITADAS — últimos 28d")
r = run(["unifiedScreenName"], ["screenPageViews", "activeUsers"], D28,
        order_by=[OrderBy(metric=OrderBy.MetricOrderBy(metric_name="screenPageViews"), desc=True)])
print(f"\n  {'Pantalla':<40} {'Vistas':>8} {'Usuarios':>10}")
print("  " + "-"*60)
for row in r.rows:
    fmt_row(row, [40, 8, 10])

# ── 3. Eventos clave ────────────────────────────────────────────
header("EVENTOS CLAVE — últimos 28d")
r = run(["eventName"], ["eventCount", "totalUsers"], D28,
        order_by=[OrderBy(metric=OrderBy.MetricOrderBy(metric_name="eventCount"), desc=True)],
        limit=30)
print(f"\n  {'Evento':<45} {'Count':>8} {'Usuarios':>10}")
print("  " + "-"*65)
for row in r.rows:
    fmt_row(row, [45, 8, 10])

# ── 4. Funnel paywall ───────────────────────────────────────────
header("FUNNEL PAYWALL — últimos 90d")
paywall_events = [
    "paywall_shown", "purchase_attempt", "purchase_success", "purchase_failure",
    "restore_purchases"
]
r = run(["eventName"], ["eventCount", "totalUsers"], D90,
        order_by=[OrderBy(metric=OrderBy.MetricOrderBy(metric_name="eventCount"), desc=True)],
        limit=50)
print(f"\n  {'Evento paywall':<40} {'Count':>8} {'Usuarios':>10}")
print("  " + "-"*60)
for row in r.rows:
    name = row.dimension_values[0].value
    if any(p in name for p in ["paywall", "purchase", "restore", "premium"]):
        fmt_row(row, [40, 8, 10])

# ── 5. Triggers del paywall ─────────────────────────────────────
header("TRIGGERS DEL PAYWALL — últimos 90d (qué feature lo dispara)")
try:
    r = run(["eventName", "customEvent:paywall_trigger"], ["eventCount"], D90,
            order_by=[OrderBy(metric=OrderBy.MetricOrderBy(metric_name="eventCount"), desc=True)],
            limit=30)
    rows = [row for row in r.rows if "paywall" in row.dimension_values[0].value]
    if rows:
        print(f"\n  {'Evento':<30} {'Trigger':<25} {'Count':>8}")
        print("  " + "-"*65)
        for row in rows:
            fmt_row(row, [30, 25, 8])
    else:
        print("\n  (sin eventos paywall con trigger en este periodo — los datos aparecerán desde hoy)")
except Exception as e:
    print(f"\n  Error: {e}")

# ── 6. Retención — nuevos vs recurrentes ───────────────────────
header("NUEVOS vs RECURRENTES — últimos 28d")
r = run(["newVsReturning"], ["activeUsers", "sessions", "screenPageViews"], D28,
        order_by=[OrderBy(metric=OrderBy.MetricOrderBy(metric_name="activeUsers"), desc=True)])
print(f"\n  {'Tipo':<20} {'Usuarios':>10} {'Sesiones':>10} {'Pantallas':>10}")
print("  " + "-"*54)
for row in r.rows:
    fmt_row(row, [20, 10, 10, 10])

# ── 7. Versiones de app ─────────────────────────────────────────
header("VERSIONES EN USO — últimos 28d")
r = run(["appVersion"], ["activeUsers", "sessions"], D28,
        order_by=[OrderBy(metric=OrderBy.MetricOrderBy(metric_name="activeUsers"), desc=True)],
        limit=10)
print(f"\n  {'Versión':<20} {'Usuarios':>10} {'Sesiones':>10}")
print("  " + "-"*44)
for row in r.rows:
    fmt_row(row, [20, 10, 10])

# ── 8. Dispositivos ─────────────────────────────────────────────
header("DISPOSITIVOS — últimos 28d")
r = run(["deviceModel"], ["activeUsers"], D28,
        order_by=[OrderBy(metric=OrderBy.MetricOrderBy(metric_name="activeUsers"), desc=True)],
        limit=10)
print(f"\n  {'Dispositivo':<30} {'Usuarios':>10}")
print("  " + "-"*44)
for row in r.rows:
    fmt_row(row, [30, 10])

# ── 9. País / región ────────────────────────────────────────────
header("PAÍSES — últimos 28d")
r = run(["country"], ["activeUsers"], D28,
        order_by=[OrderBy(metric=OrderBy.MetricOrderBy(metric_name="activeUsers"), desc=True)],
        limit=10)
print(f"\n  {'País':<30} {'Usuarios':>10}")
print("  " + "-"*44)
for row in r.rows:
    fmt_row(row, [30, 10])

print("\n")
