<?php

declare(strict_types=1);

namespace Instinctor\Services;

use Instinctor\Core\Config;
use Instinctor\Core\Mailer;
use Instinctor\Core\DB;


if ( ! defined( 'ABSPATH' ) ) exit;

/**
 * Email Service
 * Manages email templates and sending
 */
class EmailService
{
    private const OPTION_KEY = 'instinctor_email_templates';
    private const RELAY_URL = 'https://platform.instinctor.com/api/relay';

    public static function getTemplates(): array
    {
        $saved = Config::get(self::OPTION_KEY, []);
        return array_merge(self::getDefaultTemplates(), $saved);
    }

    public static function getTemplate(string $type): array
    {
        $templates = self::getTemplates();
        return $templates[$type] ?? [];
    }

    public static function saveTemplate(string $type, array $data): bool
    {
        $templates = Config::get(self::OPTION_KEY, []);
        
        // Get current values or defaults
        $currentIncludeFooter = $templates[$type]['include_footer'] ?? self::getDefaultIncludeFooter($type);
        $currentEnabled = $templates[$type]['enabled'] ?? false;
        
        $templates[$type] = [
            'subject' => sanitize_text_field(stripslashes($data['subject'] ?? '')),
            'heading' => sanitize_text_field(stripslashes($data['heading'] ?? '')),
            'body' => wp_kses_post(stripslashes($data['body'] ?? '')),
            'enabled' => isset($data['enabled']) ? !empty($data['enabled']) : $currentEnabled,
            'include_footer' => isset($data['include_footer']) ? !empty($data['include_footer']) : $currentIncludeFooter,
        ];
        return Config::set(self::OPTION_KEY, $templates);
    }
    
    /**
     * Bulk enable/disable templates
     */
    public static function bulkUpdateEnabled(array $types, bool $enabled): bool
    {
        $templates = Config::get(self::OPTION_KEY, []);
        $defaults = self::getDefaultTemplates();
        
        foreach ($types as $type) {
            if (isset($defaults[$type])) {
                if (!isset($templates[$type])) {
                    $templates[$type] = $defaults[$type];
                }
                $templates[$type]['enabled'] = $enabled;
            }
        }
        
        return Config::set(self::OPTION_KEY, $templates);
    }
    
    /**
     * Reset all templates to defaults
     */
    public static function resetAllTemplates(): bool
    {
        return Config::delete(self::OPTION_KEY);
    }
    
    /**
     * Fix corrupted templates (remove excessive escaping)
     */
    public static function fixCorruptedTemplates(): int
    {
        $templates = Config::get(self::OPTION_KEY, []);
        $fixed = 0;
        
        foreach ($templates as $type => $template) {
            $changed = false;
            foreach (['subject', 'heading', 'body'] as $field) {
                if (isset($template[$field])) {
                    $original = $template[$field];
                    // Keep stripping slashes until no more double slashes
                    $clean = $original;
                    while (strpos($clean, '\\\\') !== false || strpos($clean, "\\'") !== false) {
                        $clean = stripslashes($clean);
                    }
                    if ($clean !== $original) {
                        $templates[$type][$field] = $clean;
                        $changed = true;
                    }
                }
            }
            if ($changed) {
                $fixed++;
            }
        }
        
        if ($fixed > 0) {
            Config::set(self::OPTION_KEY, $templates);
        }
        
        return $fixed;
    }

    public static function getDefaultTemplates(): array
    {
        $storeName = get_bloginfo('name');
        
        return [
            'order_confirmation' => [
                'subject' => __('Your order #{order_number} has been received', 'instinctor'),
                'heading' => __('Thank you for your order!', 'instinctor'),
                'body' => __("Hi {customer_name},\n\nWe've received your order and it's being processed.\n\n{order_details}\n\nThank you for shopping with us!", 'instinctor'),
                'enabled' => false,
            ],
            'order_processing' => [
                'subject' => __('Your order #{order_number} is being processed', 'instinctor'),
                'heading' => __('Order Processing', 'instinctor'),
                'body' => __("Hi {customer_name},\n\nGood news! Your order is now being prepared.\n\n{order_details}\n\nWe'll notify you when it ships.", 'instinctor'),
                'enabled' => false,
            ],
            'order_shipped' => [
                'subject' => __('Your order #{order_number} has shipped!', 'instinctor'),
                'heading' => __('Your order is on its way!', 'instinctor'),
                'body' => __("Hi {customer_name},\n\nGreat news! Your order has been shipped.\n\n{tracking_info}\n\n{order_details}\n\nThank you for your purchase!", 'instinctor'),
                'enabled' => false,
            ],
            'order_completed' => [
                'subject' => __('Your order #{order_number} is complete', 'instinctor'),
                'heading' => __('Order Complete', 'instinctor'),
                'body' => __("Hi {customer_name},\n\nYour order has been completed.\n\n{order_details}\n\nWe hope you enjoy your purchase! If you have any questions, please don't hesitate to contact us.", 'instinctor'),
                'enabled' => false,
            ],
            'order_cancelled' => [
                'subject' => __('Your order #{order_number} has been cancelled', 'instinctor'),
                'heading' => __('Order Cancelled', 'instinctor'),
                'body' => __("Hi {customer_name},\n\nYour order has been cancelled.\n\n{order_details}\n\nIf you have any questions about this cancellation, please contact us.", 'instinctor'),
                'enabled' => false,
            ],
            'order_refunded' => [
                'subject' => __('Refund for order #{order_number}', 'instinctor'),
                'heading' => __('Refund Processed', 'instinctor'),
                'body' => __("Hi {customer_name},\n\nA refund has been processed for your order.\n\nRefund amount: {refund_amount}\n\n{order_details}\n\nThe refund should appear in your account within 5-10 business days.", 'instinctor'),
                'enabled' => false,
            ],
            'customer_welcome' => [
                'subject' => __('Welcome to {store_name}!', 'instinctor'),
                'heading' => __('Welcome!', 'instinctor'),
                'body' => __("Hi {customer_name},\n\nThank you for creating an account with us.\n\nYou can now:\n- Track your orders\n- Save your addresses\n- Checkout faster\n\nHappy shopping!", 'instinctor'),
                'enabled' => false,
            ],
            'customer_reset_password' => [
                'subject' => __('Password reset for {store_name}', 'instinctor'),
                'heading' => __('Reset Your Password', 'instinctor'),
                'body' => __("Hi {customer_name},\n\nA password reset was requested for your account.\n\nClick here to reset your password:\n{reset_link}\n\nIf you didn't request this, you can safely ignore this email.", 'instinctor'),
                'enabled' => false,
            ],
            'low_stock' => [
                'subject' => __('Low stock alert: {product_name}', 'instinctor'),
                'heading' => __('Low Stock Alert', 'instinctor'),
                'body' => __("{product_name} is running low on stock.\n\nCurrent stock: {stock_quantity}\n\nPlease restock soon.", 'instinctor'),
                'enabled' => false,
            ],
            'new_order_admin' => [
                'subject' => __('New order #{order_number}', 'instinctor'),
                'heading' => __('New Order Received', 'instinctor'),
                'body' => __("You have received a new order!\n\n{order_details}\n\nCustomer: {customer_name}\nEmail: {customer_email}", 'instinctor'),
                'enabled' => false,
            ],
            // v1.3.0 Templates
            'gift_card_received' => [
                'subject' => __('You received a gift card from {sender_name}!', 'instinctor'),
                'heading' => __('You\'ve Got a Gift!', 'instinctor'),
                'body' => __("Hi {recipient_name},\n\n{sender_name} sent you a {amount} gift card!\n\n{personal_message}\n\nYour gift card code: {gift_card_code}\n\nRedeem it at: {store_url}\n\nThis gift card expires: {expires_at}", 'instinctor'),
                'enabled' => false,
            ],
            'loyalty_welcome' => [
                'subject' => __('Welcome to our rewards program!', 'instinctor'),
                'heading' => __('You\'re In!', 'instinctor'),
                'body' => __("Hi {customer_name},\n\nWelcome to our loyalty rewards program!\n\nYou've earned {points} points just for signing up.\n\nEarn more points:\n- 1 point per dollar spent\n- 100 points for referrals\n\nStart shopping and earning!", 'instinctor'),
                'enabled' => false,
            ],
            'loyalty_reminder' => [
                'subject' => __('You have {points} points waiting!', 'instinctor'),
                'heading' => __('Don\'t Forget Your Points!', 'instinctor'),
                'body' => __("Hi {customer_name},\n\nYou have {points} loyalty points worth {points_value}!\n\nYour tier: {tier}\n\nUse them on your next order before they expire.\n\nShop now: {store_url}", 'instinctor'),
                'enabled' => false,
            ],
            'loyalty_expired' => [
                'subject' => __('Your loyalty points have expired', 'instinctor'),
                'heading' => __('Points Expired', 'instinctor'),
                'body' => __("Hi {customer_name},\n\nUnfortunately, {points_expired} loyalty points have expired due to inactivity.\n\nKeep your points active by making a purchase!\n\nShop now: {store_url}", 'instinctor'),
                'enabled' => false,
            ],
            'loyalty_tier_upgrade' => [
                'subject' => __('Congratulations! You\'ve reached {new_tier} status!', 'instinctor'),
                'heading' => __('You Leveled Up!', 'instinctor'),
                'body' => __("Hi {customer_name},\n\nAmazing news! You've been upgraded to {new_tier} tier!\n\nYour new benefits:\n{tier_benefits}\n\nThank you for being a loyal customer!", 'instinctor'),
                'enabled' => false,
            ],
            'rma_approved' => [
                'subject' => __('Your return request #{rma_number} has been approved', 'instinctor'),
                'heading' => __('Return Approved', 'instinctor'),
                'body' => __("Hi {customer_name},\n\nYour return request has been approved.\n\nRMA Number: {rma_number}\nOrder: #{order_number}\n\nPlease ship items to:\n{return_address}\n\nInclude your RMA number on the package.\n\nOnce we receive your items, we'll process your {refund_type}.", 'instinctor'),
                'enabled' => false,
            ],
            'rma_received' => [
                'subject' => __('We received your return #{rma_number}', 'instinctor'),
                'heading' => __('Return Received', 'instinctor'),
                'body' => __("Hi {customer_name},\n\nWe've received your returned items for RMA #{rma_number}.\n\nWe're inspecting your items and will process your {refund_type} within 3-5 business days.\n\nThank you for your patience!", 'instinctor'),
                'enabled' => false,
            ],
            'rma_completed' => [
                'subject' => __('Your return #{rma_number} is complete', 'instinctor'),
                'heading' => __('Return Complete', 'instinctor'),
                'body' => __("Hi {customer_name},\n\nYour return has been completed!\n\nRMA Number: {rma_number}\nRefund Amount: {refund_amount}\n\nThe refund has been processed to your original payment method.", 'instinctor'),
                'enabled' => false,
            ],
            // License & Subscription emails (M4)
            'license_delivery' => [
                'subject' => __('Your Instinctor license key', 'instinctor'),
                'heading' => __('Here\'s your license key', 'instinctor'),
                'body' => __("Hi {customer_name},\n\nThank you for your purchase! Your Instinctor license key is below.\n\n{license_key}\n\nTo activate:\n1. Go to your WordPress admin → Instinctor → License\n2. Paste your license key and click Activate\n\nYour license is valid for {activation_limit} site(s) and expires on {license_expires}.\n\nNeed help? Reply to this email or visit {support_url}.\n\nWelcome aboard!", 'instinctor'),
                'enabled' => true,
            ],
            'subscription_renewal' => [
                'subject' => __('Your Instinctor subscription has renewed', 'instinctor'),
                'heading' => __('Subscription Renewed', 'instinctor'),
                'body' => __("Hi {customer_name},\n\nYour Instinctor {plan_name} subscription has been renewed successfully.\n\nAmount charged: {renewal_amount}\nNext renewal: {next_renewal_date}\n\nYour license key remains the same: {license_key}\n\nManage your subscription: {account_url}\n\nThank you for staying with us!", 'instinctor'),
                'enabled' => true,
            ],
            'payment_failed' => [
                'subject' => __('Action required: payment failed for your Instinctor subscription', 'instinctor'),
                'heading' => __('Payment Failed', 'instinctor'),
                'body' => __("Hi {customer_name},\n\nWe were unable to process the payment for your Instinctor {plan_name} subscription.\n\nTo keep your Pro features active, please update your payment method:\n{update_payment_url}\n\nWe'll retry the payment automatically. If it fails again, your subscription will be paused.\n\nIf you need help, just reply to this email.", 'instinctor'),
                'enabled' => true,
            ],
            'subscription_cancelled' => [
                'subject' => __('Your Instinctor subscription has been cancelled', 'instinctor'),
                'heading' => __('Subscription Cancelled', 'instinctor'),
                'body' => __("Hi {customer_name},\n\nYour Instinctor {plan_name} subscription has been cancelled.\n\nYour Pro features will remain active until {access_until}. After that, your site will revert to the free tier.\n\nChanged your mind? Resubscribe any time at {resubscribe_url}.\n\nWe'd love to know why you cancelled, it helps us improve. Just hit reply.\n\nThank you for being a customer.", 'instinctor'),
                'enabled' => true,
            ],
        ];
    }

    public static function getPlaceholders(): array
    {
        return [
            '{order_number}' => __('Order number', 'instinctor'),
            '{order_date}' => __('Order date', 'instinctor'),
            '{order_total}' => __('Order total', 'instinctor'),
            '{order_details}' => __('Order items table', 'instinctor'),
            '{customer_name}' => __('Customer full name', 'instinctor'),
            '{customer_first_name}' => __('Customer first name', 'instinctor'),
            '{customer_email}' => __('Customer email', 'instinctor'),
            '{billing_address}' => __('Billing address', 'instinctor'),
            '{shipping_address}' => __('Shipping address', 'instinctor'),
            '{tracking_number}' => __('Tracking number', 'instinctor'),
            '{tracking_url}' => __('Tracking URL', 'instinctor'),
            '{tracking_info}' => __('Full tracking info block', 'instinctor'),
            '{store_name}' => __('Store name', 'instinctor'),
            '{store_url}' => __('Store URL', 'instinctor'),
            '{refund_amount}' => __('Refund amount', 'instinctor'),
            '{product_name}' => __('Product name', 'instinctor'),
            '{product_sku}' => __('Product SKU', 'instinctor'),
            '{stock_quantity}' => __('Stock quantity', 'instinctor'),
            '{reset_link}' => __('Password reset link', 'instinctor'),
            // v1.3.0 placeholders
            '{gift_card_code}' => __('Gift card code', 'instinctor'),
            '{sender_name}' => __('Gift card sender name', 'instinctor'),
            '{recipient_name}' => __('Gift card recipient name', 'instinctor'),
            '{amount}' => __('Gift card amount', 'instinctor'),
            '{personal_message}' => __('Gift card personal message', 'instinctor'),
            '{expires_at}' => __('Expiration date', 'instinctor'),
            '{points}' => __('Loyalty points', 'instinctor'),
            '{points_value}' => __('Loyalty points value', 'instinctor'),
            '{points_expired}' => __('Expired points count', 'instinctor'),
            '{tier}' => __('Loyalty tier', 'instinctor'),
            '{new_tier}' => __('New loyalty tier', 'instinctor'),
            '{tier_benefits}' => __('Tier benefits list', 'instinctor'),
            '{rma_number}' => __('RMA number', 'instinctor'),
            '{refund_type}' => __('Refund type', 'instinctor'),
            '{return_address}' => __('Return shipping address', 'instinctor'),
            '{support_email}' => __('Support email address', 'instinctor'),
            '{store_phone}' => __('Store phone number', 'instinctor'),
            '{product_url}' => __('Product URL', 'instinctor'),
            '{product_price}' => __('Product price', 'instinctor'),
            '{original_price}' => __('Original price', 'instinctor'),
            '{sale_price}' => __('Sale price', 'instinctor'),
            '{carrier}' => __('Shipping carrier', 'instinctor'),
            // License & Subscription placeholders (M4)
            '{license_key}' => __('License key', 'instinctor'),
            '{activation_limit}' => __('Activation limit (number of sites)', 'instinctor'),
            '{license_expires}' => __('License expiry date', 'instinctor'),
            '{support_url}' => __('Support URL', 'instinctor'),
            '{plan_name}' => __('Subscription plan name', 'instinctor'),
            '{renewal_amount}' => __('Renewal charge amount', 'instinctor'),
            '{next_renewal_date}' => __('Next renewal date', 'instinctor'),
            '{account_url}' => __('Customer account URL', 'instinctor'),
            '{update_payment_url}' => __('Update payment method URL', 'instinctor'),
            '{access_until}' => __('Date Pro access ends after cancellation', 'instinctor'),
            '{resubscribe_url}' => __('Resubscribe / pricing page URL', 'instinctor'),
            '{days_remaining}' => __('Days remaining in trial (e.g. "in 3 days" or "today")', 'instinctor'),
            '{upgrade_url}' => __('Upgrade / pricing page URL', 'instinctor'),
            '{whats_new}' => __('Recent changelog highlights', 'instinctor'),
        ];
    }

    public static function send(string $type, string $to, array $data = []): bool
    {
        $template = self::getTemplate($type);
        
        if (empty($template) || !$template['enabled']) {
            return false;
        }

        return self::sendWithTemplate($template, $to, $data, $type);
    }
    
    /**
     * Send test email - bypasses enabled check
     */
    public static function sendTest(string $type, string $to, array $data = []): bool
    {
        $template = self::getTemplate($type);
        
        if (empty($template)) {
            return false;
        }

        return self::sendWithTemplate($template, $to, $data, $type);
    }
    
    /**
     * Get formatted store address for emails
     */
    public static function getStoreAddress(): string
    {
        $parts = array_filter([
            Config::get('instinctor_store_name', get_bloginfo('name')),
            Config::get('instinctor_store_address_1', ''),
            Config::get('instinctor_store_address_2', ''),
            trim(
                Config::get('instinctor_store_city', '') . 
                (Config::get('instinctor_store_city') && Config::get('instinctor_store_state') ? ', ' : '') .
                Config::get('instinctor_store_state', '') . ' ' .
                Config::get('instinctor_store_postcode', '')
            ),
            Config::get('instinctor_country', 'US'),
        ]);
        
        return implode("\n", $parts);
    }
    
    /**
     * Get store contact info
     */
    public static function getStoreContact(): array
    {
        return [
            'email' => Config::get('instinctor_store_email', Config::get('admin_email', '')),
            'phone' => Config::get('instinctor_store_phone', ''),
        ];
    }
    
    /**
     * Internal method to send with a template
     */
    private static function sendWithTemplate(array $template, string $to, array $data = [], string $type = ''): bool
    {
        // Auto-populate common placeholders if not provided
        $defaults = [
            'store_name' => Config::get('instinctor_store_name', get_bloginfo('name')),
            'store_url' => home_url(),
            'return_address' => self::getStoreAddress(),
            'support_email' => Config::get('instinctor_store_email', Config::get('admin_email', '')),
            'store_phone' => Config::get('instinctor_store_phone', ''),
        ];
        
        $data = array_merge($defaults, $data);
        
        $subject = self::replacePlaceholders($template['subject'], $data);
        $heading = self::replacePlaceholders($template['heading'], $data);
        $body = self::replacePlaceholders($template['body'], $data);
        
        // Check if footer should be included
        $includeFooter = $template['include_footer'] ?? self::getDefaultIncludeFooter($type);

        $html = self::buildEmailHtml($heading, $body, $data, $includeFooter);

        // Use relay server for reliable delivery (same as ChatService)
        return self::sendViaRelay($to, $subject, $html);
    }
    
    /**
     * Send email via relay server (uses SendGrid for reliable delivery)
     */
    private static function sendViaRelay(string $toEmail, string $subject, string $htmlContent): bool
    {
        // Delegated to Mailer facade — handles relay on WP, direct SendGrid on standalone
        return Mailer::html($toEmail, $subject, $htmlContent);
    }
    
    /**
     * Public method for sending pre-built HTML emails via relay
     * Used by AdminController for test emails
     */
    public static function sendDirectEmail(string $toEmail, string $subject, string $htmlContent): bool
    {
        return self::sendViaRelay($toEmail, $subject, $htmlContent);
    }

    /**
     * Build notification HTML using the standard email template
     * For non-template emails (form submissions, system notifications, etc.)
     */
    public static function buildNotificationHtml(string $heading, string $body): string
    {
        return self::buildEmailHtml($heading, $body, [
            'store_name' => Config::get('instinctor_store_name', get_bloginfo('name')),
            'store_url' => home_url(),
        ], true);
    }

    /**
     * Form-submission notification, laid out as a table instead of a run of
     * label/value lines.
     *
     * The plain-text body path renders each field as "<strong>Label:</strong>\n
     * value\n\n", and buildEmailHtml's nl2br turns every one of those breaks into
     * a <br>. On a 12-field form that produced a full-width row per field with a
     * double line break between each, so a lead that fits on half a screen filled
     * several. Short values now pair two-per-row, long ones keep the full width,
     * checkbox fields collapse to a single line, and empty fields are dropped
     * rather than printed as a bare label. (Sergei 2026-08-11)
     *
     * @param array<string,mixed> $formData Raw submitted fields, keyed by field name.
     * @param array<string,string> $meta    Footer rows (submission id, time, IP).
     */
    public static function buildFormNotificationHtml(string $heading, array $formData, array $meta = []): string
    {
        // Plumbing that the person reading a lead never needs to see.
        $skip = ['page_id', 'form_id', 'form_name', 'action', 'nonce', 'attribution',
                 '_instinctor_hp', '_instinctor_ts', 'instinctor_hp'];

        $pairs  = [];   // short values: two per row
        $blocks = [];   // long values: full width
        $flags  = [];   // checkbox-style fields, collapsed into one line

        foreach ($formData as $key => $value) {
            if (in_array($key, $skip, true)) { continue; }
            if (is_array($value)) { $value = implode(', ', $value); }
            // Stored values are wp_kses_post'd, so decode once here and escape on output.
            $value = trim(html_entity_decode((string) $value, ENT_QUOTES, 'UTF-8'));
            if ($value === '') { continue; }

            $label = ucwords(str_replace(['_', '-'], ' ', (string) $key));

            if (in_array(strtolower($value), ['on', 'yes', '1', 'true'], true)) {
                // "need_store" => "Store", so the collapsed line reads as a list of wants.
                $flags[] = preg_replace('/^(Need|Want|Wants)\s+/i', '', $label);
                continue;
            }
            if (mb_strlen($value) > 48 || strpos($value, "\n") !== false) {
                $blocks[] = [$label, $value];
            } else {
                $pairs[] = [$label, $value, (string) $key];
            }
        }

        $lbl = 'font:600 11px/1.3 -apple-system,BlinkMacSystemFont,\'Segoe UI\',Roboto,sans-serif;'
             . 'letter-spacing:.06em;text-transform:uppercase;color:#86868b;padding-bottom:3px;';
        $val = 'font-size:15px;line-height:1.45;color:#1d1d1f;word-break:break-word;';

        $rows = '';

        // Short fields, two to a row.
        for ($i = 0, $n = count($pairs); $i < $n; $i += 2) {
            $rows .= '<tr>';
            foreach ([$pairs[$i], $pairs[$i + 1] ?? null] as $cell) {
                if ($cell === null) { $rows .= '<td width="50%" style="padding:0 0 14px;"></td>'; continue; }
                [$label, $value, $key] = $cell;
                $rows .= '<td width="50%" valign="top" style="padding:0 14px 14px 0;">'
                       . '<div style="' . $lbl . '">' . esc_html($label) . '</div>'
                       . '<div style="' . $val . '">' . self::linkifyFieldValue($key, $value) . '</div>'
                       . '</td>';
            }
            $rows .= '</tr>';
        }

        if ($flags) {
            $rows .= '<tr><td colspan="2" style="padding:0 0 14px;">'
                   . '<div style="' . $lbl . '">Also wants</div>'
                   . '<div style="' . $val . '">' . esc_html(implode(', ', $flags)) . '</div>'
                   . '</td></tr>';
        }

        foreach ($blocks as [$label, $value]) {
            $rows .= '<tr><td colspan="2" style="padding:0 0 14px;">'
                   . '<div style="' . $lbl . '">' . esc_html($label) . '</div>'
                   . '<div style="' . $val . 'white-space:pre-wrap;">' . esc_html($value) . '</div>'
                   . '</td></tr>';
        }

        if ($rows === '') {
            $rows = '<tr><td colspan="2" style="' . $val . 'color:#86868b;">'
                  . 'Every field was submitted empty. This is very likely junk rather than a lead.'
                  . '</td></tr>';
        }

        if ($meta) {
            $bits = [];
            foreach ($meta as $k => $v) {
                if ((string) $v === '') { continue; }
                $bits[] = esc_html($k) . ' ' . esc_html((string) $v);
            }
            if ($bits) {
                $rows .= '<tr><td colspan="2" style="padding:6px 0 0;border-top:1px solid #e8e8ed;">'
                       . '<div style="font-size:11px;line-height:1.5;color:#a1a1a6;">'
                       . implode(' &nbsp;·&nbsp; ', $bits) . '</div></td></tr>';
            }
        }

        $html = '<table width="100%" cellpadding="0" cellspacing="0" role="presentation" '
              . 'style="border-collapse:collapse;">' . $rows . '</table>';

        return self::buildEmailHtml($heading, $html, [
            'store_name' => Config::get('instinctor_store_name', get_bloginfo('name')),
            'store_url' => home_url(),
        ], true, true);
    }

    /**
     * Make a lead actionable from the notification: tap the phone, tap the email.
     * Falls back to escaped plain text for anything unrecognised.
     */
    private static function linkifyFieldValue(string $key, string $value): string
    {
        $k    = strtolower($key);
        $link = 'color:#1d1d1f;text-decoration:underline;';

        // filter_var, not is_email(): the standalone shim does not define is_email.
        if (strpos($k, 'email') !== false && filter_var($value, FILTER_VALIDATE_EMAIL)) {
            return '<a href="mailto:' . esc_attr($value) . '" style="' . $link . '">' . esc_html($value) . '</a>';
        }
        if (strpos($k, 'phone') !== false || strpos($k, 'tel') !== false) {
            $digits = preg_replace('/[^0-9+]/', '', $value);
            if (strlen($digits) >= 7) {
                return '<a href="tel:' . esc_attr($digits) . '" style="' . $link . '">' . esc_html($value) . '</a>';
            }
        }
        if (preg_match('#^https?://#i', $value)) {
            return '<a href="' . esc_url($value) . '" style="' . $link . '">' . esc_html($value) . '</a>';
        }
        return esc_html($value);
    }

    public static function sendOrderEmail(string $type, int $orderId): bool
    {
        $p = DB::prefix();
        
        $order = DB::get_row(DB::prepare(
            "SELECT o.*, c.email as customer_email_resolved
             FROM {$p}instinctor_orders o
             LEFT JOIN {$p}instinctor_customers c ON o.customer_id = c.id
             WHERE o.id = %d",
            $orderId
        ));

        if (!$order) {
            return false;
        }

        $items = DB::get_results(DB::prepare(
            "SELECT * FROM {$p}instinctor_order_items WHERE order_id = %d",
            $orderId
        ));

        $billing = json_decode($order->billing_address, true) ?: [];
        $shipping = json_decode($order->shipping_address, true) ?: [];
        $meta = json_decode($order->meta ?? '{}', true);
        
        // Resolve customer email
        $customerEmail = $order->customer_email_resolved ?: ($billing['email'] ?? '');
        if (empty($customerEmail)) {
            return false;
        }
        
        // Get tracking from tracking table with meta fallback
        $trackingRow = DB::get_row(DB::prepare(
            "SELECT tracking_number, tracking_url FROM {$p}instinctor_order_tracking WHERE order_id = %d ORDER BY created_at DESC LIMIT 1",
            $orderId
        ));
        $trackingNumber = ($trackingRow->tracking_number ?? '') ?: ($meta['tracking_number'] ?? '');
        $trackingUrl = ($trackingRow->tracking_url ?? '') ?: ($meta['tracking_url'] ?? '');

        $data = [
            'order_number' => $order->order_number,
            'order_date' => date_i18n(Config::get('date_format', 'Y-m-d'), strtotime($order->created_at)),
            'order_total' => CurrencyService::formatPrice($order->total),
            'order_details' => self::buildOrderDetailsTable($items),
            'customer_name' => trim(($billing['first_name'] ?? '') . ' ' . ($billing['last_name'] ?? '')),
            'customer_first_name' => $billing['first_name'] ?? '',
            'customer_email' => $customerEmail,
            'billing_address' => self::formatAddress($billing),
            'shipping_address' => self::formatAddress($shipping),
            'store_name' => get_bloginfo('name'),
            'store_url' => home_url(),
            'tracking_number' => $trackingNumber,
            'tracking_url' => $trackingUrl,
        ];

        return self::send($type, $customerEmail, $data);
    }

    private static function replacePlaceholders(string $text, array $data): string
    {
        foreach ($data as $key => $value) {
            $placeholder = '{' . $key . '}';
            $text = str_replace($placeholder, $value, $text);
        }
        return $text;
    }

    /**
     * Get default footer settings
     */
    public static function getDefaultFooterSettings(): array
    {
        return [
            'show_store_name' => true,
            'show_address' => true,
            'show_city_state_zip' => true,
            'show_country' => false,
            'show_email' => true,
            'show_phone' => true,
            'show_social' => false,
            'custom_text' => '',
            // Styling options
            'text_align' => 'center',
            'show_logo' => false,
            'store_name_size' => '14',
            'store_name_weight' => '600',
            'address_size' => '12',
            'address_weight' => '400',
            'contact_size' => '12',
            'contact_weight' => '400',
            'custom_size' => '11',
            'custom_weight' => '400',
        ];
    }
    
    /**
     * Get footer settings
     */
    public static function getFooterSettings(): array
    {
        $saved = Config::get('instinctor_email_footer_settings', []);
        return array_merge(self::getDefaultFooterSettings(), $saved);
    }
    
    /**
     * Save footer settings
     */
    public static function saveFooterSettings(array $settings): bool
    {
        return Config::set('instinctor_email_footer_settings', $settings);
    }
    
    /**
     * Check if email type is an admin-only notification
     */
    public static function isAdminEmail(string $type): bool
    {
        return in_array($type, ['low_stock', 'new_order_admin'], true);
    }
    
    /**
     * Get default include_footer setting for email type
     */
    public static function getDefaultIncludeFooter(string $type): bool
    {
        // Admin emails don't include footer by default
        return !self::isAdminEmail($type);
    }
    
    /**
     * Build a test email with the given content
     */
    public static function buildTestEmail(string $heading, string $body): string
    {
        return self::buildEmailHtml($heading, $body, [], true);
    }

    /**
     * @param bool $rawBody Body is already HTML and must not be escaped. Used by
     *                      buildFormNotificationHtml(), which composes its own table.
     */
    private static function buildEmailHtml(string $heading, string $body, array $data, bool $includeFooter = true, bool $rawBody = false): string
    {
        $storeName = get_bloginfo('name');
        $storeUrl = home_url();
        $primaryColor = '#1d1d1f';
        
        // Get footer settings
        $footerSettings = self::getFooterSettings();
        
        // Get styling options
        $textAlign = $footerSettings['text_align'] ?? 'center';
        $storeNameSize = $footerSettings['store_name_size'] ?? '14';
        $storeNameWeight = $footerSettings['store_name_weight'] ?? '600';
        $addressSize = $footerSettings['address_size'] ?? '12';
        $addressWeight = $footerSettings['address_weight'] ?? '400';
        $contactSize = $footerSettings['contact_size'] ?? '12';
        $contactWeight = $footerSettings['contact_weight'] ?? '400';
        $customSize = $footerSettings['custom_size'] ?? '11';
        $customWeight = $footerSettings['custom_weight'] ?? '400';
        
        // Get store info from settings
        $storeAddress = Config::get('instinctor_store_address', '');
        $storeCity = Config::get('instinctor_store_city', '');
        $storeState = Config::get('instinctor_store_state', '');
        $storePostcode = Config::get('instinctor_store_postcode', '');
        $storeCountry = Config::get('instinctor_store_country', '');
        $storeEmail = Config::get('instinctor_store_email', Config::get('admin_email', ''));
        $storePhone = Config::get('instinctor_store_phone', '');
        
        // Build footer HTML parts
        $logoHtml = '';
        $storeNameHtml = '';
        $addressHtml = '';
        $contactHtml = '';
        $socialHtml = '';
        $customFooterText = '';
        
        if ($includeFooter) {
            // Logo
            if (!empty($footerSettings['show_logo'])) {
                $customLogoId = get_theme_mod('custom_logo');
                if ($customLogoId) {
                    $logoUrl = wp_get_attachment_image_url($customLogoId, 'medium');
                    if ($logoUrl) {
                        $logoHtml = '<div style="margin-bottom:12px;"><img src="' . esc_url($logoUrl) . '" alt="' . esc_attr($storeName) . '" style="max-height:50px;width:auto;"></div>';
                    }
                }
            }
            
            // Store name
            if (!empty($footerSettings['show_store_name'])) {
                $storeNameHtml = '<div style="font-size:' . esc_attr($storeNameSize) . 'px;font-weight:' . esc_attr($storeNameWeight) . ';margin-bottom:8px;"><a href="' . esc_url($storeUrl) . '" style="color:#1d1d1f;text-decoration:none;">' . esc_html($storeName) . '</a></div>';
            }
            
            // Address parts
            $addressParts = [];
            if (!empty($footerSettings['show_address']) && $storeAddress) {
                $addressParts[] = esc_html($storeAddress);
            }
            if (!empty($footerSettings['show_city_state_zip'])) {
                $cityLine = array_filter([$storeCity, $storeState, $storePostcode]);
                if ($cityLine) {
                    $addressParts[] = esc_html(implode(', ', $cityLine));
                }
            }
            if (!empty($footerSettings['show_country']) && $storeCountry) {
                $addressParts[] = esc_html($storeCountry);
            }
            if (!empty($addressParts)) {
                $addressHtml = '<div style="font-size:' . esc_attr($addressSize) . 'px;font-weight:' . esc_attr($addressWeight) . ';color:#86868b;margin-bottom:4px;">' . implode('<br>', $addressParts) . '</div>';
            }
            
            // Contact parts
            $contactParts = [];
            if (!empty($footerSettings['show_email']) && $storeEmail) {
                $contactParts[] = '<a href="mailto:' . esc_attr($storeEmail) . '" style="color:#86868b;">' . esc_html($storeEmail) . '</a>';
            }
            if (!empty($footerSettings['show_phone']) && $storePhone) {
                $contactParts[] = esc_html($storePhone);
            }
            if (!empty($contactParts)) {
                $contactHtml = '<div style="font-size:' . esc_attr($contactSize) . 'px;font-weight:' . esc_attr($contactWeight) . ';color:#86868b;margin-bottom:4px;">' . implode(' &bull; ', $contactParts) . '</div>';
            }
            
            // Social media
            if (!empty($footerSettings['show_social'])) {
                $socialLinks = [];
                $facebook = Config::get('instinctor_social_facebook', '');
                $instagram = Config::get('instinctor_social_instagram', '');
                $twitter = Config::get('instinctor_social_twitter', '');
                
                if ($facebook) {
                    $socialLinks[] = '<a href="' . esc_url($facebook) . '" style="color:#86868b;text-decoration:none;margin:0 8px;">Facebook</a>';
                }
                if ($instagram) {
                    $socialLinks[] = '<a href="' . esc_url($instagram) . '" style="color:#86868b;text-decoration:none;margin:0 8px;">Instagram</a>';
                }
                if ($twitter) {
                    $socialLinks[] = '<a href="' . esc_url($twitter) . '" style="color:#86868b;text-decoration:none;margin:0 8px;">Twitter</a>';
                }
                
                if ($socialLinks) {
                    $socialHtml = '<div style="margin-top:12px;">' . implode('', $socialLinks) . '</div>';
                }
            }
            
            // Custom footer text
            if (!empty($footerSettings['custom_text'])) {
                $customFooterText = '<div style="font-size:' . esc_attr($customSize) . 'px;font-weight:' . esc_attr($customWeight) . ';color:#a1a1a6;margin-top:12px;padding-top:12px;border-top:1px solid #e8e8ed;">' . esc_html($footerSettings['custom_text']) . '</div>';
            }
        }
        
        $bodyHtml = $body;

        // A raw body is already trusted HTML built by us; escaping and the
        // tag-restore dance below apply only to the plain-text path.
        if (!$rawBody) {
            $bodyHtml = nl2br(esc_html($body));

            // Restore order details and tracking info FIRST (before strong tag conversion)
            if (isset($data['order_details'])) {
                $bodyHtml = str_replace(esc_html($data['order_details']), $data['order_details'], $bodyHtml);
            }
            if (isset($data['tracking_info'])) {
                $bodyHtml = str_replace(esc_html($data['tracking_info']), $data['tracking_info'], $bodyHtml);
            }

            // Then allow certain HTML in body text
            $bodyHtml = str_replace(
                ['&lt;strong&gt;', '&lt;/strong&gt;', '&lt;br&gt;', '&lt;br/&gt;'],
                ['<strong>', '</strong>', '<br>', '<br>'],
                $bodyHtml
            );
        }

        return '<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body style="margin:0; padding:0; background:#f5f5f7; font-family:-apple-system,BlinkMacSystemFont,\'Segoe UI\',Roboto,sans-serif;">
    <table width="100%" cellpadding="0" cellspacing="0" style="background:#f5f5f7; padding:20px 8px;">
        <tr>
            <td align="center">
                <table width="640" cellpadding="0" cellspacing="0" style="background:#fff; border-radius:8px; overflow:hidden;">
                    <tr>
                        <td style="padding:18px 24px; background:' . esc_attr($primaryColor) . '; color:#fff;">
                            <h1 style="margin:0; font-size:19px; font-weight:600;">' . esc_html($heading) . '</h1>
                        </td>
                    </tr>
                    <tr>
                        <td style="padding:22px 24px; font-size:15px; line-height:1.55; color:#1d1d1f;">
                            ' . $bodyHtml . '
                        </td>
                    </tr>
                    <tr>
                        <td style="padding:14px 24px; background:#f5f5f7; text-align:' . esc_attr($textAlign) . '; font-size:13px; color:#86868b; line-height:1.5;">
                            ' . $logoHtml . '
                            ' . $storeNameHtml . '
                            ' . $addressHtml . '
                            ' . $contactHtml . '
                            ' . $socialHtml . '
                            ' . $customFooterText . '
                        </td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
</body>
</html>';
    }

    private static function buildOrderDetailsTable(array $items): string
    {
        $html = '<table width="100%" cellpadding="8" cellspacing="0" style="border:1px solid #e8e8ed; border-radius:6px; margin:16px 0;">';
        $html .= '<tr style="background:#f5f5f7;"><th align="left" style="border-bottom:1px solid #e8e8ed;">Item</th><th align="right" style="border-bottom:1px solid #e8e8ed;">Qty</th><th align="right" style="border-bottom:1px solid #e8e8ed;">Price</th></tr>';

        foreach ($items as $item) {
            $meta   = json_decode($item->meta ?? '{}', true) ?: [];
            $addons = is_array($meta['addons'] ?? null) ? $meta['addons'] : [];

            // Build addon line(s) — keys are names, values are customer input
            $addonLines = '';
            foreach ($addons as $name => $val) {
                if ($val === '' || $val === null) continue;
                $label = ($val === '1' || $val === 1)
                    ? esc_html($name)
                    : esc_html($name) . ': ' . esc_html((string) $val);
                $addonLines .= '<div style="font-size:12px;color:#888;margin-top:2px">+ ' . $label . '</div>';
            }

            $html .= '<tr>';
            $html .= '<td style="border-bottom:1px solid #e8e8ed;">' . esc_html($item->name) . $addonLines . '</td>';
            $html .= '<td align="right" style="border-bottom:1px solid #e8e8ed;">' . intval($item->quantity) . '</td>';
            $html .= '<td align="right" style="border-bottom:1px solid #e8e8ed;">$' . number_format($item->total, 2) . '</td>';
            $html .= '</tr>';
        }

        $html .= '</table>';
        return $html;
    }

    private static function buildTrackingInfo(object $order): string
    {
        if (empty($order->tracking_number)) {
            return '';
        }

        $html = '<div style="background:#f5f5f7; padding:16px; border-radius:6px; margin:16px 0;">';
        $html .= '<strong>Tracking Number:</strong> ' . esc_html($order->tracking_number);
        
        if (!empty($order->tracking_url)) {
            $html .= '<br><a href="' . esc_url($order->tracking_url) . '" style="color:#0066cc;">Track your package</a>';
        }
        
        $html .= '</div>';
        return $html;
    }

    private static function formatAddress(array $address): string
    {
        $parts = array_filter([
            trim(($address['first_name'] ?? '') . ' ' . ($address['last_name'] ?? '')),
            $address['address_1'] ?? '',
            $address['address_2'] ?? '',
            trim(($address['city'] ?? '') . ', ' . ($address['state'] ?? '') . ' ' . ($address['postcode'] ?? '')),
            $address['country'] ?? '',
        ]);
        return implode('<br>', $parts);
    }
}
