<?php

namespace GriffinForms\Admin\Html\Pages;

class Diagnostics extends \GriffinForms\Admin\Html\Pages\Format
{
    protected $package_state_resolver;
    protected $package_state_store;
    protected $log;

    protected function setPackageStateResolver()
    {
        $this->package_state_resolver = \GriffinForms\Includes\Packages\PackageStateResolver::getInstance();
    }

    protected function setPackageStateStore()
    {
        $this->package_state_store = \GriffinForms\Includes\Packages\PackageStateStore::getInstance();
    }

    public function html()
    {
        $state = $this->package_state_resolver->getState();
        $packages = is_array($state['packages'] ?? null) ? $state['packages'] : [];
        $lifecycle_state = $this->package_state_store->getLifecycleState();
        $recent_logs = $this->log->getByCategories($this->getDiagnosticsCategories(), 8);
        $recent_license_logs = $this->log->getByCategories($this->getLicenseCategories(), 5);
        $recent_update_logs = $this->log->getByCategories($this->getUpdateCategories(), 5);

        echo '<div class="wrap gf-package-diagnostics-wrap">';
        $this->pageHeading(__('Package Diagnostics', 'griffinforms-form-builder'), __('Internal support and QA snapshot for package architecture state.', 'griffinforms-form-builder'));

        echo '<div class="card" style="max-width:1180px;">';
        echo '<div class="card-body">';
        echo '<p class="mb-4 text-muted">' . esc_html__('This internal page summarizes the current GriffinForms package state, lifecycle facts, blockers, and recent package-related events without requiring direct database inspection.', 'griffinforms-form-builder') . '</p>';
        echo '<p class="mb-4"><strong>' . esc_html__('Resolved At:', 'griffinforms-form-builder') . '</strong> ' . esc_html($this->formatDateTimeValue((string) ($state['resolved_at'] ?? ''))) . '</p>';

        $this->packageSummaryHtml($packages);
        $this->compatibilityHtml($packages);
        $this->licenseHtml($packages);
        $this->updateHtml($packages);
        $this->recentLicenseEventsHtml($recent_license_logs);
        $this->recentUpdateEventsHtml($recent_update_logs);
        $this->lifecycleHtml($lifecycle_state, $packages);
        $this->blockersHtml($packages);
        $this->recentEventsHtml($recent_logs);

        echo '</div>';
        echo '</div>';
        echo '</div>';
    }

    protected function packageSummaryHtml(array $packages)
    {
        echo '<h2 class="mb-3">' . esc_html__('Package Summary', 'griffinforms-form-builder') . '</h2>';
        echo '<table class="widefat striped mb-4">';
        echo '<thead><tr>';
        echo '<th>' . esc_html__('Package', 'griffinforms-form-builder') . '</th>';
        echo '<th>' . esc_html__('Version', 'griffinforms-form-builder') . '</th>';
        echo '<th>' . esc_html__('Present', 'griffinforms-form-builder') . '</th>';
        echo '<th>' . esc_html__('Active', 'griffinforms-form-builder') . '</th>';
        echo '<th>' . esc_html__('Approval', 'griffinforms-form-builder') . '</th>';
        echo '<th>' . esc_html__('Compatibility', 'griffinforms-form-builder') . '</th>';
        echo '<th>' . esc_html__('Entitlement', 'griffinforms-form-builder') . '</th>';
        echo '<th>' . esc_html__('Integrity', 'griffinforms-form-builder') . '</th>';
        echo '<th>' . esc_html__('Update', 'griffinforms-form-builder') . '</th>';
        echo '</tr></thead><tbody>';

        foreach ($packages as $package_id => $package_state) {
            echo '<tr>';
            echo '<td><strong>' . esc_html((string) ($package_state['package_label_internal'] ?? $package_id)) . '</strong><br><code>' . esc_html((string) ($package_state['package_id'] ?? $package_id)) . '</code></td>';
            echo '<td>' . esc_html($this->formatValue((string) ($package_state['package_version'] ?? ''))) . '</td>';
            echo '<td>' . esc_html(!empty($package_state['is_present']) ? __('Yes', 'griffinforms-form-builder') : __('No', 'griffinforms-form-builder')) . '</td>';
            echo '<td>' . esc_html(!empty($package_state['is_active']) ? __('Yes', 'griffinforms-form-builder') : __('No', 'griffinforms-form-builder')) . '</td>';
            echo '<td>' . esc_html($this->formatStateLabel((string) ($package_state['approval_status'] ?? 'unknown'))) . '</td>';
            echo '<td>' . esc_html($this->formatStateLabel((string) ($package_state['compatibility_state'] ?? 'unknown'))) . '</td>';
            echo '<td>' . esc_html($this->formatStateLabel((string) ($package_state['entitlement_state'] ?? 'unknown'))) . '</td>';
            echo '<td>' . esc_html($this->formatStateLabel((string) ($package_state['integrity_state'] ?? 'unknown'))) . '</td>';
            echo '<td>' . esc_html($this->formatStateLabel((string) ($package_state['update_state'] ?? 'unknown'))) . '</td>';
            echo '</tr>';
        }

        echo '</tbody></table>';
    }

    protected function compatibilityHtml(array $packages)
    {
        echo '<h2 class="mb-3">' . esc_html__('Compatibility and Dependency', 'griffinforms-form-builder') . '</h2>';
        echo '<table class="widefat striped mb-4"><tbody>';

        foreach ($packages as $package_id => $package_state) {
            $package_label = (string) ($package_state['package_label_internal'] ?? $package_id);
            $message = sprintf(
                /* translators: 1: package label, 2: compatibility state, 3: recommended action */
                __('%1$s is currently %2$s. Recommended action: %3$s.', 'griffinforms-form-builder'),
                $package_label,
                $this->formatStateLabel((string) ($package_state['compatibility_state'] ?? 'unknown')),
                $this->formatStateLabel((string) ($package_state['recommended_user_action'] ?? 'none'))
            );

            $this->tableRowHtml(
                $package_label,
                $message . ' ' . $this->renderInlineCodeValue(__('Blocking reason', 'griffinforms-form-builder'), (string) ($package_state['blocking_reason_key'] ?? 'none'))
            );
        }

        echo '</tbody></table>';
    }

    protected function licenseHtml(array $packages)
    {
        $pro_state = is_array($packages['pro'] ?? null) ? $packages['pro'] : [];

        echo '<h2 class="mb-3">' . esc_html__('License and Entitlement', 'griffinforms-form-builder') . '</h2>';
        echo '<table class="widefat striped mb-4"><tbody>';
        $this->tableRowHtml(__('Current license state', 'griffinforms-form-builder'), $this->formatStateLabel((string) ($pro_state['entitlement_state'] ?? 'not_installed')));
        $this->tableRowHtml(__('Verification state', 'griffinforms-form-builder'), $this->formatStateLabel((string) ($pro_state['verification_state'] ?? 'not_recorded')));
        $this->tableRowHtml(__('License key present', 'griffinforms-form-builder'), !empty($pro_state['license_key_present']) ? __('Yes', 'griffinforms-form-builder') : __('No', 'griffinforms-form-builder'));
        $this->tableRowHtml(__('Warning layer', 'griffinforms-form-builder'), $this->formatValue((string) ($pro_state['warning_layer_key'] ?? 'none')));
        $this->tableRowHtml(__('Recommended action', 'griffinforms-form-builder'), $this->formatValue((string) ($pro_state['recommended_user_action'] ?? 'none')));
        $this->tableRowHtml(__('Last verified', 'griffinforms-form-builder'), $this->formatDateTimeValue((string) ($pro_state['last_verified_at'] ?? '')));
        $this->tableRowHtml(__('Last successful verification', 'griffinforms-form-builder'), $this->formatDateTimeValue((string) ($pro_state['last_successful_verification_at'] ?? '')));
        $this->tableRowHtml(__('Last failed verification', 'griffinforms-form-builder'), $this->formatDateTimeValue((string) ($pro_state['last_failed_verification_at'] ?? '')));
        $this->tableRowHtml(__('Next retry', 'griffinforms-form-builder'), $this->formatDateTimeValue((string) ($pro_state['next_retry_at'] ?? '')));
        $this->tableRowHtml(__('Grace started', 'griffinforms-form-builder'), $this->formatDateTimeValue((string) ($pro_state['grace_started_at'] ?? '')));
        $this->tableRowHtml(__('Grace expires', 'griffinforms-form-builder'), $this->formatDateTimeValue((string) ($pro_state['grace_expires_at'] ?? '')));
        $this->tableRowHtml(__('License expires', 'griffinforms-form-builder'), $this->formatDateTimeValue((string) ($pro_state['license_expires_at'] ?? '')));
        $this->tableRowHtml(__('Verification failures', 'griffinforms-form-builder'), (string) max(0, absint($pro_state['verification_failure_count'] ?? 0)));
        echo '</tbody></table>';
    }

    protected function lifecycleHtml(array $lifecycle_state, array $packages)
    {
        echo '<h2 class="mb-3">' . esc_html__('Lifecycle History', 'griffinforms-form-builder') . '</h2>';
        echo '<table class="widefat striped mb-4">';
        echo '<thead><tr>';
        echo '<th>' . esc_html__('Package', 'griffinforms-form-builder') . '</th>';
        echo '<th>' . esc_html__('First Installed', 'griffinforms-form-builder') . '</th>';
        echo '<th>' . esc_html__('Last Activated', 'griffinforms-form-builder') . '</th>';
        echo '<th>' . esc_html__('Last Deactivated', 'griffinforms-form-builder') . '</th>';
        echo '<th>' . esc_html__('Last Deleted', 'griffinforms-form-builder') . '</th>';
        echo '</tr></thead><tbody>';

        foreach ($packages as $package_id => $package_state) {
            $package_lifecycle = is_array($lifecycle_state[$package_id] ?? null) ? $lifecycle_state[$package_id] : [];
            echo '<tr>';
            echo '<td><strong>' . esc_html((string) ($package_state['package_label_internal'] ?? $package_id)) . '</strong><br><code>' . esc_html($package_id) . '</code></td>';
            echo '<td>' . $this->formatLifecycleEventHtml($package_lifecycle, 'first_installed_at', 'first_installed_user_id') . '</td>';
            echo '<td>' . $this->formatLifecycleEventHtml($package_lifecycle, 'last_activated_at', 'last_activated_user_id') . '</td>';
            echo '<td>' . $this->formatLifecycleEventHtml($package_lifecycle, 'last_deactivated_at', 'last_deactivated_user_id') . '</td>';
            echo '<td>' . $this->formatLifecycleEventHtml($package_lifecycle, 'last_deleted_at', 'last_deleted_user_id') . '</td>';
            echo '</tr>';
        }

        echo '</tbody></table>';
    }

    protected function updateHtml(array $packages)
    {
        $pro_state = is_array($packages['pro'] ?? null) ? $packages['pro'] : [];
        $update_record = $this->getPackageUpdateRecord((string) ($pro_state['package_bootstrap_file'] ?? ''));

        echo '<h2 class="mb-3">' . esc_html__('Update and Distribution', 'griffinforms-form-builder') . '</h2>';
        echo '<table class="widefat striped mb-4"><tbody>';
        $this->tableRowHtml(__('Normalized update state', 'griffinforms-form-builder'), $this->formatStateLabel((string) ($pro_state['update_state'] ?? 'unknown')));
        $this->tableRowHtml(__('Package bootstrap', 'griffinforms-form-builder'), $this->formatValue((string) ($pro_state['package_bootstrap_file'] ?? '')));
        $this->tableRowHtml(__('Native WP update entry', 'griffinforms-form-builder'), !empty($update_record) ? __('Present', 'griffinforms-form-builder') : __('Not present', 'griffinforms-form-builder'));

        if (!empty($update_record)) {
            $this->tableRowHtml(__('Available version', 'griffinforms-form-builder'), $this->formatValue((string) ($update_record['new_version'] ?? '')));
            $this->tableRowHtml(__('Details URL', 'griffinforms-form-builder'), $this->formatUrlValue((string) ($update_record['url'] ?? '')));
            $this->tableRowHtml(__('Package URL', 'griffinforms-form-builder'), $this->formatUrlValue((string) ($update_record['package'] ?? '')));
            $this->tableRowHtml(__('Shell status', 'griffinforms-form-builder'), __('The Pro update shell is currently advertising a WordPress-native update record for this package.', 'griffinforms-form-builder'));
        } else {
            $message = __('No WordPress-native update record is currently present for the Pro package.', 'griffinforms-form-builder');

            if (($pro_state['update_state'] ?? '') === 'gated_by_entitlement') {
                $message .= ' ' . __('Current update visibility is gated by entitlement state.', 'griffinforms-form-builder');
            } elseif (($pro_state['update_state'] ?? '') === 'up_to_date') {
                $message .= ' ' . __('This is consistent with an up-to-date Pro shell state.', 'griffinforms-form-builder');
            }

            $this->tableRowHtml(__('Shell status', 'griffinforms-form-builder'), $message);
        }

        echo '</tbody></table>';
    }

    protected function recentLicenseEventsHtml(array $recent_logs)
    {
        echo '<h2 class="mb-3">' . esc_html__('Recent License Events', 'griffinforms-form-builder') . '</h2>';

        if (empty($recent_logs)) {
            echo '<p class="text-muted mb-4">' . esc_html__('No recent license-state, verification, grace, or activation events have been recorded yet.', 'griffinforms-form-builder') . '</p>';
            return;
        }

        $this->eventTableHtml($recent_logs, 'mb-4');
    }

    protected function recentUpdateEventsHtml(array $recent_logs)
    {
        echo '<h2 class="mb-3">' . esc_html__('Recent Update Events', 'griffinforms-form-builder') . '</h2>';

        if (empty($recent_logs)) {
            echo '<p class="text-muted mb-4">' . esc_html__('No recent package update events have been recorded yet.', 'griffinforms-form-builder') . '</p>';
            return;
        }

        $this->eventTableHtml($recent_logs, 'mb-4');
    }

    protected function blockersHtml(array $packages)
    {
        echo '<h2 class="mb-3">' . esc_html__('Current Blockers', 'griffinforms-form-builder') . '</h2>';
        echo '<table class="widefat striped mb-4"><tbody>';

        $rows = $this->buildBlockerRows($packages);
        if (empty($rows)) {
            $this->tableRowHtml(__('Current status', 'griffinforms-form-builder'), __('No high-priority package blockers are active right now.', 'griffinforms-form-builder'));
        } else {
            foreach ($rows as $row) {
                $this->tableRowHtml($row['label'], $row['message']);
            }
        }

        echo '</tbody></table>';
    }

    protected function recentEventsHtml(array $recent_logs)
    {
        echo '<h2 class="mb-3">' . esc_html__('Recent Package Events', 'griffinforms-form-builder') . '</h2>';

        if (empty($recent_logs)) {
            echo '<p class="text-muted mb-0">' . esc_html__('No package-related logs have been recorded yet.', 'griffinforms-form-builder') . '</p>';
            return;
        }

        $this->eventTableHtml($recent_logs, 'mb-2');
        echo '<p class="text-muted mb-0">' . esc_html__('This feed is intentionally short. Use the main Logs screen for deeper event history.', 'griffinforms-form-builder') . '</p>';
    }

    protected function buildBlockerRows(array $packages): array
    {
        $rows = [];

        foreach ($packages as $package_id => $package_state) {
            $warning_layer_key = (string) ($package_state['warning_layer_key'] ?? '');
            $blocking_reason_key = (string) ($package_state['blocking_reason_key'] ?? '');
            $recommended_action = (string) ($package_state['recommended_user_action'] ?? '');

            if ($warning_layer_key === '' && $blocking_reason_key === '') {
                continue;
            }

            $rows[] = [
                'label' => (string) ($package_state['package_label_internal'] ?? $package_id),
                'message' => sprintf(
                    /* translators: 1: warning layer key, 2: blocking reason key, 3: recommended action */
                    __('Warning layer: %1$s. Blocking reason: %2$s. Next action: %3$s.', 'griffinforms-form-builder'),
                    $this->formatValue($warning_layer_key !== '' ? $warning_layer_key : 'none'),
                    $this->formatValue($blocking_reason_key !== '' ? $blocking_reason_key : 'none'),
                    $this->formatValue($recommended_action !== '' ? $recommended_action : 'none')
                ),
            ];
        }

        return $rows;
    }

    protected function getDiagnosticsCategories(): array
    {
        return [
            'package_lifecycle',
            'package_compatibility',
            'package_approval',
            'package_integrity',
            'package_provider',
            'license_state',
            'license_verification',
            'license_grace',
            'license_activation',
            'package_update',
            'workflow_dependency',
            'package_diagnostics',
        ];
    }

    protected function getLicenseCategories(): array
    {
        return [
            'license_state',
            'license_verification',
            'license_grace',
            'license_activation',
        ];
    }

    protected function getUpdateCategories(): array
    {
        return [
            'package_update',
        ];
    }

    protected function getPackageUpdateRecord(string $bootstrap_file): array
    {
        $bootstrap_file = trim($bootstrap_file);
        if ($bootstrap_file === '') {
            return [];
        }

        $transient = get_site_transient('update_plugins');
        if (!is_object($transient) || !isset($transient->response) || !is_array($transient->response)) {
            return [];
        }

        $record = $transient->response[$bootstrap_file] ?? null;
        if (!is_object($record) && !is_array($record)) {
            return [];
        }

        $record = (array) $record;

        return [
            'slug' => sanitize_text_field((string) ($record['slug'] ?? '')),
            'plugin' => sanitize_text_field((string) ($record['plugin'] ?? '')),
            'new_version' => sanitize_text_field((string) ($record['new_version'] ?? '')),
            'package' => esc_url_raw((string) ($record['package'] ?? '')),
            'url' => esc_url_raw((string) ($record['url'] ?? '')),
        ];
    }

    protected function tableRowHtml(string $label, string $value)
    {
        echo '<tr>';
        echo '<th scope="row" style="width:240px;">' . esc_html($label) . '</th>';
        echo '<td>' . wp_kses_post($value) . '</td>';
        echo '</tr>';
    }

    protected function formatStateLabel(string $value): string
    {
        return ucwords(str_replace(['_', '-'], ' ', $this->formatValue($value)));
    }

    protected function formatValue(string $value): string
    {
        $value = trim($value);
        return $value !== '' ? $value : __('Not recorded', 'griffinforms-form-builder');
    }

    protected function formatDateTimeValue(string $value): string
    {
        $value = trim($value);
        if ($value === '') {
            return __('Not recorded', 'griffinforms-form-builder');
        }

        $timestamp = strtotime($value);
        if ($timestamp === false) {
            return $value;
        }

        return wp_date(
            trim(get_option('date_format') . ' ' . get_option('time_format')),
            $timestamp
        );
    }

    protected function formatUrlValue(string $value): string
    {
        $value = trim($value);
        if ($value === '') {
            return __('Not recorded', 'griffinforms-form-builder');
        }

        return sprintf(
            '<a href="%1$s" target="_blank" rel="noopener noreferrer">%2$s</a>',
            esc_url($value),
            esc_html($value)
        );
    }

    protected function formatLifecycleEventHtml(array $lifecycle_state, string $time_key, string $user_key): string
    {
        $timestamp = trim((string) ($lifecycle_state[$time_key] ?? ''));
        $user_id = absint($lifecycle_state[$user_key] ?? 0);

        if ($timestamp === '') {
            return esc_html__('Never recorded', 'griffinforms-form-builder');
        }

        $value = esc_html($this->formatDateTimeValue($timestamp));
        if ($user_id > 0) {
            $user = get_userdata($user_id);
            $user_label = $user instanceof \WP_User ? $user->user_login : sprintf(__('User %d', 'griffinforms-form-builder'), $user_id);
            $value .= '<br><span class="text-muted">' . esc_html(sprintf(__('By %s', 'griffinforms-form-builder'), $user_label)) . '</span>';
        }

        return $value;
    }

    protected function renderInlineCodeValue(string $label, string $value): string
    {
        return sprintf(
            '%1$s: <code>%2$s</code>',
            esc_html($label),
            esc_html($this->formatValue($value))
        );
    }

    protected function eventTableHtml(array $recent_logs, string $table_class_suffix = 'mb-2')
    {
        echo '<table class="widefat striped ' . esc_attr($table_class_suffix) . '">';
        echo '<thead><tr>';
        echo '<th>' . esc_html__('When', 'griffinforms-form-builder') . '</th>';
        echo '<th>' . esc_html__('Type', 'griffinforms-form-builder') . '</th>';
        echo '<th>' . esc_html__('Category', 'griffinforms-form-builder') . '</th>';
        echo '<th>' . esc_html__('Context', 'griffinforms-form-builder') . '</th>';
        echo '<th>' . esc_html__('Actor', 'griffinforms-form-builder') . '</th>';
        echo '<th>' . esc_html__('Message', 'griffinforms-form-builder') . '</th>';
        echo '</tr></thead><tbody>';

        foreach ($recent_logs as $log_entry) {
            echo '<tr>';
            echo '<td>' . esc_html($this->formatDateTimeValue((string) ($log_entry->date_time ?? ''))) . '</td>';
            echo '<td>' . esc_html($this->formatValue((string) ($log_entry->log_type ?? ''))) . '</td>';
            echo '<td>' . esc_html($this->log->normalizeCategoryPublic((string) ($log_entry->category ?? ''))) . '</td>';
            echo '<td>' . $this->formatLogContextHtml($log_entry) . '</td>';
            echo '<td>' . $this->formatLogActorHtml($log_entry) . '</td>';
            echo '<td>' . esc_html($this->formatValue((string) ($log_entry->message ?? ''))) . '</td>';
            echo '</tr>';
        }

        echo '</tbody></table>';
    }

    protected function formatLogContextHtml($log_entry): string
    {
        $item_type = trim((string) ($log_entry->item_type ?? ''));
        $item_id = absint($log_entry->item_id ?? 0);

        if ($item_type === '' && $item_id < 1) {
            return esc_html__('General', 'griffinforms-form-builder');
        }

        $parts = [];

        if ($item_type !== '') {
            $parts[] = esc_html($item_type);
        }

        if ($item_id > 0) {
            $parts[] = '<code>#' . esc_html((string) $item_id) . '</code>';
        }

        return implode('<br>', $parts);
    }

    protected function formatLogActorHtml($log_entry): string
    {
        $user_id = absint($log_entry->user_id ?? 0);

        if ($user_id < 1) {
            return esc_html__('System', 'griffinforms-form-builder');
        }

        $user = get_userdata($user_id);
        if (!$user instanceof \WP_User) {
            return esc_html(sprintf(__('User %d', 'griffinforms-form-builder'), $user_id));
        }

        $parts = [
            esc_html($user->user_login),
            '<code>#' . esc_html((string) $user_id) . '</code>',
        ];

        return implode('<br>', $parts);
    }
}
