<?php
declare(strict_types=1);
// ==================================================
// Nuclear Fancy Pants Edition™ — NUCLEAR+++
// File: /includes/class-competitor-analyzer.php
// Description: Fetches public Facebook page posts for competitor radar. Stores posts locally and formats a prompt block for Core injection. - NUCLEAR+++
// Last Edited: 2026-04-22
// ==================================================

namespace AutoMarketerAI;

defined('ABSPATH') || exit;

final class CompetitorAnalyzer
{
    private const GRAPH_BASE   = 'https://graph.facebook.com/v22.0';
    private const POSTS_LIMIT  = 20;
    private const PROMPT_POSTS = 10;
    private const REFRESH_DAYS = 7;

    public static function addPage(string $page_url): bool|string
    {
        $page_url = trim($page_url);
        if ($page_url === '') {
            return 'Page URL is required.';
        }
        $page_token = FacebookAuth::getPageToken();
        if ($page_token === null || $page_token === '') {
            return 'No Facebook page token available.';
        }
        $slug = self::extractSlug($page_url);
        if ($slug === '') {
            return 'Could not parse page slug from URL.';
        }
        $url = self::GRAPH_BASE . '/' . rawurlencode($slug)
             . '?fields=id,name&access_token=' . rawurlencode($page_token);
        $response = wp_remote_get($url, ['timeout' => 15]);
        if (is_wp_error($response)) {
            return 'Facebook API error: ' . $response->get_error_message();
        }
        $data = json_decode(wp_remote_retrieve_body($response), true);
        if (!is_array($data) || isset($data['error']) || empty($data['id'])) {
            $msg = $data['error']['message'] ?? 'Unknown error';
            return 'Could not resolve page: ' . $msg;
        }
        $page_id   = (string) $data['id'];
        $page_name = (string) ($data['name'] ?? $slug);
        global $wpdb;
        $table = $wpdb->prefix . 'amai_competitor_pages';
        $existing = $wpdb->get_var(
            $wpdb->prepare(
                "SELECT id FROM `{$table}` WHERE tenant_id = %s AND platform = 'facebook' AND page_id = %s LIMIT 1",
                'default',
                $page_id
            )
        );
        if ($existing) {
            return 'This page is already being tracked.';
        }
        $wpdb->insert(
            $table,
            ['tenant_id' => 'default', 'platform' => 'facebook', 'page_url' => $page_url,
             'page_id' => $page_id, 'page_name' => $page_name, 'created_at' => current_time('mysql', true)],
            ['%s', '%s', '%s', '%s', '%s', '%s']
        );
        if ($wpdb->insert_id === 0) {
            return 'Database error saving competitor page.';
        }
        return true;
    }

    public static function removePage(int $competitor_id): void
    {
        global $wpdb;
        $wpdb->delete($wpdb->prefix . 'amai_competitor_posts', ['competitor_id' => $competitor_id], ['%d']);
        $wpdb->delete($wpdb->prefix . 'amai_competitor_pages', ['id' => $competitor_id], ['%d']);
    }

    public static function getPages(): array
    {
        global $wpdb;
        $rows = $wpdb->get_results(
            $wpdb->prepare(
                "SELECT id, platform, page_url, page_id, page_name, last_fetched_at" .
                " FROM `{$wpdb->prefix}amai_competitor_pages`" .
                " WHERE tenant_id = %s ORDER BY created_at ASC",
                'default'
            ),
            ARRAY_A
        );
        return is_array($rows) ? $rows : [];
    }

    public static function fetchAll(): void
    {
        $page_token = FacebookAuth::getPageToken();
        if ($page_token === null || $page_token === '') {
            return;
        }
        global $wpdb;
        $cutoff = gmdate('Y-m-d H:i:s', strtotime('-' . self::REFRESH_DAYS . ' days'));
        $pages = $wpdb->get_results(
            $wpdb->prepare(
                "SELECT id, page_id, page_name FROM `{$wpdb->prefix}amai_competitor_pages`" .
                " WHERE tenant_id = %s AND platform = 'facebook'" .
                "   AND (last_fetched_at IS NULL OR last_fetched_at < %s)",
                'default', $cutoff
            ),
            ARRAY_A
        );
        if (empty($pages)) {
            return;
        }
        foreach ($pages as $page) {
            self::fetchPagePosts((int) $page['id'], (string) $page['page_id'], $page_token);
        }
    }

    public static function formatForPrompt(): string
    {
        global $wpdb;
        $pages = self::getPages();
        if (empty($pages)) {
            return '';
        }
        $posts_table = $wpdb->prefix . 'amai_competitor_posts';
        $lines = [];
        foreach ($pages as $page) {
            $competitor_id = (int) $page['id'];
            $page_name     = (string) $page['page_name'];
            $posts = $wpdb->get_col(
                $wpdb->prepare(
                    "SELECT post_text FROM `{$posts_table}`" .
                    " WHERE competitor_id = %d ORDER BY posted_at DESC LIMIT %d",
                    $competitor_id, self::PROMPT_POSTS
                )
            );
            if (empty($posts)) {
                continue;
            }
            $lines[] = 'Competitor: ' . $page_name;
            foreach ($posts as $text) {
                $clean = self::cleanPostText((string) $text);
                if ($clean !== '') {
                    $lines[] = '  - ' . $clean;
                }
            }
        }
        if (empty($lines)) {
            return '';
        }
        $block   = [];
        $block[] = '';
        $block[] = 'Competitor content radar (recent public posts from tracked competitor pages):';
        $block[] = implode("\n", $lines);
        $block[] = '- Use this to identify angles and topics your competitors are already covering.';
        $block[] = '- Do not copy their tone, style, or specific claims.';
        $block[] = '- Where possible, find a differentiated angle or address a gap they are missing.';
        $block[] = '- This is context only. Never mention competitors by name in any post.';
        return implode("\n", $block);
    }

    private static function fetchPagePosts(int $competitor_id, string $page_id, string $page_token): void
    {
        $url = self::GRAPH_BASE . '/' . rawurlencode($page_id) . '/posts'
             . '?fields=id,message,created_time'
             . '&limit=' . self::POSTS_LIMIT
             . '&access_token=' . rawurlencode($page_token);
        $response = wp_remote_get($url, ['timeout' => 20]);
        if (is_wp_error($response)) {
            error_log('[CompetitorAnalyzer] Fetch error for page ' . $page_id . ': ' . $response->get_error_message());
            return;
        }
        $data = json_decode(wp_remote_retrieve_body($response), true);
        if (!is_array($data) || isset($data['error']) || empty($data['data'])) {
            error_log('[CompetitorAnalyzer] Bad response for page ' . $page_id);
            return;
        }
        global $wpdb;
        $table = $wpdb->prefix . 'amai_competitor_posts';
        foreach ($data['data'] as $post) {
            $platform_post_id = (string) ($post['id']           ?? '');
            $message          = (string) ($post['message']      ?? '');
            $created_time     = (string) ($post['created_time'] ?? '');
            if ($platform_post_id === '' || $message === '') {
                continue;
            }
            $posted_at = '';
            if ($created_time !== '') {
                try {
                    $posted_at = (new \DateTimeImmutable($created_time))->format('Y-m-d H:i:s');
                } catch (\Throwable $e) {
                    $posted_at = '';
                }
            }
            $message = preg_replace('/[^\x00-\x7F]/', '', $message);
            $wpdb->query(
                $wpdb->prepare(
                    "INSERT INTO `{$table}` (competitor_id, platform_post_id, post_text, posted_at, fetched_at)" .
                    " VALUES (%d, %s, %s, %s, %s)" .
                    " ON DUPLICATE KEY UPDATE post_text = VALUES(post_text), fetched_at = VALUES(fetched_at)",
                    $competitor_id, $platform_post_id, $message,
                    $posted_at !== '' ? $posted_at : null,
                    gmdate('Y-m-d H:i:s')
                )
            );
        }
        $wpdb->update(
            $wpdb->prefix . 'amai_competitor_pages',
            ['last_fetched_at' => gmdate('Y-m-d H:i:s')],
            ['id' => $competitor_id],
            ['%s'], ['%d']
        );
    }

    private static function extractSlug(string $url): string
    {
        $path = preg_replace('#^https?://(www\.)?facebook\.com/#i', '', $url);
        $path = strtok(rtrim($path, '/'), '?');
        return (string) $path;
    }

    private static function cleanPostText(string $text): string
    {
        $text = preg_replace('/\s+/', ' ', trim($text));
        if (mb_strlen($text) > 300) {
            $text = mb_substr($text, 0, 297) . '...';
        }
        return $text;
    }
}
