<?php

namespace GriffinForms\Admin\App\Html\Modals\Integrations\Renders;

use GriffinForms\Includes\Integrations\Providers;
use GriffinForms\Admin\Html\Elements\LogsTimeline;

/**
 * InfoView Renderer
 *
 * Renders detailed information view for a single integration.
 * Features:
 * - Two-column layout: main content (left) and sidebar (right)
 * - Header section with icon, name, and description
 * - Status badges showing configuration state
 * - Documentation and support links
 * - Action buttons (Configure, Test Connection, Disable)
 * - Sidebar with requirements and resources
 * - Back button to return to grid view
 *
 * @since 1.0.0
 */
class InfoView extends Format
{
    /**
     * Cached count of notices for the Messages accordion badge.
     *
     * @var int
     */
    private $messages_count = 0;

    /**
     * Render integration info view
     *
     * @param array $data Integration data with keys:
     *                      - 'integration_id' (string): The integration ID
     *                      - 'provider' (array): Full provider metadata
     *                      - 'status' (array): Current integration status
     * @return string HTML info view
     */
    public function render($data = []): string
    {
        $provider = $data['provider'] ?? null;

        if (!$provider) {
            return $this->renderError(__('Integration not found', 'griffinforms-form-builder'));
        }

        $status = $data['status'] ?? [];
        $integration_id = $data['integration_id'] ?? $provider['id'];

        $html = '';
        $html .= $this->renderHeader($provider, $integration_id);
        $html .= '<div class="gf-integration-info-container">' . PHP_EOL;

        // Main content area (left)
        $html .= '<div class="gf-integration-info-main">' . PHP_EOL;
        $html .= $this->renderHeaderSection($provider, $status);
        $html .= $this->renderNotesSection($provider);
        $html .= $this->renderStatusSection($provider, $status);
        $html .= $this->renderLinksSection($provider);
        $html .= $this->renderActionsSection($provider, $status, $integration_id);
        $html .= '</div>' . PHP_EOL;

        // Sidebar (right) - Bootstrap Accordion
        $html .= $this->renderAccordionSidebar($provider, $status, $integration_id);
        $html .= PHP_EOL;

        $html .= '</div>' . PHP_EOL;

        return '<div class="gf-integration-info-view">' . PHP_EOL . $html . '</div>' . PHP_EOL;
    }

    /**
     * Render header with back button and title
     *
     * @param array $provider Provider metadata
     * @param string $integration_id Integration ID
     * @return string Header HTML
     */
    private function renderHeader(array $provider, string $integration_id): string
    {
        $html = '<div class="gf-integration-info-header">' . PHP_EOL;

        // Back button
        $html .= sprintf(
            '<button class="gf-integration-info-back" %s>' . PHP_EOL,
            $this->dataAttr('action', 'back-to-grid')
        );
        $html .= '<span class="gf-integration-info-back-icon">&larr;</span>' . PHP_EOL;
        $html .= '<span class="gf-integration-info-back-text">' . esc_html__('Back', 'griffinforms-form-builder') . '</span>' . PHP_EOL;
        $html .= '</button>' . PHP_EOL;

        // Title area (intentionally empty - styling purposes)
        $html .= '</div>' . PHP_EOL;

        return $html;
    }

    /**
     * Render main header section with icon, name, and description
     *
     * @param array $provider Provider metadata
     * @param array $status Integration status
     * @return string Section HTML
     */
    private function renderHeaderSection(array $provider, array $status): string
    {
        $html = '<div class="gf-integration-section gf-integration-section-header">' . PHP_EOL;

        // Icon on the left
        $html .= '<div class="gf-integration-info-icon">' . PHP_EOL;
        $html .= $this->renderIcon($provider) . PHP_EOL;
        $html .= '</div>' . PHP_EOL;

        // Content on the right: Name, description, category
        $html .= '<div class="gf-integration-info-content">' . PHP_EOL;

        // Name
        $html .= sprintf(
            '<h2 class="gf-integration-info-name">%s</h2>' . PHP_EOL,
            $this->escHtml($provider['name'])
        );

        // Description
        if (!empty($provider['description'])) {
            $html .= sprintf(
                '<p class="gf-integration-info-description">%s</p>' . PHP_EOL,
                $this->escHtml($provider['description'])
            );
        }

        $coming_soon = !empty($provider['coming_soon']);

        // Badges (category, scope, coming soon)
        if (!empty($provider['category']) || ($provider['scope']['is_global'] ?? false) || $coming_soon) {
            $html .= '<div class="gf-integration-header-badges">' . PHP_EOL;

            // Category badge
            if (!empty($provider['category'])) {
                $html .= sprintf(
                    '<span class="badge gf-integration-category-badge">%s</span>' . PHP_EOL,
                    $this->escHtml($provider['category'])
                );
            }

            // Scope badge
            $scope = $provider['scope'] ?? [];
            if ($scope['is_global'] ?? false) {
                $override_text = ($scope['allow_override'] ?? false) ? __('Global (Overridable)', 'griffinforms-form-builder') : __('Global', 'griffinforms-form-builder');
                $html .= '<span class="badge gf-integration-scope-badge">' . $this->escHtml($override_text) . '</span>' . PHP_EOL;
            } else {
                $html .= '<span class="badge gf-integration-scope-badge">' . $this->escHtml(__('Per-Form', 'griffinforms-form-builder')) . '</span>' . PHP_EOL;
            }

            if ($coming_soon) {
                $html .= sprintf(
                    '<span class="badge gf-integration-comingsoon-badge">%s</span>' . PHP_EOL,
                    $this->escHtml(__('Coming Soon', 'griffinforms-form-builder'))
                );
            }

            $html .= '</div>' . PHP_EOL;
        }

        $html .= '</div>' . PHP_EOL;
        $html .= '</div>' . PHP_EOL;

        return $html;
    }

    /**
     * Render optional custom notes defined by integration metadata
     *
     * @param array $provider Provider metadata
     * @return string Section HTML
     */
    private function renderNotesSection(array $provider): string
    {
        // Notes are now rendered in the Messages accordion to keep layout consistent.
        return '';
    }

    /**
     * Render status section with colored badges
     *
     * @param array $provider Provider metadata
     * @param array $status Integration status
     * @return string Section HTML
     */
    private function renderStatusSection(array $provider, array $status): string
    {
        $html = '<div class="gf-integration-section gf-integration-section-status">' . PHP_EOL;

        $html .= '<h3 class="gf-integration-section-title">' . esc_html__('Status', 'griffinforms-form-builder') . '</h3>' . PHP_EOL;

        $html .= '<div class="gf-integration-badges">' . PHP_EOL;

        // Configuration status badge
        $configured = $status['configured'] ?? $provider['configured'] ?? false;
        $active = $status['active'] ?? $provider['active'] ?? false;
        if (($provider['category_type'] ?? '') === 'payment' && $configured) {
            if (!$this->isPaymentGatewaySelected($provider['id'] ?? '')) {
                $active = false;
            }
        }

        if ($active) {
            $badge_class = 'badge bg-success gf-bg-success gf-text-success';
            $badge_text = __('Active', 'griffinforms-form-builder');
        } elseif ($configured) {
            $badge_class = 'badge bg-info gf-bg-info gf-text-info';
            $badge_text = __('Configured', 'griffinforms-form-builder');
        } else {
            $badge_class = 'badge bg-secondary gf-bg-secondary gf-text-secondary';
            $badge_text = __('Not Configured', 'griffinforms-form-builder');
        }

        $html .= sprintf(
            '<span class="%s">%s</span>' . PHP_EOL,
            $this->escAttr($badge_class),
            $this->escHtml($badge_text)
        );

        // Library status badge
        if ($provider['requires_lib'] ?? false) {
            $lib_installed = $provider['lib_installed'] ?? false;
            $lib_badge_class = $lib_installed ? 'badge bg-success gf-bg-success gf-text-success' : 'badge bg-secondary';
            $lib_badge_text = $lib_installed
                ? __('Library Installed', 'griffinforms-form-builder')
                : __('Library Required', 'griffinforms-form-builder');

            $html .= sprintf(
                '<span class="%s">%s</span>' . PHP_EOL,
                $this->escAttr($lib_badge_class),
                $this->escHtml($lib_badge_text)
            );
        }

        $html .= '</div>' . PHP_EOL;
        $html .= '</div>' . PHP_EOL;

        return $html;
    }

    /**
     * Render accordion sidebar with Requirements and Logs sections
     *
     * @param array $provider Provider metadata
     * @param string $integration_id Integration ID
     * @return string Accordion HTML
     */
    private function renderAccordionSidebar(array $provider, array $status, string $integration_id): string
    {
        $html = '<div class="gf-integration-info-sidebar">' . PHP_EOL;
        $html .= '<div class="accordion gf-integration-accordion" id="gf-integration-accordion-' . esc_attr($integration_id) . '">' . PHP_EOL;

        // Requirements accordion item
        $html .= $this->renderAccordionItem(
            $integration_id,
            'requirements',
            __('Requirements', 'griffinforms-form-builder'),
            $this->renderRequirementsSection($provider),
            true // First item open
        );

        // Messages accordion item
        $notices = $this->collectNotices($provider, $status);
        $notice_count = count($notices);
        $messages_title = esc_html__('Messages', 'griffinforms-form-builder');
        $html .= $this->renderAccordionItem(
            $integration_id,
            'messages',
            $messages_title,
            $this->renderMessagesSection($notices),
            false
        );

        // Logs accordion item
        $html .= $this->renderAccordionItem(
            $integration_id,
            'logs',
            __('Recent Logs', 'griffinforms-form-builder'),
            $this->renderLogsSection($integration_id),
            false // Second item closed
        );

        $html .= '</div>' . PHP_EOL;
        $html .= '</div>' . PHP_EOL;

        return $html;
    }

    /**
     * Render a single accordion item
     *
     * @param string $integration_id Integration ID
     * @param string $item_id Item identifier (requirements, logs, etc.)
     * @param string $title Item title
     * @param string $content Item content HTML
     * @param bool $is_open Whether this item should be open by default
     * @return string Accordion item HTML
     */
    private function renderAccordionItem(
        string $integration_id,
        string $item_id,
        string $title,
        string $content,
        bool $is_open = false
    ): string {
        $accordion_id = 'gf-integration-accordion-' . esc_attr($integration_id);
        $item_unique_id = $accordion_id . '-' . esc_attr($item_id);
        $badge = '';
        if ($item_id === 'messages') {
            $count = $this->messages_count ?? 0;
            if ($count > 0) {
                $badge = ' <span class="badge gf-bg-danger gf-text-danger ms-2">' . (int) $count . '</span>';
            }
        }

        $html = '<div class="accordion-item">' . PHP_EOL;

        // Header
        $html .= sprintf(
            '<h2 class="accordion-header"><button class="accordion-button%s" type="button" data-bs-toggle="collapse" data-bs-target="#%s" aria-expanded="%s" aria-controls="%s" data-item-id="%s">%s%s</button></h2>' . PHP_EOL,
            $is_open ? '' : ' collapsed',
            esc_attr($item_unique_id),
            $is_open ? 'true' : 'false',
            esc_attr($item_unique_id),
            esc_attr($item_id),
            esc_html($title),
            $badge
        );

        // Content
        $html .= sprintf(
            '<div id="%s" class="accordion-collapse collapse%s" data-bs-parent="#%s"><div class="accordion-body">%s</div></div>' . PHP_EOL,
            esc_attr($item_unique_id),
            $is_open ? ' show' : '',
            esc_attr($accordion_id),
            $content
        );

        $html .= '</div>' . PHP_EOL;

        return $html;
    }

    /**
     * Render requirements section (sidebar)
     *
     * @param array $provider Provider metadata
     * @return string Section HTML
     */
    private function renderRequirementsSection(array $provider): string
    {
        $requires = $provider['requires'] ?? [];

        if (empty($requires)) {
            return '<p class="text-muted">' . esc_html__('No specific requirements', 'griffinforms-form-builder') . '</p>';
        }

        $html = '<ul class="gf-integration-requirements-list-sidebar">' . PHP_EOL;

        // PHP version
        if (!empty($requires['php'])) {
            $html .= sprintf(
                '<li><strong>PHP:</strong> <span>%s</span></li>' . PHP_EOL,
                $this->escHtml($requires['php'])
            );
        }

        // Modules
        if (!empty($requires['modules']) && is_array($requires['modules'])) {
            $modules = implode(', ', $requires['modules']);
            $html .= sprintf(
                '<li><strong>Modules:</strong> <span>%s</span></li>' . PHP_EOL,
                $this->escHtml($modules)
            );
        }

        // Libraries
        if (!empty($requires['libs']) && is_array($requires['libs'])) {
            $libs = implode(', ', $requires['libs']);
            $html .= sprintf(
                '<li><strong>Libraries:</strong> <span>%s</span></li>' . PHP_EOL,
                $this->escHtml($libs)
            );
        }

        $html .= '</ul>' . PHP_EOL;

        return $html;
    }

    /**
     * Render logs section using shared timeline renderer.
     *
     * @param string $integration_id Integration ID
     * @return string
     */
    private function renderLogsSection(string $integration_id): string
    {
        $options = array(
            'keyword' => $integration_id,
            'limit' => 5,
            'empty_message' => __('No logs found for this integration', 'griffinforms-form-builder'),
        );

        $timeline = new LogsTimeline('', 0, $options);
        ob_start();
        $timeline->html();
        return ob_get_clean();
    }

    /**
     * Render documentation and support links section
     *
     * @param array $provider Provider metadata
     * @return string Section HTML
     */
    private function renderLinksSection(array $provider): string
    {
        $has_docs = !empty($provider['documentation']);
        $has_setup = !empty($provider['setup_guide']);
        $has_support = !empty($provider['support_url']);

        if (!$has_docs && !$has_setup && !$has_support) {
            return '';
        }

        $html = '<div class="gf-integration-section gf-integration-section-links">' . PHP_EOL;

        $html .= '<h3 class="gf-integration-section-title">' . esc_html__('Resources', 'griffinforms-form-builder') . '</h3>' . PHP_EOL;

        $html .= '<div class="gf-integration-links">' . PHP_EOL;

        if ($has_docs) {
            $html .= sprintf(
                '<a href="%s" target="_blank" rel="noopener" class="gf-integration-link">%s</a>' . PHP_EOL,
                $this->escUrl($provider['documentation']),
                $this->escHtml(__('Documentation', 'griffinforms-form-builder'))
            );
        }

        if ($has_setup) {
            $html .= sprintf(
                '<a href="%s" target="_blank" rel="noopener" class="gf-integration-link">%s</a>' . PHP_EOL,
                $this->escUrl($provider['setup_guide']),
                $this->escHtml(__('Setup Guide', 'griffinforms-form-builder'))
            );
        }

        if ($has_support) {
            $html .= sprintf(
                '<a href="%s" target="_blank" rel="noopener" class="gf-integration-link">%s</a>' . PHP_EOL,
                $this->escUrl($provider['support_url']),
                $this->escHtml(__('Support', 'griffinforms-form-builder'))
            );
        }

        $html .= '</div>' . PHP_EOL;
        $html .= '</div>' . PHP_EOL;

        return $html;
    }

    /**
     * Render action buttons section
     *
     * @param array $provider Provider metadata
     * @param array $status Integration status
     * @param string $integration_id Integration ID
     * @return string Section HTML
     */
    private function renderActionsSection(array $provider, array $status, string $integration_id): string
    {
        $html = '<div class="gf-integration-section gf-integration-section-actions">' . PHP_EOL;

        $html .= '<div class="gf-integration-actions">' . PHP_EOL;

        $configured       = $status['configured'] ?? $provider['configured'] ?? false;
        $active           = $status['active'] ?? $provider['active'] ?? false;
        $coming_soon      = !empty($provider['coming_soon']);
        $is_paid          = !empty($provider['is_paid']);
        $package_admitted = !empty($provider['package_admitted']);

        if ($coming_soon) {
            $notice_classes = $this->escAttr('gf-notice gf-notice-warning gf-integration-comingsoon-alert');
            $html .= sprintf(
                '<div class="%s">%s</div>' . PHP_EOL,
                $notice_classes,
                $this->escHtml(__('This integration is launching soon. Configuration and actions will unlock once it is available.', 'griffinforms-form-builder'))
            );

            if (!empty($provider['waitlist_url'])) {
                $html .= sprintf(
                    '<a href="%s" target="_blank" rel="noopener" class="gf-btn gf-btn-outline">%s</a>' . PHP_EOL,
                    $this->escUrl($provider['waitlist_url']),
                    $this->escHtml(__('Join Waitlist', 'griffinforms-form-builder'))
                );
            }

            $html .= '</div>' . PHP_EOL;
            $html .= '</div>' . PHP_EOL;

            return $html;
        }

        if ($is_paid && !$package_admitted) {
            $upsell_key = $provider['upsell_key'] ?? '';
            $upsell = \GriffinForms\Includes\Upsells\UpsellRegistry::getInstance();
            if ($upsell_key !== '' && $upsell->shouldRenderLockedShell($upsell_key)) {
                ob_start();
                $upsell->render($upsell_key, 'banner');
                $html .= ob_get_clean();
            }

            $html .= '</div>' . PHP_EOL;
            $html .= '</div>' . PHP_EOL;

            return $html;
        }

        // Check if library is required and missing
        $lib_required = $provider['requires_lib'] ?? false;
        $lib_installed = $provider['lib_installed'] ?? false;
        $lib_missing = $lib_required && !$lib_installed;

        // Configure button - disabled if library is required but missing
        $configure_attrs = $this->dataAttr('action', 'configure') . ' ' . $this->dataAttr('integration-id', $integration_id);
        if ($lib_missing) {
            $configure_attrs .= ' disabled';
            $configure_title = __('Library must be installed first', 'griffinforms-form-builder');
            $configure_attrs .= ' title="' . esc_attr($configure_title) . '"';
        }

        $html .= sprintf(
            '<button class="gf-btn gf-btn-primary gf-integration-btn-configure" %s>%s</button>' . PHP_EOL,
            $configure_attrs,
            $this->escHtml(__('Configure', 'griffinforms-form-builder'))
        );

        // Test connection button - only if configured
        if ($configured) {
            $html .= sprintf(
                '<button class="gf-btn gf-btn-light gf-integration-btn-test" %s>%s</button>' . PHP_EOL,
                $this->dataAttr('action', 'test-connection') . ' ' . $this->dataAttr('integration-id', $integration_id),
                $this->escHtml(__('Test Connection', 'griffinforms-form-builder'))
            );
        }

        // Form-specific settings button (when overrides are allowed)
        $allow_override = $provider['scope']['allow_override'] ?? false;
        $coming_soon = !empty($provider['coming_soon']);
        if ($allow_override && !$coming_soon) {
            $form_settings_attrs = $this->dataAttr('action', 'form-settings') . ' ' . $this->dataAttr('integration-id', $integration_id);
            if (!$configured) {
                $form_settings_attrs .= ' disabled title="' . esc_attr(__('Configure globally first to enable form-specific settings.', 'griffinforms-form-builder')) . '"';
            }

            $html .= sprintf(
                '<button class="gf-btn gf-btn-light gf-integration-btn-form-settings" %s>%s</button>' . PHP_EOL,
                $form_settings_attrs,
                $this->escHtml(__('Form Settings', 'griffinforms-form-builder'))
            );
        }

        // Disable button - only if configured or active
        if ($configured || $active) {
            $html .= sprintf(
                '<button class="gf-btn gf-btn-light gf-text-danger gf-integration-btn-disable" %s>%s</button>' . PHP_EOL,
                $this->dataAttr('action', 'disable') . ' ' . $this->dataAttr('integration-id', $integration_id),
                $this->escHtml(__('Disable', 'griffinforms-form-builder'))
            );
        }

        $html .= '</div>' . PHP_EOL;
        $html .= '</div>' . PHP_EOL;

        return $html;
    }

    /**
     * Collect notices for the Messages accordion.
     *
     * @param array $provider
     * @param array $status
     * @return array<int,array{type:string,message:string,link?:array{url:string,label:string}}>
     */
    private function collectNotices(array $provider, array $status): array
    {
        $notices = array();

        // General info notes (previously rendered in header)
        $notes = $provider['info_notes'] ?? array();
        if (!empty($notes)) {
            if (!is_array($notes)) {
                $notes = array($notes);
            }
            foreach ($notes as $note) {
                $note = trim((string) $note);
                if ($note === '') {
                    continue;
                }
                $notices[] = array(
                    'type'    => 'info',
                    'message' => $note,
                );
            }
        }

        // Payment gateway configured but not selected in Payments settings
        $configured = $status['configured'] ?? $provider['configured'] ?? false;
        if (($provider['category_type'] ?? '') === 'payment' && $configured && !$this->isPaymentGatewaySelected($provider['id'] ?? '')) {
            $notices[] = array(
                'type'    => 'info',
                'message' => __('Gateway is configured. To accept payments, choose it in Payments settings.', 'griffinforms-form-builder'),
                'link'    => array(
                    'url'   => admin_url('admin.php?page=griffinforms-settings-payments'),
                    'label' => __('Open Payments settings', 'griffinforms-form-builder'),
                ),
            );
        }

        // CAPTCHA configured but another provider is active in Antispam settings
        if (($provider['category_type'] ?? '') === 'captcha' && $configured) {
            $active_captcha = $this->getActiveCaptchaProviderId();
            $current_id     = $provider['id'] ?? '';
            if ($current_id && $active_captcha && $active_captcha !== $current_id) {
                $notices[] = array(
                    'type'    => 'info',
                    'message' => __('This CAPTCHA is configured but not selected as the Active CAPTCHA Provider in Antispam settings.', 'griffinforms-form-builder'),
                    'link'    => array(
                        'url'   => admin_url('admin.php?page=griffinforms-settings-antispam'),
                        'label' => __('Open Antispam settings', 'griffinforms-form-builder'),
                    ),
                );
            }
        }

        $notices = apply_filters('griffinforms_integration_info_notices', $notices, $provider, $status);

        // Store count for badge rendering
        $this->messages_count = count($notices);

        return is_array($notices) ? $notices : array();
    }

    /**
     * Render messages list for the accordion.
     *
     * @param array $notices
     * @return string
     */
    private function renderMessagesSection(array $notices): string
    {
        if (empty($notices)) {
            return '<p class="text-muted small mb-0">' . esc_html__('No messages for this integration.', 'griffinforms-form-builder') . '</p>';
        }

        $html = '<div class="gf-integration-messages">';
        $icon_url = plugins_url(
            'admin/images/icons/accordion-note.svg',
            dirname(__FILE__, 7) . '/griffinforms.php'
        );

        foreach ($notices as $notice) {
            $type = isset($notice['type']) ? strtolower((string) $notice['type']) : 'info';
            $message = isset($notice['message']) ? (string) $notice['message'] : '';
            if ($message === '') {
                continue;
            }

            $html .= '<div class="mb-3 small d-flex align-items-start gap-2">';
            $html .= '<span class="d-inline-flex align-items-center justify-content-center" style="width:16px;height:16px;flex-shrink:0;"><img src="' . esc_url($icon_url) . '" alt="" width="16" height="16" loading="lazy"></span>';
            $html .= '<span class="d-block" style="padding-left:2px;">' . esc_html($message);

            if (!empty($notice['link']['url']) && !empty($notice['link']['label'])) {
                $html .= ' <a class="gf-text-primary" href="' . esc_url($notice['link']['url']) . '" target="_blank" rel="noopener noreferrer">' . esc_html($notice['link']['label']) . '</a>';
            }

            $html .= '</span></div>';
        }
        $html .= '</div>';

        return $html;
    }

    /**
     * Check if a payment gateway is selected in Payments settings.
     *
     * @param string $provider_id
     * @return bool
     */
    private function isPaymentGatewaySelected(string $provider_id): bool
    {
        if ($provider_id === '') {
            return false;
        }

        $registry = \GriffinForms\Includes\Integrations\Categories\Payment::getInstance();
        if (!$registry) {
            return false;
        }

        return in_array($provider_id, $registry->getAllowedProviderIds(), true);
    }

    /**
     * Get active captcha provider ID from registry.
     */
    private function getActiveCaptchaProviderId(): ?string
    {
        $registry = \GriffinForms\Includes\Integrations\Categories\Captcha::getInstance();
        if (!$registry) {
            return null;
        }

        return $registry->getActiveProviderId();
    }
}
