<?php

declare(strict_types=1);

namespace Instinctor\Core\Mailer;


if (!defined('ABSPATH')) exit;
use Instinctor\Core\Config;

/**
 * WordPress mailer driver.
 *
 * Sends via the Instinctor relay server (instinctor.com/wp-json/ilm/v1/send_email),
 * which delivers through SendGrid. Same path as EmailService::sendViaRelay().
 *
 * Falls back to wp_mail() if the relay call fails and
 * INSTINCTOR_MAILER_FALLBACK_WP_MAIL is defined and truthy.
 */
class WordPressDriver implements DriverInterface
{
    private const RELAY_ENDPOINT = 'https://platform.instinctor.com/api/relay/email';
    private const TIMEOUT        = 15;

    public function send(string $to, string $subject, string $body, array $options = []): bool
    {
        if (empty($to) || empty($subject) || empty($body)) {
            return false;
        }

        $storeName  = (string)(Config::get('instinctor_store_name', '') ?: get_bloginfo('name'));
        $storeUrl   = (string)home_url();
        $licenseKey = $this->resolveLicenseKey($storeUrl);
        $isHtml     = $options['html'] ?? $this->looksLikeHtml($body);

        $fromEmail = (string)($options['from_email'] ?? Config::get('store_from_email', '') ?? '');
        $fromName  = (string)($options['from_name']  ?? Config::get('store_from_name', $storeName) ?? $storeName);

        $payload = [
            'license_key' => (string)$licenseKey,
            'site_url'    => $storeUrl,
            'to'          => (string)$to,
            'subject'     => (string)$subject,
            'html'        => $isHtml ? $body : nl2br(htmlspecialchars($body)),
            'from_email'  => $fromEmail,
            'from_name'   => $fromName,
        ];

        if (!empty($options['reply_to'])) {
            $payload['visitor_email'] = $options['reply_to'];
        }

        // WP.org guideline 7/9 — the platform relay is opt-in. When the site
        // owner hasn't connected platform features, fall through to wp_mail
        // (or whatever the install's existing transport is) instead of phoning
        // home with the recipient + subject + body.
        if (!\Instinctor\Core\PlatformConsent::granted()) {
            return $this->maybeWpMailFallback($to, $subject, $body, $isHtml, $options);
        }

        $response = wp_remote_post(self::RELAY_ENDPOINT, [
            'body'    => $payload,
            'timeout' => self::TIMEOUT,
        ]);

        if (is_wp_error($response)) {
            return $this->maybeWpMailFallback($to, $subject, $body, $isHtml, $options);
        }

        $result = json_decode(wp_remote_retrieve_body($response), true);

        if (!empty($result['success'])) {
            return true;
        }

        return $this->maybeWpMailFallback($to, $subject, $body, $isHtml, $options);
    }

    public function queue(string $to, string $subject, string $body, array $options = []): bool
    {
        \Instinctor\Core\Queue::dispatch('email', [
            'to'      => $to,
            'subject' => $subject,
            'body'    => $body,
            'options' => $options,
        ]);
        return true;
    }

    // -------------------------------------------------------------------------
    // Helpers
    // -------------------------------------------------------------------------

    /**
     * Resolve license key using same logic as EmailService and ChatService.
     */
    private function resolveLicenseKey(string $storeUrl): string
    {
        if (str_contains($storeUrl, 'instinctor.com')) {
            return 'INSTINCTOR_APP_INTERNAL';
        }

        $licenses   = Config::get('instinctor_addon_licenses', []);
        $licenseKey = Config::get('instinctor_license_key', '')
            ?: ($licenses['chat']['key'] ?? $licenses['all_access']['key'] ?? '');

        return $licenseKey ?: md5($storeUrl);
    }

    /**
     * Detect HTML content by checking for common HTML tags.
     */
    private function looksLikeHtml(string $body): bool
    {
        return str_contains($body, '<!DOCTYPE')
            || str_contains($body, '<html')
            || str_contains($body, '<p>')
            || str_contains($body, '<br')
            || str_contains($body, '<div')
            || str_contains($body, '<table');
    }

    /**
     * wp_mail() fallback if INSTINCTOR_MAILER_FALLBACK_WP_MAIL is set.
     * Used as a safety net in development or when relay is unreachable.
     */
    private function maybeWpMailFallback(
        string $to,
        string $subject,
        string $body,
        bool $isHtml,
        array $options
    ): bool {
        if (!defined('INSTINCTOR_MAILER_FALLBACK_WP_MAIL') || !INSTINCTOR_MAILER_FALLBACK_WP_MAIL) {
            return false;
        }

        $headers = $isHtml ? ['Content-Type: text/html; charset=UTF-8'] : [];

        if (!empty($options['reply_to'])) {
            $headers[] = 'Reply-To: ' . $options['reply_to'];
        }

        return (bool) wp_mail($to, $subject, $body, $headers);
    }
}
