<?php
declare(strict_types=1);
// ==================================================
// Nuclear Fancy Pants Edition™ — NUCLEAR+++
// File: /home/ploi/automarketer-ai.com/public/wp-content/plugins/automarketer-ai/includes/class-stats-engine.php
// Description: Polls Meta Graph API for post performance stats (likes, comments, reach) - NUCLEAR+++
// Last Edited: 2026-04-10
// ==================================================

namespace AutoMarketerAI;

class StatsEngine
{
    private const CRON_HOOK = 'amai_fetch_post_stats';
    private const GRAPH_BASE = 'https://graph.facebook.com/v22.0';

    // ---------------------------------------------------------------------------
    // Boot
    // ---------------------------------------------------------------------------

    public static function init(): void
    {
        add_action(self::CRON_HOOK, [self::class, 'run']);

        if (!wp_next_scheduled(self::CRON_HOOK)) {
            wp_schedule_event(time(), 'daily', self::CRON_HOOK);
        }
    }

    // ---------------------------------------------------------------------------
    // Main runner — called by cron
    // ---------------------------------------------------------------------------

    public static function run(): void
    {
        global $wpdb;

        $page_token = FacebookAuth::getPageToken();
        if ($page_token === null || $page_token === '') {
            error_log('[StatsEngine] No page token available - aborting stats fetch.');
            return;
        }

        $table = $wpdb->prefix . 'amai_scheduled_posts';

        $rows = $wpdb->get_results(
            $wpdb->prepare(
                "SELECT id, channel, facebook_post_id, scheduled_date, scheduled_time
                 FROM `{$table}`
                 WHERE status = 'posted'
                   AND facebook_post_id IS NOT NULL
                   AND facebook_post_id <> ''
                   AND (
                       stats_fetched_at IS NULL
                       OR stats_fetched_at < %s
                   )",
                gmdate('Y-m-d H:i:s', strtotime('-24 hours'))
            ),
            ARRAY_A
        );

        if (empty($rows)) {
            return;
        }

        foreach ($rows as $row) {
            $channel = (string) ($row['channel'] ?? 'facebook');
            $media_id = (string) $row['facebook_post_id'];
            $post_id  = (int)    $row['id'];

            $stats = ($channel === 'instagram')
                ? self::fetchInstagramStats($media_id, $page_token)
                : self::fetchFacebookStats($media_id, $page_token);

            if ($stats === null) {
                continue;
            }

            $wpdb->query(
                $wpdb->prepare(
                    "UPDATE `{$table}`
                     SET stat_likes       = %d,
                         stat_comments    = %d,
                         stat_reach       = %s,
                         stats_fetched_at = %s
                     WHERE id = %d",
                    $stats['likes'],
                    $stats['comments'],
                    $stats['reach'] !== null ? (string) $stats['reach'] : null,
                    gmdate('Y-m-d H:i:s'),
                    $post_id
                )
            );

            // Record outcome in BestTimeLearner for time-slot optimization
            if (!empty($row['scheduled_date']) && !empty($row['scheduled_time'])) {
                $tz_str = BestTimeLearner::getSiteTimezone();
                $tz     = new \DateTimeZone($tz_str);
                $dt_str = $row['scheduled_date'] . ' ' . $row['scheduled_time'];
                try {
                    $dt          = new \DateTimeImmutable($dt_str, $tz);
                    $day_of_week = ((int) $dt->format('N')) - 1;
                    $hour_local  = (int) $dt->format('G');
                    BestTimeLearner::recordOutcome(
                        $channel,
                        $day_of_week,
                        $hour_local,
                        $stats['likes'],
                        $stats['comments'],
                        $stats['reach']
                    );
                } catch (\Throwable $e) {
                    // Non-fatal -- learner miss is acceptable
                }
            }
        }
    }

    // ---------------------------------------------------------------------------
    // Facebook — likes + comments + reach (page_impressions_unique)
    // ---------------------------------------------------------------------------

    private static function fetchFacebookStats(string $post_id, string $page_token): ?array
    {
        $url = self::GRAPH_BASE . '/' . rawurlencode($post_id)
            . '?fields=likes.summary(true),comments.summary(true),insights.metric(post_impressions_unique)'
            . '&access_token=' . rawurlencode($page_token);

        $response = wp_remote_get($url, ['timeout' => 15]);

        if (is_wp_error($response)) {
            error_log('[StatsEngine] Facebook stats request error: ' . $response->get_error_message());
            return null;
        }

        $body = wp_remote_retrieve_body($response);
        $data = json_decode($body, true);

        if (!is_array($data) || isset($data['error'])) {
            error_log('[StatsEngine] Facebook stats API error for ' . $post_id . ': ' . $body);
            return null;
        }

        $likes    = (int) ($data['likes']['summary']['total_count']    ?? 0);
        $comments = (int) ($data['comments']['summary']['total_count'] ?? 0);
        $reach    = null;

        if (isset($data['insights']['data']) && is_array($data['insights']['data'])) {
            foreach ($data['insights']['data'] as $metric) {
                if (($metric['name'] ?? '') === 'post_impressions_unique') {
                    $reach = (int) ($metric['values'][0]['value'] ?? 0);
                    break;
                }
            }
        }

        return ['likes' => $likes, 'comments' => $comments, 'reach' => $reach];
    }

    // ---------------------------------------------------------------------------
    // Instagram — like_count + comments_count (reach skipped until App Review)
    // ---------------------------------------------------------------------------

    private static function fetchInstagramStats(string $media_id, string $page_token): ?array
    {
        $url = self::GRAPH_BASE . '/' . rawurlencode($media_id)
            . '?fields=like_count,comments_count'
            . '&access_token=' . rawurlencode($page_token);

        $response = wp_remote_get($url, ['timeout' => 15]);

        if (is_wp_error($response)) {
            error_log('[StatsEngine] Instagram stats request error: ' . $response->get_error_message());
            return null;
        }

        $body = wp_remote_retrieve_body($response);
        $data = json_decode($body, true);

        if (!is_array($data) || isset($data['error'])) {
            error_log('[StatsEngine] Instagram stats API error for ' . $media_id . ': ' . $body);
            return null;
        }

        $likes    = (int) ($data['like_count']    ?? 0);
        $comments = (int) ($data['comments_count'] ?? 0);

        return ['likes' => $likes, 'comments' => $comments, 'reach' => null];
    }
}