<?php
/**
 * Stories API — Aggregates news, sports, and events with images for hero carousel.
 * Sources: WLWT RSS + NewsAPI, ESPN, TicketMaster
 */
require_once __DIR__ . '/../config/auth.php';
requireLogin();

$cacheFile = __DIR__ . '/../uploads/stories_cache.json';
if (file_exists($cacheFile) && (time() - filemtime($cacheFile)) < 1800) {
    header('Content-Type: application/json');
    readfile($cacheFile);
    exit;
}

$stories = [];

function fetchUrl($url) {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 8,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_ENCODING       => '',  // handles gzip/deflate automatically
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_USERAGENT      => 'CFDPortal/1.0',
    ]);
    $result = curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    return ($code >= 200 && $code < 400) ? $result : false;
}

// ── 1. WLWT RSS — local Cincinnati news with media images ───
$rssResp = fetchUrl('https://www.wlwt.com/topstories-rss');
if ($rssResp) {
    libxml_use_internal_errors(true);
    $rss = @simplexml_load_string($rssResp);
    if ($rss) {
        $ns = $rss->getNamespaces(true);
        foreach (($rss->channel->item ?? []) as $item) {
            $title = (string)($item->title ?? '');
            if (!$title) continue;

            // Get media image from media:content or media:thumbnail
            $img = '';
            if (isset($ns['media'])) {
                $media = $item->children($ns['media']);
                if (isset($media->content)) {
                    $img = (string)$media->content->attributes()->url;
                } elseif (isset($media->thumbnail)) {
                    $img = (string)$media->thumbnail->attributes()->url;
                }
            }
            // Try enclosure as fallback
            if (!$img && isset($item->enclosure)) {
                $img = (string)$item->enclosure->attributes()->url;
            }
            if (!$img) continue; // Skip stories without images

            $stories[] = [
                'title'    => $title,
                'subtitle' => (string)($item->description ?? ''),
                'image'    => $img,
                'source'   => 'WLWT',
                'url'      => (string)($item->link ?? ''),
                'category' => 'news',
                'time'     => (string)($item->pubDate ?? ''),
            ];
        }
    }
}

// ── 2. NewsAPI — Cincinnati news with images (fallback) ─────
$newsKey = env('NEWSAPI_KEY', '');
if ($newsKey && count($stories) < 5) {
    $resp = fetchUrl("https://newsapi.org/v2/everything?q=Cincinnati&sortBy=publishedAt&pageSize=8&language=en&apiKey={$newsKey}");
    if ($resp) {
        $data = json_decode($resp, true);
        foreach (($data['articles'] ?? []) as $a) {
            $img = $a['urlToImage'] ?? '';
            $title = $a['title'] ?? '';
            if (!$img || !$title || $title === '[Removed]') continue;
            $stories[] = [
                'title'    => $title,
                'subtitle' => $a['description'] ?? '',
                'image'    => $img,
                'source'   => $a['source']['name'] ?? 'News',
                'url'      => $a['url'] ?? '',
                'category' => 'news',
                'time'     => $a['publishedAt'] ?? '',
            ];
        }
    }
}

// ── 2b. WCPO — second Cincinnati TV station ─────────────────
$wcpoResp = fetchUrl('https://www.wcpo.com/news/local-news.rss');
if ($wcpoResp) {
    libxml_use_internal_errors(true);
    $rss = @simplexml_load_string($wcpoResp);
    if ($rss) {
        $ns = $rss->getNamespaces(true);
        $count = 0;
        foreach (($rss->channel->item ?? []) as $item) {
            if ($count >= 5) break;
            $title = (string)($item->title ?? '');
            if (!$title) continue;
            $img = '';
            if (isset($ns['media'])) {
                $media = $item->children($ns['media']);
                if (isset($media->content)) $img = (string)$media->content->attributes()->url;
                elseif (isset($media->thumbnail)) $img = (string)$media->thumbnail->attributes()->url;
            }
            if (!$img && isset($item->enclosure)) $img = (string)$item->enclosure->attributes()->url;
            if (!$img) $img = 'https://ewscripps.brightspotcdn.com/dims4/default/82e53b3/2147483647/strip/true/crop/1280x720+0+0/resize/1280x720!/quality/90/?url=http%3A%2F%2Fewscripps-brightspot.s3.amazonaws.com%2Fe5%2F59%2F18ba6c3d4bdba0d5f42f7d7f96f1%2Fwcpo-logo.png';
            $stories[] = [
                'title'    => $title,
                'subtitle' => (string)($item->description ?? ''),
                'image'    => $img,
                'source'   => 'WCPO',
                'url'      => (string)($item->link ?? ''),
                'category' => 'news',
                'time'     => (string)($item->pubDate ?? ''),
            ];
            $count++;
        }
    }
}

// ── 3. Fire/EMS News — FireEngineering + STATter911 + IAFF + JEMS ──
$fireFeeds = [
    ['url' => 'https://www.fireengineering.com/feed/', 'source' => 'Fire Engineering', 'imgType' => 'media'],
    ['url' => 'https://statter911.com/feed/', 'source' => 'STATter911', 'imgType' => 'content'],
    ['url' => 'https://www.iaff.org/feed/', 'source' => 'IAFF', 'imgType' => 'media', 'fallbackImg' => 'https://www.iaff.org/wp-content/uploads/2023/04/IAFF-building.jpg'],
    ['url' => 'https://www.jems.com/feed/', 'source' => 'JEMS', 'imgType' => 'content', 'fallbackImg' => 'https://www.jems.com/wp-content/uploads/2020/09/Paramedic.jpeg'],
];
foreach ($fireFeeds as $feed) {
    $rssResp = fetchUrl($feed['url']);
    if (!$rssResp) continue;
    libxml_use_internal_errors(true);
    $rss = @simplexml_load_string($rssResp);
    if (!$rss) continue;
    $ns = $rss->getNamespaces(true);
    $count = 0;
    foreach (($rss->channel->item ?? []) as $item) {
        if ($count >= 4) break;
        $title = (string)($item->title ?? '');
        if (!$title) continue;

        $img = '';
        if ($feed['imgType'] === 'media' && isset($ns['media'])) {
            $media = $item->children($ns['media']);
            if (isset($media->content)) $img = (string)$media->content->attributes()->url;
        }
        if (!$img) {
            $content = (string)($item->children('content', true)->encoded ?? '');
            if (preg_match('/src=["\']?(https?:\/\/[^"\'>\s]+\.(?:jpg|jpeg|png))/i', $content, $m)) {
                $img = $m[1];
            }
        }
        if (!$img && !empty($feed['fallbackImg'])) $img = $feed['fallbackImg'];
        if (!$img) continue;

        $stories[] = [
            'title'    => trim(html_entity_decode(strip_tags($title), ENT_QUOTES, 'UTF-8')),
            'subtitle' => trim(html_entity_decode(strip_tags((string)($item->description ?? '')), ENT_QUOTES, 'UTF-8')),
            'image'    => $img,
            'source'   => $feed['source'],
            'url'      => (string)($item->link ?? ''),
            'category' => 'fire',
            'time'     => (string)($item->pubDate ?? ''),
        ];
        $count++;
    }
}

// ── 4. ESPN — MLB, NFL, MLS headlines ───────────────────────
$espnFeeds = [
    ['url' => 'https://site.api.espn.com/apis/site/v2/sports/baseball/mlb/news?limit=5', 'sport' => 'MLB'],
    ['url' => 'https://site.api.espn.com/apis/site/v2/sports/football/nfl/news?limit=5', 'sport' => 'NFL'],
];

foreach ($espnFeeds as $feed) {
    $resp = fetchUrl($feed['url']);
    if (!$resp) continue;
    $data = json_decode($resp, true);
    foreach (($data['articles'] ?? []) as $a) {
        $headline = $a['headline'] ?? '';
        $desc = $a['description'] ?? '';

        $img = '';
        foreach (($a['images'] ?? []) as $i) {
            if (($i['width'] ?? 0) >= 400) { $img = $i['url']; break; }
        }
        if (!$img && !empty($a['images'])) $img = $a['images'][0]['url'] ?? '';
        if (!$img) continue;

        // Label Cincinnati teams specifically
        $source = $feed['sport'];
        $text = strtolower($headline . ' ' . $desc);
        if (strpos($text, 'reds') !== false || strpos($text, 'cincinnati') !== false) $source = 'Cincinnati Reds';
        elseif (strpos($text, 'bengals') !== false) $source = 'Cincinnati Bengals';
        elseif (strpos($text, 'fc cincinnati') !== false || strpos($text, 'fcc') !== false) $source = 'FC Cincinnati';

        $stories[] = [
            'title'    => $headline,
            'subtitle' => $desc,
            'image'    => $img,
            'source'   => $source,
            'url'      => $a['links']['web']['href'] ?? '',
            'category' => 'sports',
            'time'     => $a['published'] ?? '',
        ];
    }
}

// ── 4. TicketMaster — upcoming Cincinnati events ────────────
$tmKey = 'hBs3viDcJsoaf6TmwLJHRvGxC8jg37N4';
$today = date('Y-m-d\TH:i:s\Z');
$resp = fetchUrl("https://app.ticketmaster.com/discovery/v2/events.json?apikey={$tmKey}&city=Cincinnati&stateCode=OH&startDateTime={$today}&size=5&sort=date,asc");
if ($resp) {
    $data = json_decode($resp, true);
    foreach (($data['_embedded']['events'] ?? []) as $evt) {
        $img = '';
        foreach (($evt['images'] ?? []) as $i) {
            if (($i['width'] ?? 0) >= 500) { $img = $i['url']; break; }
        }
        if (!$img && !empty($evt['images'])) $img = $evt['images'][0]['url'] ?? '';
        if (!$img) continue;

        $venue = $evt['_embedded']['venues'][0]['name'] ?? '';
        $date = $evt['dates']['start']['localDate'] ?? '';
        $dateStr = $date ? date('M j', strtotime($date)) : '';

        $stories[] = [
            'title'    => $evt['name'] ?? '',
            'subtitle' => ($venue ? $venue . ' · ' : '') . $dateStr,
            'image'    => $img,
            'source'   => 'Events',
            'url'      => $evt['url'] ?? '',
            'category' => 'events',
            'time'     => $date,
        ];
    }
}

// ── 6. NWS Weather Alerts — severe weather for Hamilton County ──
$nwsResp = fetchUrl('https://api.weather.gov/alerts/active?area=OH&zone=OHZ077');
if ($nwsResp) {
    $nwsData = json_decode($nwsResp, true);
    foreach (($nwsData['features'] ?? []) as $alert) {
        $props = $alert['properties'] ?? [];
        $event = $props['event'] ?? '';
        $headline = $props['headline'] ?? '';
        if (!$event) continue;

        // Use severity to pick a dramatic background image
        $severity = strtolower($props['severity'] ?? 'minor');
        $urgency = strtolower($props['urgency'] ?? 'expected');
        $nwsImg = 'https://cdn.pixabay.com/photo/2018/08/23/07/35/thunderstorm-3625405_1280.jpg'; // dramatic storm

        $stories[] = [
            'title'    => $event,
            'subtitle' => $headline,
            'image'    => $nwsImg,
            'source'   => 'NWS Alert',
            'url'      => $props['uri'] ?? 'https://weather.gov',
            'category' => 'weather',
            'time'     => $props['onset'] ?? $props['effective'] ?? '',
        ];
    }
}

// Clean all text fields — strip HTML tags, decode entities, trim whitespace
foreach ($stories as &$s) {
    $s['title']    = trim(html_entity_decode(strip_tags($s['title'] ?? ''), ENT_QUOTES, 'UTF-8'));
    $s['subtitle'] = trim(html_entity_decode(strip_tags($s['subtitle'] ?? ''), ENT_QUOTES, 'UTF-8'));
    $s['source']   = trim(strip_tags($s['source'] ?? ''));
}
unset($s);

// Deduplicate by title
$seen = [];
$stories = array_filter($stories, function($s) use (&$seen) {
    $key = strtolower(trim($s['title']));
    if (isset($seen[$key])) return false;
    $seen[$key] = true;
    return true;
});

// Shuffle to mix categories, limit to 20
shuffle($stories);
$stories = array_values(array_slice($stories, 0, 20));

$result = ['stories' => $stories, 'count' => count($stories), 'cached_at' => date('c')];
@file_put_contents($cacheFile, json_encode($result));
jsonResponse($result);
