<?php
/**
 * Email service using Microsoft Graph API.
 *
 * Sends email via M365 Graph API using client credentials flow (OAuth 2.0).
 * Used for quote submission notifications and other system emails.
 *
 * All HTTP calls use curl.
 */

// Deny direct access
if (basename($_SERVER['SCRIPT_FILENAME'] ?? '') === basename(__FILE__)) {
    http_response_code(403);
    exit('Direct access denied.');
}

require_once __DIR__ . '/../config.php';
require_once __DIR__ . '/../helpers.php';

// Token cache: persists across calls within a single request
$_graph_token_cache = [
    'access_token' => null,
    'expires_at'   => 0,
];

/**
 * Obtain an access token from Azure AD using client credentials flow.
 *
 * Caches the token in a static variable and reuses it until 60 seconds
 * before expiry.
 *
 * @return string Bearer access token.
 * @throws RuntimeException If credentials are not configured or request fails.
 */
function get_graph_token(): string
{
    global $_graph_token_cache;

    // Return cached token if still valid (with 60s buffer)
    if (
        $_graph_token_cache['access_token'] !== null
        && $_graph_token_cache['expires_at'] > time() + 60
    ) {
        return $_graph_token_cache['access_token'];
    }

    if (empty(GRAPH_TENANT_ID) || empty(GRAPH_CLIENT_ID) || GRAPH_CLIENT_SECRET === 'CHANGE_ME_PLACEHOLDER') {
        throw new RuntimeException('Microsoft Graph API credentials not configured');
    }

    $token_url = "https://login.microsoftonline.com/" . GRAPH_TENANT_ID . "/oauth2/v2.0/token";

    $post_fields = http_build_query([
        'client_id'     => GRAPH_CLIENT_ID,
        'client_secret' => GRAPH_CLIENT_SECRET,
        'scope'         => 'https://graph.microsoft.com/.default',
        'grant_type'    => 'client_credentials',
    ]);

    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL            => $token_url,
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => $post_fields,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 15,
        CURLOPT_HTTPHEADER     => ['Content-Type: application/x-www-form-urlencoded'],
    ]);

    $response = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curl_error = curl_error($ch);
    curl_close($ch);

    if ($response === false) {
        app_log('ERROR', "Graph token request failed (curl): {$curl_error}");
        throw new RuntimeException("Failed to obtain Graph token: {$curl_error}");
    }

    if ($http_code !== 200) {
        app_log('ERROR', "Graph token request failed (HTTP {$http_code}): {$response}");
        throw new RuntimeException("Failed to obtain Graph token: HTTP {$http_code}");
    }

    $data = json_decode($response, true);
    if (empty($data['access_token'])) {
        app_log('ERROR', 'Graph token response missing access_token');
        throw new RuntimeException('Invalid Graph token response');
    }

    $_graph_token_cache['access_token'] = $data['access_token'];
    $_graph_token_cache['expires_at']   = time() + (int)($data['expires_in'] ?? 3600);

    return $data['access_token'];
}

/**
 * Send an email via Microsoft Graph API.
 *
 * @param string      $to_email  Recipient email address.
 * @param string      $subject   Email subject.
 * @param string      $body_html HTML body content.
 * @param string|null $cc_email  Optional CC recipient.
 * @return bool True if sent successfully, false otherwise.
 */
function send_email(string $to_email, string $subject, string $body_html, ?string $cc_email = null): bool
{
    if (GRAPH_CLIENT_SECRET === 'CHANGE_ME_PLACEHOLDER' || empty(GRAPH_TENANT_ID)) {
        app_log('WARNING', 'Graph API not configured - skipping email send');
        return false;
    }

    try {
        $token = get_graph_token();
    } catch (RuntimeException $e) {
        app_log('ERROR', 'Cannot send email - token error: ' . $e->getMessage());
        return false;
    }

    $message = [
        'message' => [
            'subject' => $subject,
            'body' => [
                'contentType' => 'HTML',
                'content'     => $body_html,
            ],
            'from' => [
                'emailAddress' => [
                    'name'    => defined('GRAPH_SENDER_NAME') ? GRAPH_SENDER_NAME : 'Arizona Computer Guru',
                    'address' => GRAPH_SENDER_EMAIL,
                ],
            ],
            'toRecipients' => [
                ['emailAddress' => ['address' => $to_email]],
            ],
            'replyTo' => [
                [
                    'emailAddress' => [
                        'name'    => defined('GRAPH_REPLY_TO_NAME') ? GRAPH_REPLY_TO_NAME : 'Arizona Computer Guru',
                        'address' => defined('GRAPH_REPLY_TO_EMAIL') ? GRAPH_REPLY_TO_EMAIL : GRAPH_SENDER_EMAIL,
                    ],
                ],
            ],
        ],
        'saveToSentItems' => 'true',
    ];

    if ($cc_email !== null) {
        $message['message']['ccRecipients'] = [
            ['emailAddress' => ['address' => $cc_email]],
        ];
    }

    $url = "https://graph.microsoft.com/v1.0/users/" . GRAPH_SENDER_EMAIL . "/sendMail";
    $json_body = json_encode($message, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL            => $url,
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => $json_body,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 15,
        CURLOPT_HTTPHEADER     => [
            'Content-Type: application/json',
            "Authorization: Bearer {$token}",
        ],
    ]);

    $response  = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curl_error = curl_error($ch);
    curl_close($ch);

    if ($response === false) {
        app_log('ERROR', "Graph sendMail curl error: {$curl_error}");
        return false;
    }

    // Graph sendMail returns 202 on success (no body)
    if ($http_code >= 200 && $http_code < 300) {
        app_log('INFO', "[OK] Email sent to {$to_email}: {$subject}");
        return true;
    }

    app_log('ERROR', "[ERROR] Graph sendMail failed (HTTP {$http_code}): {$response}");
    return false;
}

/**
 * Build the HTML email body for a quote submission notification.
 *
 * Matches the exact template from the Python email_service.py implementation.
 *
 * @param string      $company_name  Company name.
 * @param string      $contact_name  Contact name.
 * @param string      $contact_email Contact email address.
 * @param string|null $contact_phone Contact phone number.
 * @param string      $monthly_total Formatted monthly total.
 * @param string      $setup_total   Formatted setup total.
 * @param array       $items         Array of item data (service_name, billing_frequency, unit_price, quantity).
 * @param string|null $notes         Additional notes from the prospect.
 * @return string HTML email body.
 */
function build_quote_notification_html(
    string $company_name,
    string $contact_name,
    string $contact_email,
    ?string $contact_phone,
    string $monthly_total,
    string $setup_total,
    array $items,
    ?string $notes = null
): string {

    $items_html = '';
    foreach ($items as $item) {
        $freq = $item['billing_frequency'] ?? 'monthly';
        $freq_label = $freq === 'monthly' ? '/mo' : ' (one-time)';
        $qty = (int)($item['quantity'] ?? 1);
        $price = $item['unit_price'] ?? '0.00';
        $line_total = (float)$price * $qty;

        $service_name = htmlspecialchars($item['service_name'] ?? '', ENT_QUOTES, 'UTF-8');
        $price_formatted = htmlspecialchars($price, ENT_QUOTES, 'UTF-8');
        $line_formatted = number_format($line_total, 2, '.', ',');

        $items_html .= "
        <tr>
            <td style=\"padding: 8px 12px; border-bottom: 1px solid #e5e7eb;\">{$service_name}</td>
            <td style=\"padding: 8px 12px; border-bottom: 1px solid #e5e7eb; text-align: center;\">{$qty}</td>
            <td style=\"padding: 8px 12px; border-bottom: 1px solid #e5e7eb; text-align: right;\">\${$price_formatted}{$freq_label}</td>
            <td style=\"padding: 8px 12px; border-bottom: 1px solid #e5e7eb; text-align: right;\">\${$line_formatted}{$freq_label}</td>
        </tr>";
    }

    $notes_section = '';
    if ($notes !== null && $notes !== '') {
        $notes_escaped = htmlspecialchars($notes, ENT_QUOTES, 'UTF-8');
        $notes_section = "
        <div style=\"margin-top: 20px; padding: 12px 16px; background: #f8f9fb; border-radius: 8px;\">
            <strong style=\"color: #333d49;\">Notes:</strong>
            <p style=\"margin: 4px 0 0; color: #555;\">{$notes_escaped}</p>
        </div>";
    }

    $phone_line = $contact_phone ? '<br>Phone: ' . htmlspecialchars($contact_phone, ENT_QUOTES, 'UTF-8') : '';
    $contact_name_escaped = htmlspecialchars($contact_name, ENT_QUOTES, 'UTF-8');
    $company_escaped = htmlspecialchars($company_name, ENT_QUOTES, 'UTF-8');
    $email_escaped = htmlspecialchars($contact_email, ENT_QUOTES, 'UTF-8');

    $setup_section = '';
    if ((float)($setup_total ?? 0) > 0) {
        $setup_section = "<div style='background: #fff7ed; border-radius: 8px; padding: 12px 20px; margin-bottom: 20px;'><span style=\"color: #9a3412; font-size: 14px;\">One-Time Costs: <strong>\${$setup_total}</strong></span></div>";
    }

    return "
    <div style=\"font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; max-width: 600px; margin: 0 auto;\">
        <div style=\"background: linear-gradient(135deg, #333d49, #113559); padding: 24px 32px; border-radius: 12px 12px 0 0;\">
            <h1 style=\"color: white; margin: 0; font-size: 22px;\">New Quote Submission</h1>
            <p style=\"color: rgba(255,255,255,0.7); margin: 4px 0 0; font-size: 14px;\">Arizona Computer Guru - MSP Quote Wizard</p>
        </div>

        <div style=\"padding: 24px 32px; border: 1px solid #e5e7eb; border-top: none; border-radius: 0 0 12px 12px;\">
            <div style=\"margin-bottom: 20px;\">
                <h2 style=\"color: #333d49; font-size: 18px; margin: 0 0 8px;\">Contact Information</h2>
                <p style=\"margin: 0; color: #555; line-height: 1.6;\">
                    <strong>{$contact_name_escaped}</strong><br>
                    {$company_escaped}<br>
                    Email: <a href=\"mailto:{$email_escaped}\">{$email_escaped}</a>
                    {$phone_line}
                </p>
            </div>

            <div style=\"background: linear-gradient(135deg, #333d49, #113559); border-radius: 8px; padding: 16px 20px; margin-bottom: 20px; display: flex; justify-content: space-between; align-items: center;\">
                <span style=\"color: rgba(255,255,255,0.8); font-size: 14px;\">Monthly Total</span>
                <span style=\"color: white; font-size: 24px; font-weight: bold;\">\${$monthly_total}/mo</span>
            </div>

            {$setup_section}

            <h3 style=\"color: #333d49; font-size: 16px; margin: 20px 0 8px;\">Services</h3>
            <table style=\"width: 100%; border-collapse: collapse; font-size: 14px;\">
                <thead>
                    <tr style=\"background: #f8f9fb;\">
                        <th style=\"padding: 8px 12px; text-align: left; color: #333d49;\">Service</th>
                        <th style=\"padding: 8px 12px; text-align: center; color: #333d49;\">Qty</th>
                        <th style=\"padding: 8px 12px; text-align: right; color: #333d49;\">Unit Price</th>
                        <th style=\"padding: 8px 12px; text-align: right; color: #333d49;\">Total</th>
                    </tr>
                </thead>
                <tbody>
                    {$items_html}
                </tbody>
            </table>

            {$notes_section}

            <div style=\"margin-top: 24px; padding-top: 16px; border-top: 2px solid #fe7400; text-align: center;\">
                <p style=\"color: #999; font-size: 12px; margin: 0;\">
                    Submitted via <a href=\"https://azcomputerguru.com/quote\" style=\"color: #fe7400;\">azcomputerguru.com/quote</a>
                </p>
            </div>
        </div>
    </div>
    ";
}
