"""
DEWA PR Tracker — Streamlit Dashboard
Run:  streamlit run dashboard.py
"""
import math
import re as _re
from datetime import datetime, timedelta

import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
import streamlit as st

import database as db
from config import (
    COST_PER_PODCAST_OLD_AED,
    NOTEBOOKLM_MONTHLY_USD,
    NOTEBOOKLM_START_DATE,
    USD_TO_AED,
    DASHBOARD_TITLE,
    PAGE_SIZE,
)

# ── Page setup ────────────────────────────────────────────────────────────────
st.set_page_config(
    page_title=DASHBOARD_TITLE,
    page_icon="📰",
    layout="wide",
    initial_sidebar_state="collapsed",   # collapsed by default on mobile
)

# ── SVG helpers ───────────────────────────────────────────────────────────────
def _svg(paths, size=16, color="#0077b6"):
    return (
        f'<svg xmlns="http://www.w3.org/2000/svg" width="{size}" height="{size}" '
        f'viewBox="0 0 24 24" fill="none" stroke="{color}" stroke-width="2" '
        f'stroke-linecap="round" stroke-linejoin="round" '
        f'style="vertical-align:middle;margin-right:6px;flex-shrink:0">{paths}</svg>'
    )

# Icon paths
_P_DOC  = '<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/>'
_P_MIC  = '<path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" y1="19" x2="12" y2="23"/><line x1="8" y1="23" x2="16" y2="23"/>'
_P_COIN = '<line x1="12" y1="1" x2="12" y2="23"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/>'
_P_BAR  = '<line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/>'
_P_LIST = '<line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/>'
_P_CAL  = '<rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/>'
_P_LINK = '<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>'
_P_CLK  = '<circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>'
_P_WAVE = '<polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/>'
_P_SYNC = '<polyline points="23 4 23 10 17 10"/><polyline points="1 20 1 14 7 14"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/>'

def section_title(icon_path, text, icon_color="#0077b6"):
    st.markdown(
        f'<h3 style="display:flex;align-items:center;color:#0f172a;'
        f'margin-bottom:.5rem;margin-top:1.5rem;font-size:1.1rem;font-weight:700">'
        f'{_svg(icon_path, size=18, color=icon_color)}{text}</h3>',
        unsafe_allow_html=True,
    )

# ── CSS — light theme + mobile ────────────────────────────────────────────────
st.markdown("""
<style>
    /* ── Hide Streamlit chrome ── */
    [data-testid="stToolbar"],
    [data-testid="stDecoration"],
    [data-testid="stHeader"],
    header, #MainMenu, footer { display:none !important; visibility:hidden !important; }

    /* ── Base ── */
    html, body, .stApp        { background:#f0f4f8 !important; font-family:'Inter',sans-serif; }
    h1,h2,h3,h4               { color:#0f172a !important; }
    p, li                     { color:#475569; }
    .stDivider                { border-color:#e2e8f0 !important; }
    .block-container           { padding-top:1.5rem !important; padding-bottom:3rem !important; }

    /* ── Sidebar ── */
    [data-testid="stSidebar"]                   { background:#ffffff !important; border-right:1px solid #e2e8f0; }
    [data-testid="stSidebar"] label             { color:#64748b !important; font-size:.85rem; }
    [data-testid="stSidebar"] .stButton>button  {
        background:#f1f5f9; border:1px solid #e2e8f0; color:#0f172a;
        border-radius:8px; font-weight:500; transition:all .15s; width:100%;
    }
    [data-testid="stSidebar"] .stButton>button:hover { background:#e0f2fe; border-color:#0077b6; color:#0077b6; }

    /* ── KPI cards ── */
    .kpi-grid {
        display:grid;
        grid-template-columns: repeat(5, 1fr);
        gap:12px;
        margin-bottom:8px;
    }
    @media (max-width:900px)  { .kpi-grid { grid-template-columns: repeat(3,1fr); } }
    @media (max-width:600px)  { .kpi-grid { grid-template-columns: repeat(2,1fr); } }

    .kpi-card {
        background:#ffffff;
        border:1px solid #e2e8f0;
        border-radius:14px;
        padding:18px 16px 14px;
        position:relative;
        overflow:hidden;
        box-shadow:0 1px 3px rgba(0,0,0,.06);
        transition:box-shadow .2s, border-color .2s;
    }
    .kpi-card:hover              { box-shadow:0 4px 12px rgba(0,0,0,.1); border-color:#bfdbfe; }
    .kpi-card::before            { content:""; position:absolute; top:0; left:0; right:0; height:3px; border-radius:14px 14px 0 0; }
    .kpi-card.blue::before       { background:#0077b6; }
    .kpi-card.green::before      { background:#16a34a; }
    .kpi-card.amber::before      { background:#d97706; }
    .kpi-card.purple::before     { background:#7c3aed; }
    .kpi-card.rose::before       { background:#e11d48; }
    .kpi-label {
        font-size:.68rem; font-weight:700; letter-spacing:.06em;
        text-transform:uppercase; color:#94a3b8;
        display:flex; align-items:center; gap:4px; margin-bottom:8px;
    }
    .kpi-value { font-size:1.9rem; font-weight:800; color:#0f172a; line-height:1; }
    .kpi-sub   { font-size:.7rem; color:#94a3b8; margin-top:6px; line-height:1.4; }
    .kpi-delta-pos { color:#16a34a; font-weight:600; }
    .kpi-delta-neg { color:#e11d48; font-weight:600; }

    /* ── ROI summary cards ── */
    .roi-grid {
        display:grid;
        grid-template-columns:repeat(4,1fr);
        gap:12px;
        margin:12px 0 20px;
    }
    @media (max-width:900px)  { .roi-grid { grid-template-columns:repeat(2,1fr); } }
    @media (max-width:500px)  { .roi-grid { grid-template-columns:1fr; } }

    .roi-card {
        background:#ffffff;
        border:1px solid #e2e8f0;
        border-radius:14px;
        padding:18px 20px;
        box-shadow:0 1px 3px rgba(0,0,0,.06);
    }
    .roi-card-label { font-size:.68rem; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:#94a3b8; margin-bottom:8px; display:flex; align-items:center; gap:5px; }
    .cost-old  { font-size:1.5rem; font-weight:800; color:#e11d48; }
    .cost-new  { font-size:1.5rem; font-weight:800; color:#16a34a; }
    .savings   { font-size:1.5rem; font-weight:800; color:#d97706; }
    .roi-pct   { font-size:1.5rem; font-weight:800; color:#0077b6; }
    .roi-sub   { font-size:.72rem; color:#94a3b8; margin-top:6px; line-height:1.5; }

    /* ── ROI table ── */
    .tbl-wrap { overflow-x:auto; -webkit-overflow-scrolling:touch; }
    table.roi-table { width:100%; border-collapse:collapse; font-size:.82rem; min-width:480px; }
    table.roi-table th {
        background:#f8fafc; color:#64748b; font-weight:700;
        padding:10px 12px; text-align:right;
        border-bottom:2px solid #e2e8f0;
        font-size:.68rem; letter-spacing:.05em; text-transform:uppercase;
        white-space:nowrap;
    }
    table.roi-table th:first-child { text-align:left; }
    table.roi-table td {
        padding:9px 12px; text-align:right;
        border-bottom:1px solid #f1f5f9; color:#475569;
        white-space:nowrap;
    }
    table.roi-table td:first-child  { text-align:left; color:#0f172a; font-weight:600; }
    table.roi-table tr:hover td     { background:#f8fafc; }
    table.roi-table tr.total-row td {
        background:#f0f9ff; color:#0077b6; font-weight:800;
        border-top:2px solid #bae6fd; font-size:.88rem;
    }
    table.roi-table tr.total-row td:nth-child(5) { color:#e11d48; }
    table.roi-table tr.total-row td:nth-child(6) { color:#16a34a; }
    table.roi-table tr.total-row td:nth-child(7) { color:#d97706; }

    /* ── PR list rows ── */
    .pr-row {
        background:#ffffff; border:1px solid #e2e8f0; border-radius:12px;
        padding:14px 16px; margin-bottom:8px;
        transition:box-shadow .15s;
    }
    .pr-row:hover { box-shadow:0 2px 8px rgba(0,0,0,.08); }
    .pr-title   { font-size:.95rem; font-weight:600; color:#0f172a; text-decoration:none; }
    .pr-title:hover { color:#0077b6; }
    .pr-desc    { font-size:.78rem; color:#94a3b8; margin-top:3px; line-height:1.5; }
    .pr-date    { font-size:.75rem; color:#64748b; font-weight:500; white-space:nowrap; }
    .pr-badge   {
        display:inline-flex; align-items:center; gap:4px;
        background:#fff7ed; color:#c2410c; border:1px solid #fed7aa;
        border-radius:20px; padding:2px 10px; font-size:.7rem; font-weight:600;
        white-space:nowrap;
    }

    /* ── Podcast expander ── */
    [data-testid="stExpander"] {
        background:#ffffff; border:1px solid #e2e8f0 !important;
        border-radius:12px; margin-bottom:6px;
        box-shadow:0 1px 2px rgba(0,0,0,.04);
    }
    [data-testid="stExpander"] summary { color:#0f172a !important; font-weight:500; }

    /* ── Charts: white bg ── */
    .js-plotly-plot .plotly { border-radius:12px; }

    /* ── Tabs ── */
    [data-testid="stTabs"] [role="tab"]                       { color:#64748b !important; font-weight:500; font-size:.9rem; }
    [data-testid="stTabs"] [role="tab"][aria-selected="true"] { color:#0077b6 !important; font-weight:700; }

    /* ── DEWA logo ── */
    .dewa-logo { font-size:1.5rem; font-weight:900; letter-spacing:.1em; color:#0077b6; }
    .dewa-logo-sub { font-size:.6rem; color:#94a3b8; letter-spacing:.1em; text-transform:uppercase; margin-top:1px; }

    /* ── Mobile: collapse sidebar toggle hint ── */
    @media (max-width:768px) {
        .block-container { padding-left:1rem !important; padding-right:1rem !important; }
        .kpi-value       { font-size:1.5rem; }
        .cost-old, .cost-new, .savings, .roi-pct { font-size:1.2rem; }
    }
</style>
""", unsafe_allow_html=True)


# ── Data loading (cached 5 min) ───────────────────────────────────────────────
@st.cache_data(ttl=300)
def load_data():
    db.init_db()
    prs      = [dict(r) for r in db.get_all_press_releases()]
    pods     = [dict(r) for r in db.get_all_podcasts()]
    roi_rows = [dict(r) for r in db.get_roi_monthly_since(NOTEBOOKLM_START_DATE)]
    stats    = db.get_stats()
    log      = [dict(r) for r in db.get_scrape_log()]
    return prs, pods, roi_rows, stats, log


prs, pods, roi_rows, stats, scrape_log = load_data()
df_pr  = pd.DataFrame(prs)
df_pod = pd.DataFrame(pods)

if not df_pod.empty and "title" in df_pod.columns:
    df_pod["language"] = df_pod["title"].apply(
        lambda t: "ar" if _re.search(r"[\u0600-\u06FF]", str(t)) else "en"
    )
if not df_pr.empty:
    df_pr["date"]  = pd.to_datetime(df_pr["date"], errors="coerce")
    df_pr["week"]  = df_pr["date"].dt.to_period("W").astype(str)
    df_pr["month"] = df_pr["date"].dt.to_period("M").astype(str)
if not df_pod.empty:
    df_pod["date"] = pd.to_datetime(df_pod["date"], errors="coerce")

# ── ROI pre-calculations ──────────────────────────────────────────────────────
NOTEBOOKLM_AED = NOTEBOOKLM_MONTHLY_USD * USD_TO_AED
NLM_START      = pd.Timestamp(NOTEBOOKLM_START_DATE)

df_roi = pd.DataFrame(roi_rows) if roi_rows else pd.DataFrame(
    columns=["month","pr_count","en_episodes","ar_episodes","total_episodes"]
)
if not df_roi.empty:
    df_roi["old_cost"] = df_roi["pr_count"] * COST_PER_PODCAST_OLD_AED
    df_roi["new_cost"] = NOTEBOOKLM_AED
    df_roi["savings"]  = df_roi["old_cost"] - df_roi["new_cost"]
    total_prs_nlm  = int(df_roi["pr_count"].sum())
    total_old_cost = float(df_roi["old_cost"].sum())
    total_new_cost = float(df_roi["new_cost"].sum())
    total_savings  = float(df_roi["savings"].sum())
    roi_pct        = (total_savings / total_old_cost * 100) if total_old_cost > 0 else 0
else:
    total_prs_nlm = total_old_cost = total_new_cost = total_savings = roi_pct = 0


# ── Sidebar ───────────────────────────────────────────────────────────────────
with st.sidebar:
    st.markdown(
        '<div class="dewa-logo">DEWA</div>'
        '<div class="dewa-logo-sub">Dubai Electricity &amp; Water Authority</div>',
        unsafe_allow_html=True,
    )
    st.divider()

    if not df_pr.empty and df_pr["date"].notna().any():
        min_date = df_pr["date"].min().date()
        max_date = df_pr["date"].max().date()
    else:
        min_date = datetime(2019, 1, 1).date()
        max_date = datetime.today().date()

    date_from, date_to = st.date_input(
        "Date range",
        value=(NLM_START.date(), max_date),
        min_value=min_date, max_value=max_date,
    )
    categories = ["All"]
    if not df_pr.empty and "category" in df_pr.columns:
        cats = df_pr["category"].dropna().unique().tolist()
        categories += sorted(cats)
    selected_cat = st.selectbox("Category", categories)
    has_podcast_filter = st.checkbox("Show only PRs with podcast", value=False)

    st.divider()
    if st.button("Refresh data", use_container_width=True):
        st.cache_data.clear()
        st.rerun()
    if st.button("Run scraper now", use_container_width=True):
        with st.spinner("Scraping DEWA website…"):
            try:
                from scraper import run_scrape
                prs_n, pods_n = run_scrape()
                st.success(f"Done — {prs_n} PRs, {pods_n} podcasts saved.")
                st.cache_data.clear()
                st.rerun()
            except Exception as e:
                st.error(f"Scraper error: {e}")
    st.divider()

    last_scraped = stats.get('last_scraped','Never') or 'Never'
    st.caption(f"Last scraped: {last_scraped}")

    # ── Live countdown to next 08:00 Dubai time ───────────────────────────────
    st.markdown("""
<div style="background:#f0f9ff;border:1px solid #bae6fd;border-radius:10px;padding:12px 14px;margin-top:8px">
  <div style="font-size:.65rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:#0284c7;margin-bottom:6px">
    Next auto-refresh
  </div>
  <div style="display:flex;align-items:center;gap:6px">
    <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24"
      fill="none" stroke="#0284c7" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
      <circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>
    </svg>
    <span id="cd-timer" style="font-size:1.2rem;font-weight:800;color:#0f172a;letter-spacing:.04em">--:--:--</span>
  </div>
  <div style="font-size:.68rem;color:#64748b;margin-top:4px">Daily at 08:00 Dubai time</div>
</div>
<script>
(function() {
  function nextRefresh() {
    // Current time in Dubai (UTC+4)
    var now   = new Date();
    var dubai = new Date(now.toLocaleString("en-US", {timeZone:"Asia/Dubai"}));
    var next  = new Date(dubai);
    next.setHours(8, 0, 0, 0);
    if (dubai >= next) next.setDate(next.getDate() + 1);   // already past 08:00 today
    return next - dubai;   // ms remaining
  }
  function fmt(ms) {
    var s  = Math.floor(ms / 1000);
    var h  = Math.floor(s / 3600);
    var m  = Math.floor((s % 3600) / 60);
    var sc = s % 60;
    return [h,m,sc].map(function(v){return String(v).padStart(2,'0');}).join(':');
  }
  function tick() {
    var el = document.getElementById('cd-timer');
    if (!el) return;
    var ms = nextRefresh();
    el.textContent = fmt(ms);
    // Pulse red when < 5 minutes
    el.style.color = ms < 300000 ? '#e11d48' : '#0f172a';
  }
  tick();
  setInterval(tick, 1000);
})();
</script>
""", unsafe_allow_html=True)


# ── Apply filters ─────────────────────────────────────────────────────────────
filtered = df_pr.copy()
if not filtered.empty:
    if filtered["date"].notna().any():
        filtered = filtered[
            (filtered["date"].dt.date >= date_from) &
            (filtered["date"].dt.date <= date_to)
        ]
    if selected_cat != "All":
        filtered = filtered[filtered["category"] == selected_cat]
    if has_podcast_filter:
        filtered = filtered[filtered["podcast_count"] > 0]


# ═══════════════════════════════════════════════════════════════════════════════
# HEADER
# ═══════════════════════════════════════════════════════════════════════════════
st.markdown(
    f'<div style="display:flex;align-items:center;gap:12px;margin-bottom:2px">'
    f'{_svg(_P_DOC, size=30, color="#0077b6")}'
    f'<h1 style="color:#0f172a;margin:0;font-size:1.6rem;font-weight:800">{DASHBOARD_TITLE}</h1>'
    f'</div>'
    f'<p style="color:#94a3b8;font-size:.82rem;margin:4px 0 0 38px">'
    f'NotebookLM adoption since {NOTEBOOKLM_START_DATE} &nbsp;·&nbsp; '
    f'{datetime.today().strftime("%d %B %Y")}</p>',
    unsafe_allow_html=True,
)
st.markdown("<br>", unsafe_allow_html=True)


# ═══════════════════════════════════════════════════════════════════════════════
# KPI CARDS
# ═══════════════════════════════════════════════════════════════════════════════
today       = datetime.today().date()
week_start  = today - timedelta(days=today.weekday())
month_start = today.replace(day=1)
last_month  = (month_start - timedelta(days=1)).replace(day=1)

if not filtered.empty and filtered["date"].notna().any():
    prs_today      = len(filtered[filtered["date"].dt.date == today])
    prs_week       = len(filtered[filtered["date"].dt.date >= week_start])
    prs_month      = len(filtered[filtered["date"].dt.date >= month_start])
    prs_last_month = len(filtered[
        (filtered["date"].dt.date >= last_month) &
        (filtered["date"].dt.date <  month_start)
    ])
else:
    prs_today = prs_week = prs_month = prs_last_month = 0

prs_with_pod = len(filtered[filtered["podcast_count"] > 0]) if not filtered.empty else 0
coverage_pct = (prs_with_pod / len(filtered) * 100) if len(filtered) > 0 else 0
month_delta  = prs_month - prs_last_month
d_cls        = "kpi-delta-pos" if month_delta >= 0 else "kpi-delta-neg"
d_sign       = "+" if month_delta >= 0 else ""

def kpi_card(color, icon_path, label, value, sub="", icon_color=None):
    clr = icon_color or {"blue":"#0077b6","green":"#16a34a","amber":"#d97706","purple":"#7c3aed","rose":"#e11d48"}[color]
    ico = _svg(icon_path, size=13, color=clr)
    return (
        f'<div class="kpi-card {color}">'
        f'<div class="kpi-label">{ico}{label}</div>'
        f'<div class="kpi-value">{value}</div>'
        f'{"<div class=kpi-sub>" + sub + "</div>" if sub else ""}'
        f'</div>'
    )

st.markdown(
    f'<div class="kpi-grid">'
    f'{kpi_card("blue",  _P_DOC,  "Total Press Releases", f"{len(filtered):,}", f"since {date_from.strftime(chr(37)+chr(100)+chr(32)+chr(37)+chr(98)+chr(32)+chr(37)+chr(89))}")}'
    f'{kpi_card("green", _P_MIC,  "Podcast Coverage",     f"{coverage_pct:.1f}%", f"{prs_with_pod} of {len(filtered)} PRs", "#16a34a")}'
    f'{kpi_card("amber", _P_CAL,  "This Month",           f"{prs_month:,}", f"<span class={d_cls}>{d_sign}{month_delta} vs last month</span>", "#d97706")}'
    f'{kpi_card("purple",_P_WAVE, "This Week",            f"{prs_week:,}", f"since {week_start.strftime(chr(37)+chr(100)+chr(32)+chr(37)+chr(98))}", "#7c3aed")}'
    f'{kpi_card("rose",  _P_CLK,  "Today",               f"{prs_today:,}", today.strftime("%d %B %Y"), "#e11d48")}'
    f'</div>',
    unsafe_allow_html=True,
)
st.markdown("<br>", unsafe_allow_html=True)
st.divider()


# ═══════════════════════════════════════════════════════════════════════════════
# ROI — NotebookLM
# ═══════════════════════════════════════════════════════════════════════════════
section_title(_P_COIN, "NotebookLM ROI — Since 23 May 2025", "#16a34a")

months_active = len(df_roi)
st.markdown(
    f'<div class="roi-grid">'
    f'<div class="roi-card" style="border-top:3px solid #fecdd3">'
    f'<div class="roi-card-label">{_svg(_P_CLK, 13, "#e11d48")}Traditional Cost</div>'
    f'<div class="cost-old">AED {total_old_cost:,.0f}</div>'
    f'<div class="roi-sub">{total_prs_nlm} PRs × AED {COST_PER_PODCAST_OLD_AED:,}/podcast</div>'
    f'</div>'
    f'<div class="roi-card" style="border-top:3px solid #bbf7d0">'
    f'<div class="roi-card-label">{_svg(_P_MIC, 13, "#16a34a")}NotebookLM Cost</div>'
    f'<div class="cost-new">AED {total_new_cost:,.0f}</div>'
    f'<div class="roi-sub">{months_active} months × AED {NOTEBOOKLM_AED:.0f}/mo (${NOTEBOOKLM_MONTHLY_USD})</div>'
    f'</div>'
    f'<div class="roi-card" style="border-top:3px solid #fde68a">'
    f'<div class="roi-card-label">{_svg(_P_COIN, 13, "#d97706")}Total Savings</div>'
    f'<div class="savings">AED {total_savings:,.0f}</div>'
    f'<div class="roi-sub">Since {NOTEBOOKLM_START_DATE}</div>'
    f'</div>'
    f'<div class="roi-card" style="border-top:3px solid #bae6fd">'
    f'<div class="roi-card-label">{_svg(_P_BAR, 13, "#0077b6")}Return on Investment</div>'
    f'<div class="roi-pct">{roi_pct:.1f}%</div>'
    f'<div class="roi-sub">Savings ÷ traditional cost</div>'
    f'</div>'
    f'</div>',
    unsafe_allow_html=True,
)

# ── Charts + table ────────────────────────────────────────────────────────────
if not df_roi.empty:
    chart_col, table_col = st.columns([3, 2], gap="medium")

    PLOT_LAYOUT = dict(
        paper_bgcolor="#ffffff", plot_bgcolor="#ffffff",
        font_color="#0f172a", font_size=12,
        legend_title_text="",
        margin=dict(t=40, b=10, l=10, r=10),
        xaxis=dict(showgrid=False, title="", tickfont=dict(size=11)),
        yaxis=dict(gridcolor="#f1f5f9", title="AED", tickfont=dict(size=11)),
    )

    with chart_col:
        df_cl = df_roi[["month","old_cost","new_cost"]].melt(
            id_vars="month", var_name="Type", value_name="AED"
        )
        df_cl["Type"] = df_cl["Type"].map({
            "old_cost": "Traditional (AED 20k/podcast)",
            "new_cost": "NotebookLM ($20/month)"
        })
        fig1 = px.bar(df_cl, x="month", y="AED", color="Type", barmode="group",
            color_discrete_map={
                "Traditional (AED 20k/podcast)": "#fca5a5",
                "NotebookLM ($20/month)":         "#86efac",
            },
            title="Monthly Cost: Traditional vs NotebookLM",
        )
        fig1.update_layout(**PLOT_LAYOUT, height=300)
        st.plotly_chart(fig1, use_container_width=True)

        fig2 = px.bar(df_roi, x="month", y="pr_count",
            color_discrete_sequence=["#93c5fd"],
            title="Press Releases with Podcasts per Month",
        )
        fig2.update_layout(**{**PLOT_LAYOUT, "yaxis": dict(gridcolor="#f1f5f9", title="PRs", tickfont=dict(size=11))}, height=260)
        st.plotly_chart(fig2, use_container_width=True)

    with table_col:
        st.markdown(
            '<p style="font-size:.78rem;color:#94a3b8;margin-bottom:8px">'
            'AED 20,000 per PR podcast production (EN + AR = one production unit). '
            'NotebookLM billed as flat $20/month.</p>',
            unsafe_allow_html=True,
        )
        rows_html = ""
        for _, r in df_roi.iterrows():
            rows_html += (
                f'<tr>'
                f'<td>{r["month"]}</td>'
                f'<td>{int(r["pr_count"])}</td>'
                f'<td>{int(r["en_episodes"])}</td>'
                f'<td>{int(r["ar_episodes"])}</td>'
                f'<td style="color:#e11d48">AED {r["old_cost"]:,.0f}</td>'
                f'<td style="color:#16a34a">AED {r["new_cost"]:,.0f}</td>'
                f'<td style="color:#d97706">AED {r["savings"]:,.0f}</td>'
                f'</tr>'
            )
        rows_html += (
            f'<tr class="total-row">'
            f'<td>TOTAL</td>'
            f'<td>{total_prs_nlm}</td>'
            f'<td>{int(df_roi["en_episodes"].sum())}</td>'
            f'<td>{int(df_roi["ar_episodes"].sum())}</td>'
            f'<td>AED {total_old_cost:,.0f}</td>'
            f'<td>AED {total_new_cost:,.0f}</td>'
            f'<td>AED {total_savings:,.0f}</td>'
            f'</tr>'
        )
        st.markdown(
            f'<div class="tbl-wrap">'
            f'<table class="roi-table"><thead><tr>'
            f'<th>Month</th><th>PRs</th><th>EN</th><th>AR</th>'
            f'<th>Old Cost</th><th>New Cost</th><th>Savings</th>'
            f'</tr></thead><tbody>{rows_html}</tbody></table>'
            f'</div>',
            unsafe_allow_html=True,
        )

st.divider()


# ═══════════════════════════════════════════════════════════════════════════════
# PUBLICATION TRENDS
# ═══════════════════════════════════════════════════════════════════════════════
section_title(_P_BAR, "Publication Trends", "#7c3aed")
tab_daily, tab_weekly, tab_monthly = st.tabs(["Daily", "Weekly", "Monthly"])

TREND_LAYOUT = dict(
    paper_bgcolor="#ffffff", plot_bgcolor="#ffffff",
    font_color="#0f172a", margin=dict(t=36,b=10,l=10,r=10),
    xaxis=dict(showgrid=False, title=""),
    yaxis=dict(gridcolor="#f1f5f9"),
)

def trend_bar(df_g, x, y, title, color):
    fig = px.bar(df_g, x=x, y=y, title=title, color_discrete_sequence=[color])
    fig.update_layout(**TREND_LAYOUT)
    return fig

with tab_daily:
    if not filtered.empty and filtered["date"].notna().any():
        daily = filtered.groupby(filtered["date"].dt.date).size().reset_index(name="count")
        daily.columns = ["date","count"]
        st.plotly_chart(trend_bar(daily,"date","count","Press Releases per Day","#93c5fd"), use_container_width=True)
    else:
        st.info("No data yet.")

with tab_weekly:
    if not filtered.empty and "week" in filtered.columns and filtered["date"].notna().any():
        weekly = filtered.groupby("week").size().reset_index(name="count")
        st.plotly_chart(trend_bar(weekly,"week","count","Press Releases per Week","#a5b4fc"), use_container_width=True)
    else:
        st.info("No data yet.")

with tab_monthly:
    if not filtered.empty and "month" in filtered.columns and filtered["date"].notna().any():
        monthly = filtered.groupby("month").size().reset_index(name="count")
        st.plotly_chart(trend_bar(monthly,"month","count","Press Releases per Month","#c4b5fd"), use_container_width=True)
    else:
        st.info("No data yet.")

st.divider()


# ═══════════════════════════════════════════════════════════════════════════════
# PRESS RELEASES TABLE
# ═══════════════════════════════════════════════════════════════════════════════
section_title(_P_LIST, "Press Releases", "#0077b6")

search = st.text_input("Search", placeholder="Filter press releases by title…", label_visibility="collapsed")
display = (
    filtered[filtered["title"].str.contains(search, case=False, na=False)]
    if search else filtered.copy()
)

total_pages = max(1, math.ceil(len(display) / PAGE_SIZE))
page_num    = st.number_input("Page", min_value=1, max_value=total_pages, value=1, step=1)
start, end  = (page_num-1)*PAGE_SIZE, page_num*PAGE_SIZE
page_data   = display.iloc[start:end]

st.caption(f"Showing {start+1}–{min(end,len(display))} of {len(display)} results  (page {page_num}/{total_pages})")

for _, row in page_data.iterrows():
    url   = row.get("url","")
    title = row.get("title","—")
    d     = row.get("date")
    date_str = d.strftime("%d %b %Y") if pd.notna(d) else "—"
    desc  = str(row.get("description") or "")
    desc_short = (desc[:150]+"…") if len(desc)>150 else desc
    pod_badge = (
        f'<span class="pr-badge">{_svg(_P_MIC,11,"#c2410c")} Podcast</span>'
        if row.get("podcast_count",0) else ""
    )
    st.markdown(
        f'<div class="pr-row">'
        f'<div style="display:flex;justify-content:space-between;align-items:flex-start;gap:12px;flex-wrap:wrap">'
        f'<a class="pr-title" href="{url}" target="_blank">{title}</a>'
        f'<div style="display:flex;align-items:center;gap:8px;flex-shrink:0">'
        f'<span class="pr-date">{date_str}</span>{pod_badge}'
        f'</div></div>'
        f'{"<div class=pr-desc>" + desc_short + "</div>" if desc_short else ""}'
        f'</div>',
        unsafe_allow_html=True,
    )


# ═══════════════════════════════════════════════════════════════════════════════
# PODCASTS
# ═══════════════════════════════════════════════════════════════════════════════
st.divider()
section_title(_P_MIC, "Podcasts", "#d97706")

if not df_pod.empty:
    lang_filter = st.radio("Language", ["All","English","Arabic"], horizontal=True)
    df_show = df_pod.copy()
    if lang_filter == "English":
        df_show = df_show[df_show["language"]=="en"]
    elif lang_filter == "Arabic":
        df_show = df_show[df_show["language"]=="ar"]

    pod_q = st.text_input("Search podcasts", placeholder="Filter by title…", label_visibility="collapsed")
    if pod_q:
        df_show = df_show[df_show["title"].str.contains(pod_q, case=False, na=False)]

    st.caption(f"Showing {len(df_show)} of {len(df_pod)} episodes")

    for _, pod in df_show.head(50).iterrows():
        with st.expander(f"{pod.get('title','—')}  ·  {pod.get('date','')}"):
            ca, cb = st.columns([3,1])
            with ca:
                if pod.get("pr_title"):
                    st.markdown(f"**Linked PR:** {pod['pr_title']}")
                if pod.get("url"):
                    st.markdown(f"[Open on RSS.com]({pod['url']})")
                if pod.get("audio_url"):
                    st.audio(pod["audio_url"])
            with cb:
                if pod.get("duration"):
                    st.metric("Duration", pod["duration"])
                st.metric("Saved", f"AED {COST_PER_PODCAST_OLD_AED:,}")


# ═══════════════════════════════════════════════════════════════════════════════
# SCRAPE LOG
# ═══════════════════════════════════════════════════════════════════════════════
st.divider()
with st.expander("Scrape history"):
    if scrape_log:
        st.dataframe(
            pd.DataFrame(scrape_log)[["ran_at","prs_found","pods_found","status","notes"]],
            use_container_width=True,
        )
    else:
        st.info("No scrape runs recorded yet.")

st.markdown(
    '<p style="text-align:center;color:#cbd5e1;font-size:.75rem;margin-top:2rem">'
    'DEWA PR Tracker · Playwright · SQLite · Streamlit</p>',
    unsafe_allow_html=True,
)
