<?php
declare(strict_types=1);
// ==================================================
// Nuclear Fancy Pants Edition™ — NUCLEAR+++
// File: /includes/class-post-generator.php
// Description: Builds the Core generate-week request payload from business profile and Facebook connection - NUCLEAR+++
// Last Edited: 2026-03-28
// ==================================================

namespace AutoMarketerAI;

defined('ABSPATH') || exit;

final class PostGenerator
{
    // Build the context payload to send to Core /api/content/generate-week.
    // Returns null if required data is missing (no Facebook connection, no profile).
    public static function buildContext(): ?array
    {
        global $wpdb;

        // Load Facebook connection — need page name
        $fb_table = $wpdb->prefix . 'amai_facebook_connection';
        $fb_row   = $wpdb->get_row(
            $wpdb->prepare(
                "SELECT page_id, page_name FROM {$fb_table} WHERE tenant_id = %s AND status = 'active' LIMIT 1",
                'default'
            ),
            ARRAY_A
        );

        if (!is_array($fb_row) || empty($fb_row['page_id'])) {
            return null;
        }

        // Load business profile
        $profile_table = $wpdb->prefix . 'amai_business_profile';
        $profile       = $wpdb->get_row(
            $wpdb->prepare(
                "SELECT * FROM {$profile_table} WHERE tenant_id = %s LIMIT 1",
                'default'
            ),
            ARRAY_A
        );

        if (!is_array($profile)) {
            return null;
        }

        return [
            'page_name'           => (string) ($fb_row['page_name']              ?? ''),
            'facebook_page_id'    => (string) ($fb_row['page_id']                ?? ''),
            'business_category'   => (string) ($profile['business_category']     ?? ''),
            'business_tone'       => (string) ($profile['business_tone']         ?? 'warm_personal'),
            'customer_descriptor' => (string) ($profile['customer_descriptor']   ?? ''),
            'differentiator'      => (string) ($profile['differentiator']        ?? ''),
            'values_and_causes'   => (string) ($profile['values_and_causes']     ?? ''),
            'post_time_hour'      => (int)    ($profile['post_time_hour']         ?? 10),
        ];
    }

    // Resolve the 5 post types for the coming week using the same rotation
    // algorithm as Core AbstractAiProvider::resolveWeeklyTypes().
    // Seeded by ISO week number of the NEXT week so WP and Core always agree.
    public static function resolveWeeklyTypes(string $channel): array
    {
        $next_monday = new \DateTimeImmutable('next monday', new \DateTimeZone('UTC'));
        $week        = (int) $next_monday->format('W');

        $fb_fixed   = ['educational', 'product', 'engagement'];
        $ig_fixed   = ['tip', 'product', 'engagement'];
        $tk_fixed   = ['tip', 'product', 'engagement'];
        $x_fixed     = ['tip', 'product', 'engagement'];
        $google_fixed = ['tip', 'product', 'engagement'];
        $fb_pool    = ['feel_good', 'behind_scenes', 'quote', 'humor', 'myth_bust'];
        $ig_pool    = ['feel_good', 'quote', 'humor', 'myth_bust', 'behind_scenes'];
        $tk_pool    = ['feel_good', 'quote', 'humor', 'myth_bust', 'behind_scenes', 'milestone', 'testimonial'];
        $x_pool      = ['feel_good', 'quote', 'humor', 'myth_bust', 'behind_scenes', 'milestone', 'testimonial'];
        $google_pool = ['feel_good', 'quote', 'humor', 'myth_bust', 'behind_scenes', 'milestone', 'testimonial'];

        $pool = match ($channel) {
            'tiktok'    => $tk_pool,
            'x'         => $x_pool,
            'google'    => $google_pool,
            'instagram' => $ig_pool,
            default     => $fb_pool,
        };
        $fixed = match ($channel) {
            'tiktok'    => $tk_fixed,
            'x'         => $x_fixed,
            'google'    => $google_fixed,
            'instagram' => $ig_fixed,
            default     => $fb_fixed,
        };
        $count = count($pool);

        $idx_a = $week % $count;
        $idx_b = ($week + 2) % $count;
        if ($idx_b === $idx_a) {
            $idx_b = ($idx_b + 1) % $count;
        }

        return [
            $fixed[0],
            $fixed[1],
            $pool[$idx_a],
            $pool[$idx_b],
            $fixed[2],
        ];
    }

    // Calculate the ISO 8601 week batch string for the coming week.
    // Called on Wednesday — returns the NEXT week's batch (e.g. '2026-W15').
    public static function nextWeekBatch(): string
    {
        $next_monday = new \DateTimeImmutable('next monday', new \DateTimeZone('UTC'));
        return $next_monday->format('o-\WW');
    }

    // Calculate the 5 scheduled dates for the coming week (Mon–Fri).
    // Accepts an ordered array of 5 post_type strings — maps them to Mon through Fri.
    // Returns array keyed by post_type => date string (Y-m-d).
    public static function weekDates(array $post_types = []): array
    {
        $next_monday = new \DateTimeImmutable('next monday', new \DateTimeZone('UTC'));
        $days = [
            $next_monday->format('Y-m-d'),
            $next_monday->modify('+1 day')->format('Y-m-d'),
            $next_monday->modify('+2 days')->format('Y-m-d'),
            $next_monday->modify('+3 days')->format('Y-m-d'),
            $next_monday->modify('+4 days')->format('Y-m-d'),
        ];

        // If no types provided fall back to legacy fixed order
        if (empty($post_types)) {
            $post_types = ['educational', 'product', 'feel_good', 'behind_scenes', 'engagement'];
        }

        $result = [];
        foreach (array_values($post_types) as $i => $type) {
            if (isset($days[$i])) {
                $result[$type] = $days[$i];
            }
        }

        return $result;
    }
}