<?php
/**
 * License Email Controller
 *
 * @package Jeremias\WcLicensedProduct\Email
 */

declare(strict_types=1);

namespace Jeremias\WcLicensedProduct\Email;

use Jeremias\WcLicensedProduct\License\LicenseManager;
use Jeremias\WcLicensedProduct\Admin\SettingsController;

/**
 * Handles email notifications for licenses
 */
final class LicenseEmailController
{
    private LicenseManager $licenseManager;

    public function __construct(LicenseManager $licenseManager)
    {
        $this->licenseManager = $licenseManager;
        $this->registerHooks();
    }

    /**
     * Register WordPress hooks
     */
    private function registerHooks(): void
    {
        // Register custom WooCommerce email classes
        add_filter('woocommerce_email_classes', [$this, 'registerEmailClasses']);

        // Add license info to order completed email
        add_action('woocommerce_email_after_order_table', [$this, 'addLicenseInfoToEmail'], 20, 4);

        // Add license info to order details in emails
        add_action('woocommerce_order_item_meta_end', [$this, 'addLicenseToOrderItem'], 10, 4);

        // Schedule cron job for expiration warnings
        add_action('init', [$this, 'scheduleExpirationCheck']);

        // Cron action for checking expiring licenses
        add_action('wclp_check_expiring_licenses', [$this, 'sendExpirationWarnings']);
    }

    /**
     * Register custom email classes with WooCommerce
     *
     * @param array $email_classes Existing email classes
     * @return array Modified email classes
     */
    public function registerEmailClasses(array $email_classes): array
    {
        $email_classes['WCLP_License_Expiration'] = new LicenseExpirationEmail();
        $email_classes['WCLP_License_Expired'] = new LicenseExpiredEmail();
        return $email_classes;
    }

    /**
     * Schedule the expiration check cron job
     */
    public function scheduleExpirationCheck(): void
    {
        if (!wp_next_scheduled('wclp_check_expiring_licenses')) {
            wp_schedule_event(time(), 'daily', 'wclp_check_expiring_licenses');
        }
    }

    /**
     * Send expiration warning emails and auto-expire licenses
     */
    public function sendExpirationWarnings(): void
    {
        // First, auto-expire licenses that have passed their expiration date
        $this->autoExpireAndNotify();

        // Check if expiration emails are enabled in settings
        if (!SettingsController::isExpirationEmailsEnabled()) {
            return;
        }

        // Get the WooCommerce email instance
        $mailer = WC()->mailer();
        $emails = $mailer->get_emails();

        if (!isset($emails['WCLP_License_Expiration'])) {
            return;
        }

        /** @var LicenseExpirationEmail $expirationEmail */
        $expirationEmail = $emails['WCLP_License_Expiration'];

        // Check if the email is enabled
        if (!$expirationEmail->is_enabled()) {
            return;
        }

        // Get configurable warning days
        $firstWarningDays = SettingsController::getFirstWarningDays();
        $secondWarningDays = SettingsController::getSecondWarningDays();

        // Check for licenses expiring at first warning threshold
        $this->processExpirationWarnings($expirationEmail, $firstWarningDays, 'expiring_first_warning');

        // Check for licenses expiring at second warning threshold (if enabled)
        if ($secondWarningDays > 0 && $secondWarningDays < $firstWarningDays) {
            $this->processExpirationWarnings($expirationEmail, $secondWarningDays, 'expiring_second_warning');
        }
    }

    /**
     * Auto-expire licenses and send expired notifications
     */
    private function autoExpireAndNotify(): void
    {
        // Get licenses that should be auto-expired
        $expiredActiveLicenses = $this->licenseManager->getExpiredActiveLicenses();

        if (empty($expiredActiveLicenses)) {
            return;
        }

        // Get the WooCommerce email instance for expired notifications
        $mailer = WC()->mailer();
        $emails = $mailer->get_emails();

        /** @var LicenseExpiredEmail|null $expiredEmail */
        $expiredEmail = $emails['WCLP_License_Expired'] ?? null;

        foreach ($expiredActiveLicenses as $license) {
            // Auto-expire the license
            $wasExpired = $this->licenseManager->autoExpireLicense($license->getId());

            if ($wasExpired && $expiredEmail && $expiredEmail->is_enabled()) {
                // Check if we haven't already sent an expired notification
                if (!$this->licenseManager->wasExpirationNotified($license->getId(), 'license_expired')) {
                    // Send expired notification email
                    if ($expiredEmail->trigger($license)) {
                        $this->licenseManager->markExpirationNotified($license->getId(), 'license_expired');
                    }
                }
            }
        }
    }

    /**
     * Process and send expiration warnings for a specific time frame
     *
     * @param LicenseExpirationEmail $email Email instance
     * @param int $days Days until expiration
     * @param string $notificationType Notification type identifier
     */
    private function processExpirationWarnings(LicenseExpirationEmail $email, int $days, string $notificationType): void
    {
        $licenses = $this->licenseManager->getLicensesExpiringSoon($days);

        foreach ($licenses as $license) {
            // Skip if already notified
            if ($this->licenseManager->wasExpirationNotified($license->getId(), $notificationType)) {
                continue;
            }

            // Send the warning email using WooCommerce email system
            if ($email->trigger($license, $days)) {
                // Mark as notified
                $this->licenseManager->markExpirationNotified($license->getId(), $notificationType);
            }
        }
    }

    /**
     * Add license information to order completed email
     */
    public function addLicenseInfoToEmail(\WC_Order $order, bool $sentToAdmin, bool $plainText, $email): void
    {
        // Only add to completed order email sent to customer
        if ($sentToAdmin || !$email || $email->id !== 'customer_completed_order') {
            return;
        }

        $licenses = $this->getLicensesForOrder($order);
        if (empty($licenses)) {
            return;
        }

        if ($plainText) {
            $this->renderPlainTextLicenseInfo($licenses, $order);
        } else {
            $this->renderHtmlLicenseInfo($licenses, $order);
        }
    }

    /**
     * Add license key(s) to order item in email
     */
    public function addLicenseToOrderItem(int $itemId, \WC_Order_Item $item, \WC_Order $order, bool $plainText): void
    {
        $product = $item->get_product();
        if (!$product || !$product->is_type('licensed')) {
            return;
        }

        $licenses = $this->licenseManager->getLicensesByOrderAndProduct($order->get_id(), $product->get_id());
        if (empty($licenses)) {
            return;
        }

        if ($plainText) {
            echo "\n" . esc_html__('License Keys:', 'wc-licensed-product') . "\n";
            foreach ($licenses as $license) {
                echo '  - ' . esc_html($license->getLicenseKey());
                echo ' (' . esc_html($license->getDomain()) . ')' . "\n";
            }
        } else {
            ?>
            <div style="margin-top: 10px; padding: 10px; background-color: #f8f9fa; border-left: 3px solid #7f54b3;">
                <strong><?php esc_html_e('License Keys:', 'wc-licensed-product'); ?></strong>
                <?php foreach ($licenses as $license) : ?>
                    <div style="margin-top: 5px; padding: 5px; background: #fff;">
                        <code style="font-family: monospace;">
                            <?php echo esc_html($license->getLicenseKey()); ?>
                        </code>
                        <span style="color: #666; margin-left: 10px;">
                            <?php echo esc_html($license->getDomain()); ?>
                        </span>
                    </div>
                <?php endforeach; ?>
            </div>
            <?php
        }
    }

    /**
     * Get all licenses for an order grouped by product
     *
     * @return array Array of products with their licenses
     */
    private function getLicensesForOrder(\WC_Order $order): array
    {
        $products = [];

        foreach ($order->get_items() as $item) {
            $product = $item->get_product();
            if ($product && $product->is_type('licensed')) {
                $licenses = $this->licenseManager->getLicensesByOrderAndProduct($order->get_id(), $product->get_id());
                if (!empty($licenses)) {
                    $products[] = [
                        'product_name' => $product->get_name(),
                        'licenses' => $licenses,
                    ];
                }
            }
        }

        return $products;
    }

    /**
     * Render license info in HTML format
     */
    private function renderHtmlLicenseInfo(array $products, \WC_Order $order): void
    {
        ?>
        <div style="margin: 20px 0; padding: 20px; background-color: #f8f9fa; border: 1px solid #e5e5e5; border-radius: 4px;">
            <h2 style="margin-top: 0; color: #333;"><?php esc_html_e('Your License Keys', 'wc-licensed-product'); ?></h2>

            <?php foreach ($products as $product) : ?>
                <div style="margin-bottom: 20px;">
                    <h3 style="margin: 0 0 10px 0; font-size: 1.1em; color: #333;">
                        <?php echo esc_html($product['product_name']); ?>
                        <span style="font-weight: normal; color: #666; font-size: 0.9em;">
                            (<?php
                            printf(
                                esc_html(_n('%d license', '%d licenses', count($product['licenses']), 'wc-licensed-product')),
                                count($product['licenses'])
                            );
                            ?>)
                        </span>
                    </h3>

                    <table style="width: 100%; border-collapse: collapse; background: #fff;">
                        <thead>
                            <tr>
                                <th style="text-align: left; padding: 8px 10px; border-bottom: 2px solid #ddd; font-size: 0.9em;"><?php esc_html_e('License Key', 'wc-licensed-product'); ?></th>
                                <th style="text-align: left; padding: 8px 10px; border-bottom: 2px solid #ddd; font-size: 0.9em;"><?php esc_html_e('Domain', 'wc-licensed-product'); ?></th>
                                <th style="text-align: left; padding: 8px 10px; border-bottom: 2px solid #ddd; font-size: 0.9em;"><?php esc_html_e('Expires', 'wc-licensed-product'); ?></th>
                            </tr>
                        </thead>
                        <tbody>
                            <?php foreach ($product['licenses'] as $license) : ?>
                                <tr>
                                    <td style="padding: 8px 10px; border-bottom: 1px solid #eee;">
                                        <code style="background: #f5f5f5; padding: 3px 6px; font-family: monospace; font-size: 0.9em;">
                                            <?php echo esc_html($license->getLicenseKey()); ?>
                                        </code>
                                    </td>
                                    <td style="padding: 8px 10px; border-bottom: 1px solid #eee;">
                                        <?php echo esc_html($license->getDomain()); ?>
                                    </td>
                                    <td style="padding: 8px 10px; border-bottom: 1px solid #eee;">
                                        <?php
                                        $expiresAt = $license->getExpiresAt();
                                        echo $expiresAt
                                            ? esc_html($expiresAt->format(get_option('date_format')))
                                            : esc_html__('Never', 'wc-licensed-product');
                                        ?>
                                    </td>
                                </tr>
                            <?php endforeach; ?>
                        </tbody>
                    </table>
                </div>
            <?php endforeach; ?>

            <p style="margin-top: 15px; margin-bottom: 0; font-size: 0.9em; color: #666;">
                <?php esc_html_e('You can also view your licenses in your account under "Licenses".', 'wc-licensed-product'); ?>
            </p>
        </div>
        <?php
    }

    /**
     * Render license info in plain text format
     */
    private function renderPlainTextLicenseInfo(array $products, \WC_Order $order): void
    {
        echo "\n\n";
        echo "==========================================================\n";
        echo esc_html__('YOUR LICENSE KEYS', 'wc-licensed-product') . "\n";
        echo "==========================================================\n\n";

        foreach ($products as $product) {
            echo esc_html($product['product_name']);
            echo ' (' . count($product['licenses']) . ' ' .
                _n('license', 'licenses', count($product['licenses']), 'wc-licensed-product') . ')';
            echo "\n";
            echo "-----------------------------------------------------------\n";

            foreach ($product['licenses'] as $license) {
                echo esc_html__('License Key:', 'wc-licensed-product') . ' ';
                echo esc_html($license->getLicenseKey()) . "\n";
                echo esc_html__('Domain:', 'wc-licensed-product') . ' ';
                echo esc_html($license->getDomain()) . "\n";
                echo esc_html__('Expires:', 'wc-licensed-product') . ' ';

                $expiresAt = $license->getExpiresAt();
                echo $expiresAt
                    ? esc_html($expiresAt->format(get_option('date_format')))
                    : esc_html__('Never', 'wc-licensed-product');
                echo "\n\n";
            }
        }

        echo esc_html__('You can also view your licenses in your account under "Licenses".', 'wc-licensed-product') . "\n";
        echo "==========================================================\n\n";
    }
}
