<?php
include('config.php');
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
header("Content-Type: application/json");

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require '../vendor/autoload.php';

/* ===============================
   ENTERPRISE EMAIL LOGGING CLIENT
   Dynamic mapping: email file sends runtime facts only.
   Controller resolves module/submodule/source from DB using active_file_name/server path/URLs.
================================ */
$__pclEmailTrackingClient = __DIR__ . '/EmailTrackingApiClient.php';
if (file_exists($__pclEmailTrackingClient)) {
    require_once $__pclEmailTrackingClient;
}

if (!function_exists('pcl_email_runtime_url')) {
    function pcl_email_runtime_url()
    {
        $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
        $host   = $_SERVER['HTTP_HOST'] ?? 'www.procorporateleague.com';
        $uri    = $_SERVER['REQUEST_URI'] ?? ($_SERVER['SCRIPT_NAME'] ?? '');
        return $scheme . '://' . $host . $uri;
    }
}

if (!function_exists('pcl_email_public_file_url')) {
    function pcl_email_public_file_url()
    {
        $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
        $host   = $_SERVER['HTTP_HOST'] ?? 'www.procorporateleague.com';
        $script = $_SERVER['SCRIPT_NAME'] ?? '';
        return $script ? ($scheme . '://' . $host . $script) : null;
    }
}

if (!function_exists('pcl_email_flatten_text')) {
    function pcl_email_flatten_text($html)
    {
        return trim(preg_replace('/\s+/', ' ', html_entity_decode(strip_tags((string)$html), ENT_QUOTES, 'UTF-8')));
    }
}

if (!function_exists('pcl_email_normalize_attachment_urls')) {
    function pcl_email_normalize_attachment_urls($attachments)
    {
        if (empty($attachments)) return [];
        if (is_string($attachments)) {
            $decoded = json_decode($attachments, true);
            if (is_array($decoded)) $attachments = $decoded;
            else $attachments = array_filter(array_map('trim', explode(',', $attachments)));
        }
        $urls = [];
        if (is_array($attachments)) {
            foreach ($attachments as $item) {
                if (is_string($item) && $item !== '') {
                    $urls[] = $item;
                } elseif (is_array($item)) {
                    $url = $item['url'] ?? $item['attachment_url'] ?? $item['file_url'] ?? $item['href'] ?? null;
                    if (!empty($url)) $urls[] = $url;
                }
            }
        }
        return array_values(array_unique(array_filter($urls)));
    }
}

if (!function_exists('pcl_email_log_dynamic')) {
    function pcl_email_log_dynamic($mail, $emailBody, array $postData = [], array $extra = [])
    {
        if (!class_exists('EmailTrackingApiClient')) {
            return ['tracking_status' => 'skipped', 'reason' => 'EmailTrackingApiClient not found'];
        }

        $status = $extra['status'] ?? 'sent';
        $deliveryStatus = $extra['delivery_status'] ?? $status;

        $attachmentUrls = pcl_email_normalize_attachment_urls(
            $extra['attachment_urls'] ?? $postData['attachment_urls'] ?? $postData['attachments'] ?? []
        );

        $requestPayload = [];
        if (isset($GLOBALS['requestData']) && is_array($GLOBALS['requestData'])) $requestPayload = $GLOBALS['requestData'];
        elseif (isset($GLOBALS['data']) && is_array($GLOBALS['data'])) $requestPayload = $GLOBALS['data'];
        else $requestPayload = $postData;

        $subject = '';
        if (is_object($mail) && isset($mail->Subject)) $subject = (string)$mail->Subject;
        if ($subject === '') $subject = (string)($postData['subject'] ?? $extra['subject'] ?? '');

        $recipientEmail = $extra['recipient_email'] ?? $postData['email'] ?? $postData['recipient_email'] ?? $GLOBALS['email'] ?? '';
        $recipientName  = $extra['recipient_name']  ?? $postData['name'] ?? $postData['person_name'] ?? $postData['full_name'] ?? $GLOBALS['fullName'] ?? '';
        $recipientMobile = $extra['recipient_mobile'] ?? $postData['mobile'] ?? $postData['phone'] ?? $postData['recipient_mobile'] ?? '';
        $leadId = $extra['lead_id'] ?? $postData['lead_id'] ?? $postData['reference_id'] ?? $GLOBALS['leadId'] ?? $GLOBALS['lEADID'] ?? '';

        $messageId = null;
        if (is_object($mail) && method_exists($mail, 'getLastMessageID')) {
            $messageId = $mail->getLastMessageID();
        }

        $html = (string)($emailBody ?: (is_object($mail) && isset($mail->Body) ? $mail->Body : ''));

        $payload = [
            // Runtime recipient/data facts only. No module_key/submodule_key hardcoding here.
            'lead_id'            => $leadId,
            'team_id'            => $extra['team_id'] ?? $postData['team_id'] ?? $postData['teamId'] ?? '',
            'user_id'            => $extra['user_id'] ?? $postData['user_id'] ?? $postData['userId'] ?? '',

            'recipient_email'    => $recipientEmail,
            'recipient_name'     => $recipientName,
            'recipient_mobile'   => $recipientMobile,
            'email'              => $recipientEmail,
            'mobile'             => $recipientMobile,

            'subject'            => $subject,
            'preheader'          => $extra['preheader'] ?? $postData['preheader'] ?? '',

            // Final rendered client email after all dynamic replacements.
            'full_email_html'    => $html,
            'full_email_text'    => pcl_email_flatten_text($html),

            // Attachments / linked docs.
            'attachment_urls'    => implode(',', $attachmentUrls),
            'attachments_json'   => json_encode($attachmentUrls, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE),
            'attachment_count'   => count($attachmentUrls),

            // URL/file audit. Values are runtime-derived, not business hardcoded.
            'current_email_url'  => pcl_email_runtime_url(),
            'public_calling_url' => pcl_email_runtime_url(),
            'calling_file_url'   => $extra['calling_file_url'] ?? $postData['calling_file_url'] ?? $requestPayload['calling_file_url'] ?? ($_SERVER['HTTP_REFERER'] ?? null),
            'calling_page_url'   => $extra['calling_page_url'] ?? $postData['calling_page_url'] ?? $requestPayload['calling_page_url'] ?? ($_SERVER['HTTP_REFERER'] ?? null),
            'direct_email_url'   => pcl_email_public_file_url(),
            'server_full_path'   => __FILE__,
            'server_file_path'   => __FILE__,
            'script_name'        => basename(__FILE__),
            'active_file_name'   => basename(__FILE__),
            'request_uri'        => $_SERVER['REQUEST_URI'] ?? null,

            // Delivery/provider info.
            'status'             => $status,
            'delivery_status'    => $deliveryStatus,
            'provider_message_id'=> $messageId,
            'error_message'      => $extra['error_message'] ?? null,

            // Request/response audit.
            'request_payload_json' => $requestPayload,
            'response_json'        => $extra['response_json'] ?? [
                'status' => $status,
                'message' => $extra['message'] ?? null,
                'provider_message_id' => $messageId,
            ],
        ];

        try {
            return EmailTrackingApiClient::trackLegacy($payload);
        } catch (Throwable $trackingException) {
            return [
                'tracking_status' => 'failed',
                'error' => $trackingException->getMessage(),
            ];
        }
    }
}


function pcl_track_email_if_available($mail, $extra = []) {
    try {
        if (function_exists('pcl_email_enterprise_track_send')) {
            return pcl_email_enterprise_track_send($mail, $extra);
        }
        if (class_exists('EmailTrackingApiClient') && method_exists('EmailTrackingApiClient', 'trackLegacy')) {
            $payload = array_merge([
                'active_file_name' => basename(__FILE__),
                'lead_id' => $extra['lead_id'] ?? null,
                'recipient_email' => $extra['recipient_email'] ?? '',
                'recipient_name' => $extra['recipient_name'] ?? '',
                'subject' => $mail->Subject ?? '',
                'status' => 'sent',
                'source' => 'upload_video'
            ], $extra);
            return EmailTrackingApiClient::trackLegacy($payload);
        }
    } catch (Throwable $e) {
        return ['success' => false, 'message' => $e->getMessage()];
    }
    return ['success' => false, 'message' => 'Tracking client not available'];
}



$requestData = json_decode(file_get_contents("php://input"), true);
if (!is_array($requestData)) $requestData = [];

$leadRequestId = $requestData['lead_id'] ?? '';
$lEADID        = $leadRequestId ?: '';

/* ===============================
   CURL CALL FROM LEAD ID
================================ */
$getData    = curlGetJson('https://procorporateleague.com/pcl_rest/api/v9/user/' . $lEADID);
$leadIdData = '';
if (!empty($getData['results']) && $getData['code'] === 200) {
    $leadIdData = $getData['results'][0];
}

// echo "<pre>";
// print_r($getData);
// exit;

/* ===============================
   CURL CALL FROM MOBILE DATA
================================ */
$profileData = '';
$getData     = curlGetJson('https://procorporateleague.com/pcl_rest/api/v9/profile/mobile/' . ($leadIdData['phone'] ?? ''));
if (!empty($getData['results']) && $getData['code'] === 200) {
    $profileData = $getData['results'][0];
}

/* ===============================
   FETCH AI REPORT
================================ */
$reportData = curlGetJson('https://www.procorporateleague.com/pcl_rest/api/v9/lead/getAIReportCard/' . $lEADID);
if (!empty($reportData['__error'])) {
    echo json_encode(['status_code' => 500, 'status' => 'error', 'message' => 'API Error: ' . $reportData['__error']]);
    exit;
}
if (empty($reportData['results'][0])) {
    echo json_encode(['status_code' => 404, 'status' => 'failed', 'message' => 'No AI report found.']);
    exit;
}
$row = $reportData['results'][0];

/* ===============================
   BUILD POST DATA
================================ */
$postData = [
    "email"             => $profileData['email']                   ?? '',
    "name"              => $leadIdData['full_name']                ?? 'PCL',
    "city"              => $leadIdData['city']                     ?? '',
    "reference_id"      => $leadIdData['lead_id']                  ?? '',
    "registration_type" => $leadIdData['user_profile']             ?? '',
    "mobile"            => $leadIdData['phone']                    ?? '',
    "user_id"           => $leadIdData['master_id']                ?? '',
    "company_name"      => $profileData['company_name_individual'] ?? '',
    "person_name"       => $leadIdData['full_name']                ?? '',
    "person_age"        => $profileData['age']                     ?? '',
];

$filePath   = "https://www.procorporateleague.com/2026/pcl/assets/mail_image/";
$imgVersion = time();

if (empty($postData['email'])) {
    echo json_encode(["status_code" => 400, "status" => "failed", "message" => "Email is required"]);
    exit;
}

/* ===============================
   BUILD TEMPLATE VARIABLES
================================ */
$user_name         = htmlspecialchars($postData['name']);
$user_email        = htmlspecialchars($postData['email']);
$city              = htmlspecialchars($postData['city']);
$reference_id      = htmlspecialchars($postData['reference_id']);
$registration_type = htmlspecialchars($postData['registration_type']);
$user_mobile       = htmlspecialchars($postData['mobile']);
$corporate         = htmlspecialchars($postData['company_name']);
$age               = htmlspecialchars($postData['person_age']);

$dashboardUrl = 'https://www.procorporateleague.com/2026/pcl/playerDashboard.php?id=' . urlencode($reference_id) . '&mobile=' . urlencode($user_mobile);
$invoiceUrl   = 'https://www.procorporateleague.com/2026/pcl/playerInvoice.php?id='   . urlencode($reference_id) . '&mobile=' . urlencode($user_mobile);
$whatsappUrl  = 'https://wa.me/919818596699?text=' . urlencode('Hi, I have been shortlisted for the PCL Challenger Round. I have a few questions for next steps.');

/* ===============================
   PARSE AI REPORT DATA
================================ */
$ui            = safeJson($row['raw_ui_json']                    ?? '');
$aiInsights    = safeJson($row['ai_performance_insights']        ?? '');
$pclRating     = safeJson($row['pcl_ai_rating']                 ?? '');
$selectionJson = safeJson($row['raw_selection_probability_json'] ?? '');

$fullName       = $row['player_name'] ?? $row['name'] ?? $user_name;
$firstName      = explode(' ', trim($fullName))[0]    ?? 'Player';
$playerCategory = $row['player_type'] ?? 'Player';

$overallRating = $pclRating['overall_rating_out_of_100'] ?? 'NA';
$overallGrade  = $pclRating['overall_grade']             ?? 'NA';

$selectionProbability = $selectionJson['selection_probability_percent']
    ?? ($ui['selection_block']['probability_percent'] ?? 0);
$selectionBand = $selectionJson['selection_probability_band']
    ?? ($ui['selection_block']['probability_band'] ?? 'Selected - PCL Challenger Round');

$confidencePercent = max(0, min(100, is_numeric($selectionProbability) ? (float)$selectionProbability : 0));
$confidenceDisplay = rtrim(rtrim(number_format($confidencePercent, 2), '0'), '.');

$badges = $ui['player_card']['badges'] ?? ($row['auto_player_badges'] ?? []);
if (!is_array($badges)) $badges = json_decode($badges, true) ?: normalizeInsightArray($badges);
if (empty($badges)) $badges = ['Strike Bowler', 'Control Bowler'];

$strengthsArr    = !empty($aiInsights['strengths'])
    ? normalizeInsightArray($aiInsights['strengths'])
    : ['Strong performance potential identified by PCL AI.'];

$improvementArr  = !empty($aiInsights['areas_of_improvement'])
    ? normalizeInsightArray($aiInsights['areas_of_improvement'])
    : ['Continue improving consistency, match awareness and performance execution.'];

$playingStyleArr = !empty($aiInsights['playing_style'])
    ? normalizeInsightArray($aiInsights['playing_style'])
    : ['Competitive player with positive intent and match-readiness potential.'];

/* ===============================
   FETCH STATS
================================ */
$statsRaw       = curlGetJson('https://procorporateleague.com/pcl_rest/api/v1/pcl/stats');
$statsArrayData = [
    'total_matches_played'  => $statsRaw['results'][0]['Total_Matches_Played']  ?? 0,
    'total_runs_Scored'     => $statsRaw['results'][0]['Total_Runs_Scored']     ?? 0,
    'total_wickets_Claimed' => $statsRaw['results'][0]['Total_Wickets_Claimed'] ?? 0,
    'total_hundreds'        => $statsRaw['results'][0]['Total_Hundreds']        ?? 0,
    'total_fifties'         => $statsRaw['results'][0]['Total_Fifties']         ?? 0,
];

/* ===============================
   BUILD CONDITIONAL BLOCKS
================================ */
$age_block = !empty($age)
    ? "<p><strong>Age :</strong> " . ucwords($age) . "</p>"
    : '';

$badgesHtml = '';
foreach ($badges as $badge) {
    $badgesHtml .= '<span style="display:inline-block;background:#ffffff;color:#06142f;border-radius:999px;
                                 padding:7px 11px;margin:0 5px 7px 0;font-size:10px;font-weight:900;">'
                 . htmlspecialchars((string)$badge) . '</span>';
}

$strengthsHtml   = renderInsightCard('Strengths',         '💪', $strengthsArr);
$playingHtml     = renderInsightCard('Playing Style',     '🏏', $playingStyleArr);
$improvementHtml = renderInsightCard('Improvement Areas', '🎯', $improvementArr);

$galleryChampions = '<table role="presentation" width="100%" cellpadding="0" cellspacing="0"><tr>'
    . renderGalleryItem('jr_image_1.jpeg', 'HCL Tech - IT & Services (Platinum)',   $filePath, $imgVersion)
    . renderGalleryItem('jr_image_2.jpeg', 'Siemens - IT & Services (Diamond)',     $filePath, $imgVersion)
    . renderGalleryItem('jr_image_3.jpeg', 'Sopra Banking - IT & Services',         $filePath, $imgVersion)
    . renderGalleryItem('jr_image_4.jpeg', 'KEI Wires & Cables - Corporate',        $filePath, $imgVersion)
    . '</tr></table>';

$galleryChallengers = '<table role="presentation" width="100%" cellpadding="0" cellspacing="0"><tr>'
    . renderGalleryItem('jr_image_5.jpeg', 'COFORGE Gurugram - IT & Services', $filePath, $imgVersion)
    . renderGalleryItem('jr_image_6.jpeg', 'COFORGE Noida - IT & Services',    $filePath, $imgVersion)
    . renderGalleryItem('jr_image_7.jpeg', 'IFFCO - IT & Services',            $filePath, $imgVersion)
    . renderGalleryItem('jr_image_8.jpeg', 'SPARK MINDA - Corporate',          $filePath, $imgVersion)
    . '</tr></table>';

$galleryJonty = '<table role="presentation" width="100%" cellpadding="0" cellspacing="0"><tr>'
    . renderGalleryItem('jr_image_9.jpeg',  'TCS - Tata Consultancy Services', $filePath, $imgVersion)
    . renderGalleryItem('jr_image_10.jpeg', 'Teleperformance',                 $filePath, $imgVersion)
    . renderGalleryItem('jr_image_11.jpeg', 'Optum Noida',                     $filePath, $imgVersion)
    . renderGalleryItem('jr_image_12.jpeg', 'Team Avengers',                   $filePath, $imgVersion)
    . '</tr></table>';

/* ===============================
   DB CALLS
================================ */

// SMTP
$smtpSql = "SELECT * FROM `smtp_auth_data` WHERE id = 1";
$smtpExe = mysqli_query($conn, $smtpSql);
$smtpRow = mysqli_fetch_assoc($smtpExe);
if (empty($smtpRow)) {
    echo json_encode(["status_code" => 400, "status" => "ERROR", "message" => "SMTP AUTH MISSING"]);
    die;
}

// Email Template  ← id = 3  (AI report card template)
$emailSql = "SELECT * FROM `email_template` WHERE id = 3";
$emailExe = mysqli_query($conn, $emailSql);
$emailRow = mysqli_fetch_assoc($emailExe);
if (empty($emailRow)) {
    echo json_encode(["status_code" => 400, "status" => "ERROR", "message" => "EMAIL TEMPLATE MISSING"]);
    die;
}

$fullName = $leadIdData['full_name']??'';

/* ===============================
   REPLACE PLACEHOLDERS IN TEMPLATE
================================ */
$emailBody = $emailRow['template_file'] ?? '';
$subject   = $emailRow['subject']       ?? ($fullName . ' - Your PCL AI Report is Live - Secure Your Slot Now');

$replacements = [
    '{{first_name}}'            => ucwords($fullName)??'PCL Player',
    '{{full_name}}'             => ucwords($fullName)??'PCL Player',
    '{{user_name}}'             => ucwords($fullName)??'PCL Player',
    '{{user_email}}'            => $user_email,
    '{{city}}'                  => ucwords($city),
    '{{reference_id}}'          => $reference_id,
    '{{registration_type}}'     => $registration_type,
    '{{user_mobile}}'           => $user_mobile,
    '{{corporate}}'             => ucwords($corporate),
    '{{age_block}}'             => $age_block,
    '{{player_category}}'       => htmlspecialchars($playerCategory),
    '{{overall_rating}}'        => htmlspecialchars($overallRating),
    '{{overall_grade}}'         => htmlspecialchars($overallGrade),
    '{{selection_band}}'        => htmlspecialchars($selectionBand),
    '{{confidence_display}}'    => htmlspecialchars($confidenceDisplay),
    '{{confidence_percent}}'    => htmlspecialchars($confidencePercent),
    '{{badges_html}}'           => $badgesHtml,
    '{{strengths_html}}'        => $strengthsHtml,
    '{{playing_style_html}}'    => $playingHtml,
    '{{improvement_html}}'      => $improvementHtml,
    '{{dashboard_url}}'         => $dashboardUrl,
    '{{invoice_url}}'           => $invoiceUrl,
    '{{whatsapp_url}}'          => $whatsappUrl,
    '{{gallery_champions}}'     => $galleryChampions,
    '{{gallery_challengers}}'   => $galleryChallengers,
    '{{gallery_jonty}}'         => $galleryJonty,
    '{{filePath}}'              => $filePath,
    '{{imgVersion}}'            => $imgVersion,
    '{{total_matches_played}}'  => number_format($statsArrayData['total_matches_played']  ?: 0),
    '{{total_runs_Scored}}'     => number_format($statsArrayData['total_runs_Scored']     ?: 0),
    '{{total_wickets_Claimed}}' => number_format($statsArrayData['total_wickets_Claimed'] ?: 0),
    '{{total_hundreds}}'        => number_format($statsArrayData['total_hundreds']        ?: 0),
    '{{total_fifties}}'         => number_format($statsArrayData['total_fifties']         ?: 0),
];

$emailBody = strtr($emailBody, $replacements);
$subject   = strtr($subject,   $replacements);

/* ===============================
   SEND EMAIL
================================ */
$mail = new PHPMailer(true);
try {
    $mail->isSMTP();
    $mail->Host       = $smtpRow['smtp_host']     ?? '';
    $mail->SMTPAuth   = true;
    $mail->Username   = $smtpRow['smtp_username'] ?? '';
    $mail->Password   = $smtpRow['smtp_password'] ?? '';
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
    $mail->Port       = 587;

    $mail->setFrom($smtpRow['smtp_username'], 'Pro Corporate League');
    $mail->addAddress($postData['email'], $postData['name']);
    //$mail->addAddress('zehraruhi82@gmail.com', 'Ruhi');
    //$mail->addAddress('mohammad.mozammil@procorporateleague.com', 'Mozammil');
    $mail->addCC('sachin.gupta@procorporateleague.com',      'Sachin Gupta');
    $mail->addCC('sachin.gupta@corporateworldcup.com', 'Sachin Gupta');
    $mail->addCC('rifat.saleem@procorporateleague.com', 'Refat Saleem');

    $mail->CharSet  = 'UTF-8';
    $mail->Encoding = 'base64';
    $mail->isHTML(true);
    $mail->Subject = $subject;
    $mail->Body    = $emailBody;
    $mail->AltBody = 'Congratulations ' . $fullName . '. Your PCL AI Report is live. View dashboard: ' . $dashboardUrl;

    $mail->send();

    // Enterprise logging after successful send.
    // Controller resolves module/submodule/source dynamically using active_file_name/server path/URLs.
    $trackingResult = pcl_email_log_dynamic($mail, $emailBody ?? '', $postData ?? [], [
        'status' => 'sent',
        'delivery_status' => 'sent',
        'message' => 'Email sent successfully',
        'module_id' => 9,
        'submodule_id' => 9,
        'module_key' => 'report_card',
        'submodule_key' => 'report_card',
    ]);

    $tracking = pcl_track_email_if_available($mail, [
        'lead_id' => $leadId,
        'mobile' => $postData['mobile'],
        'recipient_email' => $postData['email'],
        'recipient_name' => $postData['name'],
        'subject' => $subject,
        'module_id' => 9,
        'submodule_id' => 9,
        'module_key' => 'report_card',
        'submodule_key' => 'report_card',
        'active_file_name' => basename(__FILE__),
        'calling_file_url' => $_SERVER['HTTP_REFERER'] ?? '',
        'full_email_html' => $emailBody
    ]);


    echo json_encode([
        "status_code" => 200,
        "status"      => "success",
        "message"     => "AI Report Card email sent successfully",
        "tracking"    => $trackingResult
    ]);

} catch (Exception $e) {
    
    $trackingResult = pcl_email_log_dynamic($mail, $emailBody ?? '', $postData ?? [], [
        'status' => 'failed',
        'delivery_status' => 'failed',
        'message' => $mail->ErrorInfo ?? $e->getMessage(),
        'error_message' => $mail->ErrorInfo ?? $e->getMessage()
    ]);
echo json_encode([
        "status_code" => 500,
        "status"      => "error",
        "message"     => $mail->ErrorInfo
    ]);
}

/* ===============================
   HELPER FUNCTIONS
================================ */
function curlGetJson(string $url, int $timeout = 30): array {
    $curl = curl_init();
    curl_setopt_array($curl, [
        CURLOPT_URL            => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING       => '',
        CURLOPT_MAXREDIRS      => 10,
        CURLOPT_TIMEOUT        => $timeout,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST  => 'GET',
        CURLOPT_HTTPHEADER     => ['Accept: application/json'],
    ]);
    $response  = curl_exec($curl);
    $curlError = curl_error($curl);
    curl_close($curl);
    if ($curlError) return ['__error' => $curlError];
    $json = json_decode($response, true);
    return is_array($json) ? $json : [];
}

function safeJson($value): array {
    if (is_array($value)) return $value;
    if (empty($value)) return [];
    $decoded = json_decode($value, true);
    return is_array($decoded) ? $decoded : [];
}

function normalizeInsightArray($value): array {
    if (is_array($value)) {
        return array_values(array_filter(array_map(fn($v) => trim((string)$v), $value)));
    }
    if (is_string($value)) {
        return array_values(array_filter(array_map('trim', preg_split('/\s*,\s*/', $value))));
    }
    return [];
}

function renderBullets(array $items, string $color = '#ffffff'): string {
    $html = '';
    foreach ($items as $item) {
        $item = trim((string)$item);
        if ($item === '') continue;
        $html .= '<tr>
            <td width="18" valign="top" style="font-size:16px;line-height:22px;color:#fbbf24;padding:0 0 9px;">•</td>
            <td valign="top" style="font-size:13px;line-height:22px;color:' . $color . ';padding:0 0 9px;">'
                . htmlspecialchars($item) . '</td>
        </tr>';
    }
    return $html ?: '<tr><td style="font-size:13px;color:' . $color . ';">Performance insight will be updated shortly.</td></tr>';
}

function renderInsightCard(string $title, string $icon, array $items): string {
    return '
    <td class="stack-column" width="33.33%" valign="top" style="padding:6px;">
        <table role="presentation" width="100%" cellpadding="0" cellspacing="0"
               style="background:#2f55ad;border:1px solid rgba(255,255,255,.18);border-radius:18px;">
            <tr>
                <td style="padding:20px 18px 18px;">
                    <div style="width:42px;height:42px;border-radius:14px;background:#fbbf24;
                                text-align:center;line-height:42px;font-size:22px;margin-bottom:16px;">' . $icon . '</div>
                    <div style="font-size:14px;font-weight:900;text-transform:uppercase;
                                color:#ffffff;margin-bottom:12px;">' . htmlspecialchars($title) . '</div>
                    <table role="presentation" width="100%" cellpadding="0" cellspacing="0">
                        ' . renderBullets($items) . '
                    </table>
                </td>
            </tr>
        </table>
    </td>';
}

function renderGalleryItem(string $img, string $caption, string $filePath, int $imgVersion): string {
    return '<td class="gallery-item" width="25%" align="center" valign="top" style="padding:5px;">
        <img src="' . htmlspecialchars($filePath . $img . '?v=' . $imgVersion) . '" width="132" height="96"
             style="width:132px;height:96px;border-radius:10px;display:block;object-fit:cover;border:1px solid #e5e7eb;"
             alt="' . htmlspecialchars($caption) . '">
        <div style="font-size:11px;color:#334155;font-weight:700;margin-top:7px;">'
             . htmlspecialchars($caption) . '</div>
    </td>';
}