<?php
/**
 * Forge Suite Dashboard — setup checklist and read-only diagnostics.
 */
if (!defined('ABSPATH')) exit;

if (!class_exists('Forge_Suite_Dashboard_Health')) {

class Forge_Suite_Dashboard_Health {
    const AJAX_ACTION = 'forge_suite_health_check';
    const REPAIR_ACTION = 'forge_suite_health_repair';
    const NONCE       = 'forge_suite_health_check';
    const HISTORY_OPTION = 'forge_suite_health_history';
    const HISTORY_LIMIT = 10;

    const PLUGINS = [
        'rankforge'   => ['name' => 'Rank Forge',   'class' => 'RANKFORGE_Core',   'option' => 'rankforge_license_data',   'admin' => 'rankforge'],
        'langforge'  => ['name' => 'Lang Forge',  'class' => 'LANGFORGE_Core',         'option' => 'langforge_license_data',         'admin' => 'langforge-settings'],
        'formforge'  => ['name' => 'Form Forge',  'class' => 'FORMFORGE_Core',  'option' => 'formforge_license_data',  'admin' => 'formforge'],
        'fieldforge' => ['name' => 'Field Forge', 'class' => 'FIELDFORGE_Core', 'option' => 'fieldforge_license_data', 'admin' => 'fieldforge'],
    ];

    public static function register() {
        add_action('wp_ajax_' . self::AJAX_ACTION, [__CLASS__, 'ajax_health_check']);
        add_action('wp_ajax_' . self::REPAIR_ACTION, [__CLASS__, 'ajax_health_repair']);
    }

    public static function render() {
        if (!current_user_can('manage_options')) return;
        $steps = self::setup_steps();
        ?>
        <div class="forge-suite-section forge-suite-health">
            <div class="forge-suite-health-head">
                <div>
                    <h2 class="forge-suite-section-title">
                        <span class="dashicons dashicons-admin-generic" style="color:#7C5CFC;"></span>
                        <?php esc_html_e('Setup & Health', 'rankforge'); ?>
                    </h2>
                    <p class="forge-suite-health-lede"><?php esc_html_e('Check activation, credits, API reachability, and migration readiness before you start deeper plugin work.', 'rankforge'); ?></p>
                </div>
                <div class="forge-suite-health-actions">
                    <button type="button" id="forge-suite-health-run" class="button button-primary">
                        <span class="dashicons dashicons-update" aria-hidden="true"></span>
                        <?php esc_html_e('Run diagnostics', 'rankforge'); ?>
                    </button>
                    <button type="button" class="button button-secondary forge-suite-health-repair" data-repair="support_package">
                        <span class="dashicons dashicons-media-code" aria-hidden="true"></span>
                        <?php esc_html_e('Support package', 'rankforge'); ?>
                    </button>
                </div>
            </div>

            <div class="forge-suite-health-steps">
                <?php foreach ($steps as $step): ?>
                    <div class="forge-suite-health-step is-<?php echo esc_attr($step['state']); ?>">
                        <span class="forge-suite-health-step-icon dashicons <?php echo esc_attr($step['icon']); ?>"></span>
                        <div>
                            <strong><?php echo esc_html($step['label']); ?></strong>
                            <span><?php echo esc_html($step['detail']); ?></span>
                        </div>
                    </div>
                <?php endforeach; ?>
            </div>

            <?php $recommendations = self::setup_recommendations(); ?>
            <?php if (!empty($recommendations)): ?>
                <div class="forge-suite-health-recommendations" id="forge-suite-health-recommendations">
                    <?php foreach ($recommendations as $rec): ?>
                        <div class="forge-suite-health-recommendation is-<?php echo esc_attr($rec['priority']); ?>">
                            <span class="dashicons <?php echo esc_attr($rec['icon']); ?>" aria-hidden="true"></span>
                            <div>
                                <strong><?php echo esc_html($rec['title']); ?></strong>
                                <span><?php echo esc_html($rec['message']); ?></span>
                            </div>
                            <?php if (!empty($rec['url'])): ?>
                                <a class="button button-secondary" href="<?php echo esc_url($rec['url']); ?>"><?php echo esc_html($rec['label']); ?></a>
                            <?php elseif (!empty($rec['repair'])): ?>
                                <button type="button" class="button button-secondary forge-suite-health-repair" data-repair="<?php echo esc_attr($rec['repair']); ?>"><?php echo esc_html($rec['label']); ?></button>
                            <?php endif; ?>
                        </div>
                    <?php endforeach; ?>
                </div>
            <?php endif; ?>

            <div id="forge-suite-health-results" class="forge-suite-health-results" aria-live="polite"></div>
            <div id="forge-suite-health-support" class="forge-suite-health-support" hidden></div>
            <?php self::render_history(); ?>
        </div>
        <?php
    }

    public static function ajax_health_check() {
        check_ajax_referer(self::NONCE, 'nonce');
        if (!current_user_can('manage_options')) {
            wp_send_json_error(['message' => __('Forbidden', 'rankforge')], 403);
        }

        $items = self::diagnostic_items();
        self::record_history($items);

        wp_send_json_success([
            'items' => $items,
            'recommendations' => self::recommendations_from_items($items),
            'history' => self::recent_history(),
        ]);
    }

    public static function ajax_health_repair() {
        check_ajax_referer(self::NONCE, 'nonce');
        if (!current_user_can('manage_options')) {
            wp_send_json_error(['message' => __('Forbidden', 'rankforge')], 403);
        }

        $repair = sanitize_key($_POST['repair'] ?? '');
        if ($repair === 'flush_permalinks') {
            flush_rewrite_rules(false);
            wp_send_json_success([
                'message' => __('Permalink rewrite rules refreshed.', 'rankforge'),
                'items' => self::diagnostic_items(),
                'history' => self::recent_history(),
            ]);
        }

        if ($repair === 'refresh_credits') {
            $result = self::refresh_credit_balances();
            if (is_wp_error($result)) {
                wp_send_json_error(['message' => $result->get_error_message()], 400);
            }
            wp_send_json_success([
                'message' => $result['message'],
                'items' => self::diagnostic_items(),
                'history' => self::recent_history(),
            ]);
        }

        if ($repair === 'support_package') {
            wp_send_json_success([
                'message' => __('Support package generated. Copy it into your Avakode support message.', 'rankforge'),
                'package' => wp_json_encode(self::support_package(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES),
                'items' => self::diagnostic_items(),
                'history' => self::recent_history(),
            ]);
        }

        if ($repair === 'clear_history') {
            delete_option(self::HISTORY_OPTION);
            wp_send_json_success([
                'message' => __('Diagnostic history cleared.', 'rankforge'),
                'items' => self::diagnostic_items(),
                'history' => [],
            ]);
        }

        wp_send_json_error(['message' => __('Unknown health action.', 'rankforge')], 400);
    }

    private static function setup_steps() {
        $active_count  = self::active_plugin_count();
        $license_count = count(self::saved_license_keys());
        $credits_ready = $license_count > 0 && class_exists('Forge_Credits_Widget');
        $migration     = self::migration_sources();

        return [
            [
                'label'  => __('Activate Forge plugins', 'rankforge'),
                'detail' => sprintf(
                    /* translators: %d: active plugin count */
                    __('%d of 4 plugins active', 'rankforge'),
                    $active_count
                ),
                'state'  => $active_count >= 4 ? 'ok' : 'warn',
                'icon'   => $active_count >= 4 ? 'dashicons-yes-alt' : 'dashicons-warning',
            ],
            [
                'label'  => __('Connect to Avakode', 'rankforge'),
                'detail' => $license_count > 0
                    ? sprintf(
                        /* translators: %d: connected license count */
                        __('%d plugin license records found', 'rankforge'),
                        $license_count
                    )
                    : __('No local license record found yet', 'rankforge'),
                'state'  => $license_count > 0 ? 'ok' : 'warn',
                'icon'   => $license_count > 0 ? 'dashicons-yes-alt' : 'dashicons-admin-network',
            ],
            [
                'label'  => __('Verify credits', 'rankforge'),
                'detail' => $credits_ready
                    ? __('Credits widget can read the connected license.', 'rankforge')
                    : __('Connect a license before checking AI credits.', 'rankforge'),
                'state'  => $credits_ready ? 'ok' : 'warn',
                'icon'   => $credits_ready ? 'dashicons-yes-alt' : 'dashicons-money-alt',
            ],
            [
                'label'  => __('Review migrations and integrations', 'rankforge'),
                'detail' => !empty($migration)
                    ? sprintf(
                        /* translators: %d: detected migration source count */
                        __('%d migration source plugins detected', 'rankforge'),
                        count($migration)
                    )
                    : __('No known migration source plugins detected.', 'rankforge'),
                'state'  => !empty($migration) ? 'warn' : 'ok',
                'icon'   => !empty($migration) ? 'dashicons-migrate' : 'dashicons-yes-alt',
            ],
        ];
    }

    private static function setup_recommendations() {
        $active_count = self::active_plugin_count();
        $license_count = count(self::saved_license_keys());
        $migration = self::migration_sources();

        if ($license_count === 0) {
            return [[
                'priority' => 'high',
                'icon' => 'dashicons-admin-network',
                'title' => __('Next best action: connect your Avakode account', 'rankforge'),
                'message' => __('Connect first so licenses, credits, and paid integrations can be checked against the right site.', 'rankforge'),
                'label' => __('Open Connect', 'rankforge'),
                'url' => admin_url('admin.php?page=forge-suite'),
            ]];
        }

        if ($active_count < 4) {
            return [[
                'priority' => 'medium',
                'icon' => 'dashicons-admin-plugins',
                'title' => __('Next best action: activate the remaining Forge plugins', 'rankforge'),
                'message' => __('The dashboard works best when all installed Forge plugins are active and can share license state.', 'rankforge'),
                'label' => __('Open plugins', 'rankforge'),
                'url' => admin_url('plugins.php'),
            ]];
        }

        if (!empty($migration)) {
            return [[
                'priority' => 'medium',
                'icon' => 'dashicons-migrate',
                'title' => __('Next best action: review migration sources', 'rankforge'),
                'message' => sprintf(
                    /* translators: %s: comma-separated migration source plugin names */
                    __('Detected %s. Run the matching Forge migration tool before disabling the source plugin.', 'rankforge'),
                    implode(', ', $migration)
                ),
                'label' => __('Run diagnostics', 'rankforge'),
                'repair' => '',
            ]];
        }

        return [[
            'priority' => 'low',
            'icon' => 'dashicons-yes-alt',
            'title' => __('Next best action: run a final health check', 'rankforge'),
            'message' => __('Everything local looks ready. Run diagnostics to verify the API, credits, and integration prerequisites.', 'rankforge'),
            'label' => __('Generate support package', 'rankforge'),
            'repair' => 'support_package',
        ]];
    }

    private static function diagnostic_items() {
        $items = [];

        $items[] = [
            'key'     => 'wordpress',
            'label'   => __('WordPress runtime', 'rankforge'),
            'status'  => 'ok',
            'message' => sprintf(
                /* translators: 1: WordPress version, 2: PHP version */
                __('WordPress %1$s, PHP %2$s', 'rankforge'),
                get_bloginfo('version'),
                PHP_VERSION
            ),
        ];

        $permalink = (string) get_option('permalink_structure', '');
        $items[] = [
            'key'     => 'permalinks',
            'label'   => __('Permalinks', 'rankforge'),
            'status'  => $permalink !== '' ? 'ok' : 'warn',
            'message' => $permalink !== ''
                ? __('Pretty permalinks are enabled.', 'rankforge')
                : __('Pretty permalinks are disabled; language and SEO routes may need plain-link fallbacks.', 'rankforge'),
            'action'  => $permalink !== '' ? null : [
                'type' => 'repair',
                'repair' => 'flush_permalinks',
                'label' => __('Refresh permalink rules', 'rankforge'),
            ],
        ];

        $active_count = self::active_plugin_count();
        $items[] = [
            'key'     => 'plugins',
            'label'   => __('Forge plugins', 'rankforge'),
            'status'  => $active_count >= 4 ? 'ok' : 'warn',
            'message' => sprintf(
                /* translators: %d: active plugin count */
                __('%d of 4 Forge plugins are active.', 'rankforge'),
                $active_count
            ),
            'action'  => $active_count >= 4 ? null : [
                'type' => 'link',
                'url' => admin_url('plugins.php'),
                'label' => __('Open plugins', 'rankforge'),
            ],
        ];

        $license_count = count(self::saved_license_keys());
        $items[] = [
            'key'     => 'license',
            'label'   => __('License connection', 'rankforge'),
            'status'  => $license_count > 0 ? 'ok' : 'warn',
            'message' => $license_count > 0
                ? sprintf(
                    /* translators: %d: connected license count */
                    __('%d local license records found.', 'rankforge'),
                    $license_count
                )
                : __('No local Avakode license records found. Use Connect to Avakode.', 'rankforge'),
            'action'  => $license_count > 0 ? null : [
                'type' => 'link',
                'url' => admin_url('admin.php?page=forge-suite'),
                'label' => __('Open Connect', 'rankforge'),
            ],
        ];

        $items[] = self::api_item();

        $items[] = [
            'key'     => 'credits',
            'label'   => __('Credits readiness', 'rankforge'),
            'status'  => $license_count > 0 && class_exists('Forge_Credits_Widget') ? 'ok' : 'warn',
            'message' => $license_count > 0 && class_exists('Forge_Credits_Widget')
                ? __('Credits widget is loaded and a license is available for balance refresh.', 'rankforge')
                : __('Credits need an active license before balance refresh or checkout can work.', 'rankforge'),
            'action'  => $license_count > 0 && class_exists('Forge_Credits_Widget') ? [
                'type' => 'repair',
                'repair' => 'refresh_credits',
                'label' => __('Refresh credits now', 'rankforge'),
            ] : null,
        ];

        $sources = self::migration_sources();
        $items[] = [
            'key'     => 'migrations',
            'label'   => __('Migrations and integrations', 'rankforge'),
            'status'  => !empty($sources) ? 'warn' : 'ok',
            'message' => !empty($sources)
                ? sprintf(
                    /* translators: %s: comma-separated plugin names */
                    __('Detected migration/integration sources: %s.', 'rankforge'),
                    implode(', ', $sources)
                )
                : __('No known migration source plugins are active on this site.', 'rankforge'),
            'action'  => !empty($sources) ? [
                'type' => 'repair',
                'repair' => 'support_package',
                'label' => __('Generate support package', 'rankforge'),
            ] : null,
        ];

        return $items;
    }

    private static function api_item() {
        $api_base = self::api_base();
        $response = wp_remote_get($api_base . '/health', [
            'timeout' => 6,
            'headers' => ['Accept' => 'application/json'],
        ]);

        if (is_wp_error($response)) {
            return [
                'key'     => 'api',
                'label'   => __('Avakode API', 'rankforge'),
                'status'  => 'error',
                'message' => $response->get_error_message(),
                'action'  => [
                    'type' => 'repair',
                    'repair' => 'support_package',
                    'label' => __('Generate support package', 'rankforge'),
                ],
            ];
        }

        $code = (int) wp_remote_retrieve_response_code($response);
        return [
            'key'     => 'api',
            'label'   => __('Avakode API', 'rankforge'),
            'status'  => ($code >= 200 && $code < 300) ? 'ok' : 'warn',
            'message' => sprintf(
                /* translators: 1: API base URL, 2: HTTP status code */
                __('%1$s returned HTTP %2$d.', 'rankforge'),
                $api_base,
                $code
            ),
            'action'  => ($code >= 200 && $code < 300) ? null : [
                'type' => 'repair',
                'repair' => 'support_package',
                'label' => __('Generate support package', 'rankforge'),
            ],
        ];
    }

    private static function active_plugin_count() {
        $count = 0;
        foreach (self::PLUGINS as $info) {
            if (class_exists($info['class'])) $count++;
        }
        return $count;
    }

    private static function saved_license_keys() {
        $keys = [];
        foreach (self::PLUGINS as $slug => $info) {
            $data = get_option($info['option'], []);
            if (is_array($data) && !empty($data['key'])) {
                $keys[$slug] = (string) $data['key'];
            }
        }
        return $keys;
    }

    private static function recommendations_from_items(array $items) {
        $recommendations = [];
        foreach ($items as $item) {
            if (($item['status'] ?? 'ok') === 'ok') {
                continue;
            }
            $recommendations[] = [
                'key' => $item['key'] ?? '',
                'title' => sprintf(
                    /* translators: %s: diagnostic label */
                    __('Review %s', 'rankforge'),
                    $item['label'] ?? __('diagnostic item', 'rankforge')
                ),
                'message' => $item['message'] ?? '',
                'action' => $item['action'] ?? null,
            ];
        }

        if (empty($recommendations)) {
            $recommendations[] = [
                'key' => 'support_package',
                'title' => __('All checks passed', 'rankforge'),
                'message' => __('Generate a support package if you want a copy of the current environment snapshot.', 'rankforge'),
                'action' => [
                    'type' => 'repair',
                    'repair' => 'support_package',
                    'label' => __('Generate support package', 'rankforge'),
                ],
            ];
        }
        return array_slice($recommendations, 0, 4);
    }

    private static function record_history(array $items) {
        $counts = ['ok' => 0, 'warn' => 0, 'error' => 0];
        foreach ($items as $item) {
            $status = $item['status'] ?? 'warn';
            if (!isset($counts[$status])) $status = 'warn';
            $counts[$status]++;
        }

        $history = self::recent_history();
        array_unshift($history, [
            'time' => current_time('mysql'),
            'ok' => $counts['ok'],
            'warn' => $counts['warn'],
            'error' => $counts['error'],
        ]);
        $history = array_slice($history, 0, self::HISTORY_LIMIT);
        update_option(self::HISTORY_OPTION, $history, false);
    }

    private static function recent_history() {
        $history = get_option(self::HISTORY_OPTION, []);
        return is_array($history) ? array_values($history) : [];
    }

    private static function render_history() {
        $history = self::recent_history();
        ?>
        <div class="forge-suite-health-history" id="forge-suite-health-history">
            <div class="forge-suite-health-history-head">
                <strong><?php esc_html_e('Diagnostic history', 'rankforge'); ?></strong>
                <button type="button" class="button button-link-delete forge-suite-health-repair" data-repair="clear_history"><?php esc_html_e('Clear history', 'rankforge'); ?></button>
            </div>
            <div class="forge-suite-health-history-list">
                <?php if (empty($history)): ?>
                    <span class="forge-suite-health-history-empty"><?php esc_html_e('No diagnostic runs yet.', 'rankforge'); ?></span>
                <?php else: ?>
                    <?php foreach (array_slice($history, 0, 5) as $entry): ?>
                        <div class="forge-suite-health-history-row">
                            <span><?php echo esc_html($entry['time'] ?? ''); ?></span>
                            <span><?php echo esc_html(sprintf(
                                /* translators: 1: ok count, 2: warning count, 3: error count */
                                __('%1$d ok, %2$d warnings, %3$d errors', 'rankforge'),
                                (int) ($entry['ok'] ?? 0),
                                (int) ($entry['warn'] ?? 0),
                                (int) ($entry['error'] ?? 0)
                            )); ?></span>
                        </div>
                    <?php endforeach; ?>
                <?php endif; ?>
            </div>
        </div>
        <?php
    }

    private static function refresh_credit_balances() {
        if (!class_exists('Forge_Credits_Widget') || !method_exists('Forge_Credits_Widget', 'fetch_balance')) {
            return new WP_Error('credits_unavailable', __('Credits widget is not loaded.', 'rankforge'));
        }

        $licenses = self::saved_license_keys();
        if (empty($licenses)) {
            return new WP_Error('no_license', __('Connect a license before refreshing credits.', 'rankforge'));
        }

        $refreshed = 0;
        $errors = [];
        // Forge_Credits_Widget moved to *-pro repos in Phase 3.5. If no Pro
        // plugin is active, the class is undefined and credits refresh is a
        // no-op (Free has no AI calls to track credits for). Guard explicitly
        // so the AJAX handler doesn't fatal on Free-only installs.
        if (!class_exists('Forge_Credits_Widget')) {
            return ['refreshed' => 0, 'errors' => [], 'message' => __('Credits refresh requires a Pro plugin to be active.', 'rankforge')];
        }
        foreach (array_keys($licenses) as $product) {
            $data = Forge_Credits_Widget::fetch_balance($product, true);
            if (is_wp_error($data)) {
                $errors[] = self::PLUGINS[$product]['name'] . ': ' . $data->get_error_message();
                continue;
            }
            $refreshed++;
        }

        if ($refreshed === 0 && !empty($errors)) {
            return new WP_Error('credits_refresh_failed', implode('; ', $errors));
        }

        return [
            'message' => sprintf(
                /* translators: %d: refreshed product count */
                __('Credit balance refreshed for %d plugin(s).', 'rankforge'),
                $refreshed
            ),
        ];
    }

    private static function support_package() {
        $licenses = [];
        foreach (self::PLUGINS as $slug => $info) {
            $data = get_option($info['option'], []);
            $key = is_array($data) && !empty($data['key']) ? (string) $data['key'] : '';
            $licenses[$slug] = [
                'active' => class_exists($info['class']),
                'has_license' => $key !== '',
                'license' => $key !== '' ? substr($key, 0, 6) . '...' . substr($key, -4) : '',
                'has_site_token' => is_array($data) && !empty($data['site_token']),
                'connected_at' => is_array($data) ? ($data['connected_at'] ?? null) : null,
            ];
        }

        return [
            'generated_at' => current_time('mysql'),
            'site_url' => home_url('/'),
            'wordpress' => get_bloginfo('version'),
            'php' => PHP_VERSION,
            'permalink_structure' => (string) get_option('permalink_structure', ''),
            'api_base' => self::api_base(),
            'forge_plugins' => $licenses,
            'migration_sources' => self::migration_sources(),
            'recent_history' => array_slice(self::recent_history(), 0, 5),
        ];
    }

    private static function migration_sources() {
        if (!function_exists('is_plugin_active')) {
            require_once ABSPATH . 'wp-admin/includes/plugin.php';
        }

        $known = [
            'advanced-custom-fields/acf.php'                  => 'ACF',
            'advanced-custom-fields-pro/acf.php'              => 'ACF Pro',
            'sitepress-multilingual-cms/sitepress.php'        => 'WPML',
            'wordpress-seo/wp-seo.php'                        => 'Yoast SEO',
            'seo-by-rank-math/rank-math.php'                  => 'Rank Math',
            'all-in-one-seo-pack/all_in_one_seo_pack.php'     => 'AIOSEO',
            'woocommerce/woocommerce.php'                     => 'WooCommerce',
            'elementor/elementor.php'                         => 'Elementor',
        ];

        $found = [];
        foreach ($known as $file => $label) {
            if (is_plugin_active($file)) {
                $found[] = $label;
            }
        }
        return $found;
    }

    private static function api_base() {
        if (class_exists('Forge_Connect') && method_exists('Forge_Connect', 'api_base')) {
            return rtrim(Forge_Connect::api_base(), '/');
        }
        if (defined('FORGE_API_URL') && FORGE_API_URL) {
            return rtrim(FORGE_API_URL, '/');
        }
        return 'https://api.avakode.com';
    }
}

}
