<?php
/**
 * Frontend Account Controller
 *
 * @package Jeremias\WcLicensedProduct\Frontend
 */

declare(strict_types=1);

namespace Jeremias\WcLicensedProduct\Frontend;

use Jeremias\WcLicensedProduct\License\LicenseManager;
use Jeremias\WcLicensedProduct\Product\VersionManager;
use Twig\Environment;

/**
 * Handles customer account pages for viewing licenses
 */
final class AccountController
{
    private Environment $twig;
    private LicenseManager $licenseManager;
    private VersionManager $versionManager;
    private DownloadController $downloadController;

    public function __construct(
        Environment $twig,
        LicenseManager $licenseManager,
        VersionManager $versionManager,
        DownloadController $downloadController
    ) {
        $this->twig = $twig;
        $this->licenseManager = $licenseManager;
        $this->versionManager = $versionManager;
        $this->downloadController = $downloadController;
        $this->registerHooks();
    }

    /**
     * Register WordPress hooks
     */
    private function registerHooks(): void
    {
        // Add licenses endpoint
        add_action('init', [$this, 'addLicensesEndpoint']);

        // Register endpoint query var with WooCommerce
        add_filter('woocommerce_get_query_vars', [$this, 'addLicensesQueryVar']);

        // Add licenses menu item
        add_filter('woocommerce_account_menu_items', [$this, 'addLicensesMenuItem']);

        // Add licenses endpoint content
        add_action('woocommerce_account_licenses_endpoint', [$this, 'displayLicensesContent']);

        // Enqueue frontend styles and scripts
        add_action('wp_enqueue_scripts', [$this, 'enqueueAssets']);

        // AJAX handler for license transfer request
        add_action('wp_ajax_wclp_customer_transfer_license', [$this, 'handleTransferRequest']);
    }

    /**
     * Add licenses endpoint for My Account
     */
    public function addLicensesEndpoint(): void
    {
        add_rewrite_endpoint('licenses', EP_ROOT | EP_PAGES);
    }

    /**
     * Register licenses query var with WooCommerce
     */
    public function addLicensesQueryVar(array $vars): array
    {
        $vars['licenses'] = 'licenses';
        return $vars;
    }

    /**
     * Add licenses menu item to My Account navigation
     */
    public function addLicensesMenuItem(array $items): array
    {
        // Insert licenses after orders
        $newItems = [];
        foreach ($items as $key => $value) {
            $newItems[$key] = $value;
            if ($key === 'orders') {
                $newItems['licenses'] = __('Licenses', 'wc-licensed-product');
            }
        }

        return $newItems;
    }

    /**
     * Display licenses content in My Account
     */
    public function displayLicensesContent(): void
    {
        $customerId = get_current_user_id();
        if (!$customerId) {
            echo '<p>' . esc_html__('Please log in to view your licenses.', 'wc-licensed-product') . '</p>';
            return;
        }

        $licenses = $this->licenseManager->getLicensesByCustomer($customerId);

        // Enrich licenses with product data and downloads
        $enrichedLicenses = [];
        foreach ($licenses as $license) {
            $product = wc_get_product($license->getProductId());
            $order = wc_get_order($license->getOrderId());

            // Get available downloads for this license
            $downloads = [];
            if ($license->getStatus() === 'active') {
                $versions = $this->versionManager->getVersionsByProduct($license->getProductId());
                foreach ($versions as $version) {
                    if ($version->isActive() && ($version->getAttachmentId() || $version->getDownloadUrl())) {
                        $downloads[] = [
                            'version' => $version->getVersion(),
                            'version_id' => $version->getId(),
                            'filename' => $version->getDownloadFilename(),
                            'download_url' => $this->downloadController->generateDownloadUrl(
                                $license->getId(),
                                $version->getId()
                            ),
                            'release_notes' => $version->getReleaseNotes(),
                            'released_at' => $version->getReleasedAt()->format(get_option('date_format')),
                            'file_hash' => $version->getFileHash(),
                        ];
                    }
                }
            }

            $enrichedLicenses[] = [
                'license' => $license,
                'product_name' => $product ? $product->get_name() : __('Unknown Product', 'wc-licensed-product'),
                'product_url' => $product ? $product->get_permalink() : '',
                'order_number' => $order ? $order->get_order_number() : '',
                'order_url' => $order ? $order->get_view_order_url() : '',
                'downloads' => $downloads,
            ];
        }

        try {
            echo $this->twig->render('frontend/licenses.html.twig', [
                'licenses' => $enrichedLicenses,
                'has_licenses' => !empty($enrichedLicenses),
            ]);
        } catch (\Exception $e) {
            // Fallback to PHP template if Twig fails
            $this->displayLicensesFallback($enrichedLicenses);
        }
    }

    /**
     * Fallback display method if Twig is unavailable
     */
    private function displayLicensesFallback(array $enrichedLicenses): void
    {
        if (empty($enrichedLicenses)) {
            echo '<p>' . esc_html__('You have no licenses yet.', 'wc-licensed-product') . '</p>';
            return;
        }

        ?>
        <div class="woocommerce-licenses">
            <?php foreach ($enrichedLicenses as $item): ?>
                <div class="license-card">
                    <div class="license-header">
                        <h3>
                            <?php if ($item['product_url']): ?>
                                <a href="<?php echo esc_url($item['product_url']); ?>">
                                    <?php echo esc_html($item['product_name']); ?>
                                </a>
                            <?php else: ?>
                                <?php echo esc_html($item['product_name']); ?>
                            <?php endif; ?>
                        </h3>
                        <span class="license-status license-status-<?php echo esc_attr($item['license']->getStatus()); ?>">
                            <?php echo esc_html(ucfirst($item['license']->getStatus())); ?>
                        </span>
                    </div>

                    <div class="license-details">
                        <div class="license-key-row">
                            <label><?php esc_html_e('License Key:', 'wc-licensed-product'); ?></label>
                            <code class="license-key" data-license-key="<?php echo esc_attr($item['license']->getLicenseKey()); ?>">
                                <?php echo esc_html($item['license']->getLicenseKey()); ?>
                            </code>
                            <button type="button" class="copy-license-btn" data-license-key="<?php echo esc_attr($item['license']->getLicenseKey()); ?>" title="<?php esc_attr_e('Copy to clipboard', 'wc-licensed-product'); ?>">
                                <span class="dashicons dashicons-clipboard"></span>
                            </button>
                        </div>

                        <div class="license-info-row">
                            <span class="license-domain-display" data-license-id="<?php echo esc_attr($item['license']->getId()); ?>">
                                <strong><?php esc_html_e('Domain:', 'wc-licensed-product'); ?></strong>
                                <span class="domain-value"><?php echo esc_html($item['license']->getDomain()); ?></span>
                                <?php if (in_array($item['license']->getStatus(), ['active', 'inactive'], true)): ?>
                                    <button type="button" class="wclp-transfer-btn"
                                            data-license-id="<?php echo esc_attr($item['license']->getId()); ?>"
                                            data-current-domain="<?php echo esc_attr($item['license']->getDomain()); ?>"
                                            title="<?php esc_attr_e('Transfer to new domain', 'wc-licensed-product'); ?>">
                                        <span class="dashicons dashicons-randomize"></span>
                                        <?php esc_html_e('Transfer', 'wc-licensed-product'); ?>
                                    </button>
                                <?php endif; ?>
                            </span>
                            <span><strong><?php esc_html_e('Expires:', 'wc-licensed-product'); ?></strong>
                                <?php
                                $expiresAt = $item['license']->getExpiresAt();
                                echo $expiresAt
                                    ? esc_html($expiresAt->format(get_option('date_format')))
                                    : esc_html__('Never', 'wc-licensed-product');
                                ?>
                            </span>
                        </div>
                    </div>

                    <?php if (!empty($item['downloads'])): ?>
                        <div class="license-downloads">
                            <h4><?php esc_html_e('Available Downloads', 'wc-licensed-product'); ?></h4>
                            <ul class="download-list">
                                <?php foreach ($item['downloads'] as $download): ?>
                                    <li>
                                        <a href="<?php echo esc_url($download['download_url']); ?>" class="download-link">
                                            <span class="dashicons dashicons-download"></span>
                                            <?php echo esc_html($download['filename'] ?: sprintf(__('Version %s', 'wc-licensed-product'), $download['version'])); ?>
                                        </a>
                                        <span class="download-version">v<?php echo esc_html($download['version']); ?></span>
                                        <span class="download-date"><?php echo esc_html($download['released_at']); ?></span>
                                    </li>
                                <?php endforeach; ?>
                            </ul>
                        </div>
                    <?php endif; ?>
                </div>
            <?php endforeach; ?>
        </div>

        <!-- Transfer Modal -->
        <div id="wclp-transfer-modal" class="wclp-modal" style="display:none;">
            <div class="wclp-modal-overlay"></div>
            <div class="wclp-modal-content">
                <button type="button" class="wclp-modal-close" aria-label="<?php esc_attr_e('Close', 'wc-licensed-product'); ?>">&times;</button>
                <h3><?php esc_html_e('Transfer License to New Domain', 'wc-licensed-product'); ?></h3>
                <form id="wclp-transfer-form">
                    <input type="hidden" name="license_id" id="transfer-license-id" value="">

                    <div class="wclp-form-row">
                        <label><?php esc_html_e('Current Domain', 'wc-licensed-product'); ?></label>
                        <p class="wclp-current-domain"><code id="transfer-current-domain"></code></p>
                    </div>

                    <div class="wclp-form-row">
                        <label for="transfer-new-domain"><?php esc_html_e('New Domain', 'wc-licensed-product'); ?></label>
                        <input type="text" name="new_domain" id="transfer-new-domain"
                               placeholder="example.com" required
                               pattern="[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)+">
                        <p class="wclp-field-description"><?php esc_html_e('Enter the new domain without http:// or www.', 'wc-licensed-product'); ?></p>
                    </div>

                    <div class="wclp-form-row wclp-form-actions">
                        <button type="submit" class="button wclp-btn-primary" id="wclp-transfer-submit">
                            <?php esc_html_e('Transfer License', 'wc-licensed-product'); ?>
                        </button>
                        <button type="button" class="button wclp-modal-cancel"><?php esc_html_e('Cancel', 'wc-licensed-product'); ?></button>
                    </div>

                    <div id="wclp-transfer-message" class="wclp-message" style="display:none;"></div>
                </form>
            </div>
        </div>
        <?php
    }

    /**
     * Enqueue frontend styles and scripts
     */
    public function enqueueAssets(): void
    {
        if (!is_account_page()) {
            return;
        }

        wp_enqueue_style(
            'wc-licensed-product-frontend',
            WC_LICENSED_PRODUCT_PLUGIN_URL . 'assets/css/frontend.css',
            [],
            WC_LICENSED_PRODUCT_VERSION
        );

        wp_enqueue_script(
            'wc-licensed-product-frontend',
            WC_LICENSED_PRODUCT_PLUGIN_URL . 'assets/js/frontend.js',
            ['jquery'],
            WC_LICENSED_PRODUCT_VERSION,
            true
        );

        wp_localize_script('wc-licensed-product-frontend', 'wcLicensedProduct', [
            'ajaxUrl' => admin_url('admin-ajax.php'),
            'transferNonce' => wp_create_nonce('wclp_customer_transfer'),
            'strings' => [
                'copied' => __('Copied!', 'wc-licensed-product'),
                'copyFailed' => __('Copy failed', 'wc-licensed-product'),
                'transferSuccess' => __('License transferred successfully!', 'wc-licensed-product'),
                'transferError' => __('Transfer failed. Please try again.', 'wc-licensed-product'),
                'transferConfirm' => __('Are you sure you want to transfer this license to a new domain? This action cannot be undone.', 'wc-licensed-product'),
                'invalidDomain' => __('Please enter a valid domain.', 'wc-licensed-product'),
            ],
        ]);
    }

    /**
     * Handle AJAX license transfer request from customer
     */
    public function handleTransferRequest(): void
    {
        // Verify nonce
        if (!check_ajax_referer('wclp_customer_transfer', 'nonce', false)) {
            wp_send_json_error(['message' => __('Security check failed.', 'wc-licensed-product')], 403);
        }

        // Verify user is logged in
        $customerId = get_current_user_id();
        if (!$customerId) {
            wp_send_json_error(['message' => __('Please log in to transfer a license.', 'wc-licensed-product')], 401);
        }

        // Get and validate license ID
        $licenseId = isset($_POST['license_id']) ? absint($_POST['license_id']) : 0;
        if (!$licenseId) {
            wp_send_json_error(['message' => __('Invalid license.', 'wc-licensed-product')], 400);
        }

        // Get and validate new domain
        $newDomain = isset($_POST['new_domain']) ? sanitize_text_field($_POST['new_domain']) : '';
        $newDomain = $this->normalizeDomain($newDomain);

        if (empty($newDomain)) {
            wp_send_json_error(['message' => __('Please enter a valid domain.', 'wc-licensed-product')], 400);
        }

        // Verify the license belongs to this customer
        $license = $this->licenseManager->getLicenseById($licenseId);
        if (!$license) {
            wp_send_json_error(['message' => __('License not found.', 'wc-licensed-product')], 404);
        }

        if ($license->getCustomerId() !== $customerId) {
            wp_send_json_error(['message' => __('You do not have permission to transfer this license.', 'wc-licensed-product')], 403);
        }

        // Check if license is in a transferable state
        if ($license->getStatus() === 'revoked') {
            wp_send_json_error(['message' => __('Revoked licenses cannot be transferred.', 'wc-licensed-product')], 400);
        }

        if ($license->getStatus() === 'expired') {
            wp_send_json_error(['message' => __('Expired licenses cannot be transferred.', 'wc-licensed-product')], 400);
        }

        // Check if domain is the same
        if ($license->getDomain() === $newDomain) {
            wp_send_json_error(['message' => __('The new domain is the same as the current domain.', 'wc-licensed-product')], 400);
        }

        // Perform the transfer
        $result = $this->licenseManager->transferLicense($licenseId, $newDomain);

        if ($result) {
            wp_send_json_success([
                'message' => __('License transferred successfully!', 'wc-licensed-product'),
                'new_domain' => $newDomain,
            ]);
        } else {
            wp_send_json_error(['message' => __('Failed to transfer license. Please try again.', 'wc-licensed-product')], 500);
        }
    }

    /**
     * Normalize domain for comparison and storage
     */
    private function normalizeDomain(string $domain): string
    {
        // Remove protocol if present
        $domain = preg_replace('#^https?://#i', '', $domain);

        // Remove www prefix
        $domain = preg_replace('#^www\.#i', '', $domain);

        // Remove trailing slash
        $domain = rtrim($domain, '/');

        // Remove path if present
        $domain = explode('/', $domain)[0];

        // Convert to lowercase
        $domain = strtolower($domain);

        // Basic validation - must contain at least one dot and valid characters
        if (!preg_match('/^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$/', $domain)) {
            return '';
        }

        return $domain;
    }
}
