<?php

namespace GriffinForms\Admin\Html\Pages;

class Onboarding extends \GriffinForms\Admin\Html\Pages\Format
{
    protected $feature_flags;
    protected $eligibility;
    protected $progress;
    protected $starter_catalog;
    protected $starter_generator;
    protected $placement_service;
    protected $user_state_repository;
    protected $current_state = [];
    protected $entry_source = 'manual';
    protected $current_step = 'welcome';
    protected $error_message = '';
    protected $preview_mode = false;
    protected $migration_notice_service;

    protected function setFeatureFlags()
    {
        $this->feature_flags = \GriffinForms\Includes\Onboarding\FeatureFlags::getInstance();
    }

    protected function setEligibility()
    {
        $this->eligibility = \GriffinForms\Includes\Onboarding\Eligibility::getInstance();
    }

    protected function setProgress()
    {
        $this->progress = \GriffinForms\Includes\Onboarding\Progress::getInstance();
    }

    protected function setStarterCatalog()
    {
        $this->starter_catalog = \GriffinForms\Includes\Onboarding\StarterCatalog::getInstance();
    }

    protected function setStarterGenerator()
    {
        $this->starter_generator = \GriffinForms\Includes\Onboarding\StarterGenerator::getInstance();
    }

    protected function setPlacementService()
    {
        $this->placement_service = \GriffinForms\Includes\Onboarding\PlacementService::getInstance();
    }

    protected function setUserStateRepository()
    {
        $this->user_state_repository = \GriffinForms\Includes\Onboarding\UserStateRepository::getInstance();
    }

    protected function setMigrationNoticeService()
    {
        $this->migration_notice_service = \GriffinForms\Includes\Migration\MigrationNotice::getInstance();
    }

    protected function setEntrySource()
    {
        $entry_source = isset($_GET['entry_source']) ? sanitize_key(wp_unslash($_GET['entry_source'])) : 'manual';
        $allowed_sources = ['activation_redirect', 'forms_empty_state', 'manual'];
        $this->entry_source = in_array($entry_source, $allowed_sources, true) ? $entry_source : 'manual';
        $this->preview_mode = !empty($_GET['gf_onboarding_preview']);
    }

    protected function setCurrentState()
    {
        $this->current_state = $this->user_state_repository->getState();
    }

    protected function navigateTo(string $url)
    {
        if (!headers_sent()) {
            wp_safe_redirect($url);
            exit;
        }

        $escaped_url = esc_url($url);
        $json_url = wp_json_encode($url);

        echo '<script>';
        echo 'window.location.href = ' . $json_url . ';';
        echo '</script>';
        echo '<noscript><meta http-equiv="refresh" content="0;url=' . $escaped_url . '"></noscript>';
        exit;
    }

    protected function processDismissAction()
    {
        $action = isset($_GET['gf_onboarding_action']) ? sanitize_key(wp_unslash($_GET['gf_onboarding_action'])) : '';
        if ($action !== 'dismiss') {
            return;
        }

        $nonce = isset($_GET['_wpnonce']) ? sanitize_text_field(wp_unslash($_GET['_wpnonce'])) : '';
        if (!wp_verify_nonce($nonce, 'griffinforms_onboarding_dismiss')) {
            return;
        }

        $this->progress->markDismissed();
        $this->navigateTo($this->feature_flags->getFormsPageUrl());
    }

    protected function maybeResetPreviewState()
    {
        if (!$this->preview_mode) {
            return;
        }

        $this->current_state = $this->user_state_repository->resetStateForCurrentVersion();
    }

    protected function ensureAccessible()
    {
        if (!$this->eligibility->canAccessOnboardingPage()) {
            $this->navigateTo($this->feature_flags->getFormsPageUrl());
        }
    }

    protected function markEntry()
    {
        $this->current_state = $this->progress->markEntry($this->entry_source);
    }

    protected function getDismissUrl(): string
    {
        return wp_nonce_url(
            $this->feature_flags->getOnboardingPageUrl([
                'entry_source' => $this->entry_source,
                'gf_onboarding_action' => 'dismiss',
            ]),
            'griffinforms_onboarding_dismiss'
        );
    }

    protected function getCreateFormUrl(): string
    {
        return $this->getStepUrl('goal', [
            'entry_source' => $this->entry_source,
        ]);
    }

    protected function getStepUrl(string $step_key, array $query_args = []): string
    {
        return $this->feature_flags->getOnboardingPageUrl(array_merge([
            'entry_source' => $this->entry_source,
            'step' => $step_key,
        ], $query_args));
    }

    protected function getBuilderUrl(int $form_id): string
    {
        return add_query_arg([
            'page' => 'griffinforms-app',
            'form_id' => $form_id,
            'gf_onboarding_created' => 1,
        ], admin_url('admin.php'));
    }

    protected function getDocumentationUrl(): string
    {
        return 'https://griffinforms.com/docs/';
    }

    protected function getMigrationPageUrl(array $query_args = []): string
    {
        return add_query_arg($query_args, admin_url('admin.php?page=griffinforms-migration'));
    }

    protected function getBrandLogoUrl(): string
    {
        return $this->config->getRootUrl() . 'admin/images/onboarding/griffinforms-logo.svg';
    }

    protected function canRenderImportEntry(): bool
    {
        if (!$this->feature_flags->isEnabled('import_entry')) {
            return false;
        }

        return !empty($this->getImportEntrySources());
    }

    /**
     * @return array<int, \GriffinForms\Includes\Migration\MigrationSourceInterface>
     */
    protected function getImportEntrySources(): array
    {
        return $this->migration_notice_service->getDetectedSources();
    }

    protected function getImportEntryUrl(): string
    {
        $query_args = [
            'gf_from' => 'onboarding',
        ];

        $sources = $this->getImportEntrySources();
        if (count($sources) === 1) {
            $query_args['source'] = $sources[0]->getSlug();
        }

        return $this->getMigrationPageUrl($query_args);
    }

    protected function getImportEntryLabels(): string
    {
        $labels = array_map(static function ($source): string {
            return $source->getLabel();
        }, $this->getImportEntrySources());

        $labels = array_values(array_filter(array_map('sanitize_text_field', $labels)));
        if (empty($labels)) {
            return '';
        }

        if (count($labels) === 1) {
            return $labels[0];
        }

        $last = array_pop($labels);
        return implode(', ', $labels) . ' and ' . $last;
    }

    protected function getSuggestedPageTitle(): string
    {
        $goal_key = (string) ($this->current_state['selected_goal'] ?? '');
        $goal = $this->starter_catalog->getGoal($goal_key);

        if ($goal && !empty($goal['page_title']) && is_string($goal['page_title'])) {
            return sanitize_text_field($goal['page_title']);
        }

        return __('Contact Us', 'griffinforms-form-builder');
    }

    protected function getPlacementResultLabel(array $placement_result): string
    {
        $title = trim((string) ($placement_result['title'] ?? ''));
        if ($title !== '') {
            return $title;
        }

        $post_type = (string) ($placement_result['post_type'] ?? '');
        $post_id = absint($placement_result['post_id'] ?? 0);

        if ($post_type === 'page' && $post_id > 0) {
            return sprintf(__('Untitled page (#%d)', 'griffinforms-form-builder'), $post_id);
        }

        if ($post_type === 'post' && $post_id > 0) {
            return sprintf(__('Untitled post (#%d)', 'griffinforms-form-builder'), $post_id);
        }

        if ($post_id > 0) {
            return sprintf(__('Content item #%d', 'griffinforms-form-builder'), $post_id);
        }

        return __('Created content', 'griffinforms-form-builder');
    }

    protected function getPublishContinueLabel(string $placement_action): string
    {
        $placement_action = sanitize_key($placement_action);

        if ($placement_action === 'create_form_only') {
            return $this->lang->getText('onboarding_publish_continue_unpublished');
        }

        return $this->lang->getText('onboarding_publish_continue');
    }

    protected function setCurrentStep()
    {
        $requested_step = isset($_GET['step']) ? sanitize_key(wp_unslash($_GET['step'])) : '';
        $fallback_step = $this->progress->resolveResumeStep($this->current_state);

        if ($requested_step === '' || !$this->feature_flags->isStepEnabled($requested_step)) {
            $requested_step = $fallback_step ?: 'welcome';
        }

        if ($requested_step === 'starter' && empty($this->current_state['selected_goal'])) {
            $requested_step = $this->feature_flags->isStepEnabled('goal') ? 'goal' : ($fallback_step ?: 'welcome');
        }

        if ($requested_step === 'publish' && empty($this->current_state['last_created_form_id'])) {
            $requested_step = $this->feature_flags->isStepEnabled('starter') ? 'starter' : ($fallback_step ?: 'welcome');
        }

        if ($requested_step === 'success' && empty($this->current_state['last_created_form_id'])) {
            $requested_step = $fallback_step ?: 'welcome';
        }

        if (!in_array($requested_step, ['welcome', 'goal', 'starter', 'publish', 'success'], true)) {
            $requested_step = $fallback_step ?: 'welcome';
        }

        $this->current_step = $requested_step;
    }

    protected function syncCurrentStepState()
    {
        if ($this->current_state['status'] === 'completed') {
            return;
        }

        if ($this->current_state['current_step'] === $this->current_step) {
            return;
        }

        $this->current_state = $this->progress->moveToStep($this->current_step, [
            'selected_goal' => $this->current_state['selected_goal'],
            'selected_toggles' => $this->current_state['selected_toggles'],
            'selected_placement_action' => $this->current_state['selected_placement_action'],
            'placement_page_title' => $this->current_state['placement_page_title'],
            'placement_target_type' => $this->current_state['placement_target_type'],
            'placement_target_id' => $this->current_state['placement_target_id'],
            'placement_result' => $this->current_state['placement_result'],
            'placement_error' => $this->current_state['placement_error'],
            'last_created_form_id' => $this->current_state['last_created_form_id'],
        ]);
    }

    protected function processPostAction()
    {
        if (strtoupper($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
            return;
        }

        $action = isset($_POST['gf_onboarding_action']) ? sanitize_key(wp_unslash($_POST['gf_onboarding_action'])) : '';
        if ($action === 'select_goal') {
            $this->processGoalSelection();
            return;
        }

        if ($action === 'create_starter') {
            $this->processStarterCreation();
            return;
        }

        if ($action === 'complete_publish') {
            $this->processPublishCompletion();
        }
    }

    protected function processGoalSelection()
    {
        $nonce = isset($_POST['gf_onboarding_nonce']) ? sanitize_text_field(wp_unslash($_POST['gf_onboarding_nonce'])) : '';
        if (!wp_verify_nonce($nonce, 'griffinforms_onboarding_goal')) {
            $this->error_message = __('The onboarding request could not be verified. Please try again.', 'griffinforms-form-builder');
            $this->current_step = 'goal';
            return;
        }

        $goal_key = isset($_POST['goal_key']) ? sanitize_key(wp_unslash($_POST['goal_key'])) : '';
        if (!$this->starter_catalog->getGoal($goal_key)) {
            $this->error_message = __('Choose a starter goal to continue.', 'griffinforms-form-builder');
            $this->current_step = 'goal';
            return;
        }

        $this->current_state = $this->progress->moveToStep('starter', [
            'selected_goal' => $goal_key,
            'selected_toggles' => [],
        ]);

        $this->navigateTo($this->getStepUrl('starter'));
    }

    protected function processStarterCreation()
    {
        $nonce = isset($_POST['gf_onboarding_nonce']) ? sanitize_text_field(wp_unslash($_POST['gf_onboarding_nonce'])) : '';
        if (!wp_verify_nonce($nonce, 'griffinforms_onboarding_starter')) {
            $this->error_message = __('The onboarding request could not be verified. Please try again.', 'griffinforms-form-builder');
            $this->current_step = 'starter';
            return;
        }

        $goal_key = isset($_POST['goal_key']) ? sanitize_key(wp_unslash($_POST['goal_key'])) : '';
        $toggle_keys = isset($_POST['toggle_keys']) && is_array($_POST['toggle_keys'])
            ? array_map('sanitize_key', wp_unslash($_POST['toggle_keys']))
            : [];

        $goal = $this->starter_catalog->getGoal($goal_key);
        if (!$goal) {
            $this->error_message = __('The selected starter goal is no longer available.', 'griffinforms-form-builder');
            $this->current_step = 'goal';
            return;
        }

        $toggle_keys = $this->starter_catalog->sanitizeToggleKeys($goal_key, $toggle_keys);
        $this->current_state = $this->progress->moveToStep('starter', [
            'selected_goal' => $goal_key,
            'selected_toggles' => $toggle_keys,
            'selected_placement_action' => '',
            'placement_page_title' => '',
            'placement_target_type' => '',
            'placement_target_id' => 0,
            'placement_result' => [],
            'placement_error' => '',
        ]);

        $form_id = $this->starter_generator->createFormFromGoal($goal_key, $toggle_keys);
        if (is_wp_error($form_id)) {
            $this->error_message = $form_id->get_error_message();
            $this->current_step = 'starter';
            return;
        }

        $next_step = $this->feature_flags->isStepEnabled('publish') ? 'publish' : 'success';
        $this->current_state = $this->progress->moveToStep($next_step, [
            'selected_goal' => $goal_key,
            'selected_toggles' => $toggle_keys,
            'last_created_form_id' => $form_id,
            'selected_placement_action' => '',
            'placement_page_title' => '',
            'placement_target_type' => '',
            'placement_target_id' => 0,
            'placement_result' => [],
            'placement_error' => '',
        ]);

        if ($next_step === 'success') {
            $this->current_state = $this->progress->markCompleted([
                'selected_goal' => $goal_key,
                'selected_toggles' => $toggle_keys,
                'last_created_form_id' => $form_id,
            ]);
        }

        $this->navigateTo($this->getStepUrl($next_step));
    }

    protected function processPublishCompletion()
    {
        $nonce = isset($_POST['gf_onboarding_nonce']) ? sanitize_text_field(wp_unslash($_POST['gf_onboarding_nonce'])) : '';
        if (!wp_verify_nonce($nonce, 'griffinforms_onboarding_publish')) {
            $this->error_message = __('The onboarding request could not be verified. Please try again.', 'griffinforms-form-builder');
            $this->current_step = 'publish';
            return;
        }

        $form_id = absint($this->current_state['last_created_form_id']);
        if ($form_id < 1) {
            $this->error_message = __('The created form could not be found. Please start again.', 'griffinforms-form-builder');
            $this->current_step = 'starter';
            return;
        }

        $placement_action = isset($_POST['placement_action']) ? sanitize_key(wp_unslash($_POST['placement_action'])) : 'create_form_only';
        $allowed_actions = ['create_form_only', 'create_and_add_to_new_page', 'create_and_add_to_new_post', 'add_to_existing_content'];
        if (!in_array($placement_action, $allowed_actions, true)) {
            $placement_action = 'create_form_only';
        }

        $placement_target_type = isset($_POST['placement_target_type']) ? sanitize_key(wp_unslash($_POST['placement_target_type'])) : 'page';
        if (!in_array($placement_target_type, ['page', 'post'], true)) {
            $placement_target_type = 'page';
        }

        $placement_target_id = isset($_POST['placement_target_id']) ? absint(wp_unslash($_POST['placement_target_id'])) : 0;
        $page_title = isset($_POST['page_title']) ? sanitize_text_field(wp_unslash($_POST['page_title'])) : '';

        $placement_result = [];
        $placement_error = '';
        $manual_fallback = false;

        $result = $this->placement_service->placeForm(
            $form_id,
            $placement_action,
            $placement_target_type,
            $placement_target_id,
            $page_title
        );

        if (is_wp_error($result)) {
            $placement_error = $result->get_error_message();
            $manual_fallback = $result->get_error_code() === 'griffinforms_builder_manual_fallback';
        } else {
            $placement_result = $result;
        }

        if ($placement_error !== '' && !$manual_fallback) {
            $this->error_message = $placement_error;
            $this->current_state = $this->progress->moveToStep('publish', [
                'selected_goal' => $this->current_state['selected_goal'],
                'selected_toggles' => $this->current_state['selected_toggles'],
                'selected_placement_action' => $placement_action,
                'placement_page_title' => $page_title,
                'placement_target_type' => $placement_target_type,
                'placement_target_id' => $placement_target_id,
                'placement_result' => [],
                'placement_error' => $placement_error,
                'last_created_form_id' => $form_id,
            ]);
            $this->current_step = 'publish';
            return;
        }

        $this->current_state = $this->progress->markCompleted([
            'selected_goal' => $this->current_state['selected_goal'],
            'selected_toggles' => $this->current_state['selected_toggles'],
            'selected_placement_action' => $placement_action,
            'placement_page_title' => $page_title,
            'placement_target_type' => $placement_target_type,
            'placement_target_id' => $placement_target_id,
            'placement_result' => $placement_result,
            'placement_error' => $placement_error,
            'last_created_form_id' => $form_id,
        ]);

        $this->navigateTo($this->getStepUrl('success'));
    }

    protected function getVisibleSteps(): array
    {
        return array_values(array_intersect($this->feature_flags->getEnabledSteps(), ['welcome', 'goal', 'starter', 'publish']));
    }

    protected function renderProgress()
    {
        $visible_steps = $this->getVisibleSteps();
        $step_index = array_search($this->current_step, $visible_steps, true);
        $current_number = $step_index === false ? 1 : ($step_index + 1);
        if ($this->current_step === 'success') {
            $current_number = max(1, count($visible_steps));
        }
        $total_steps = max(1, count($visible_steps));

        echo '<ol class="gf-onboarding-progress" aria-label="' . esc_attr__('Onboarding progress', 'griffinforms-form-builder') . '">';
        foreach ($visible_steps as $index => $step_key) {
            $step_number = $index + 1;
            $state_class = 'is-upcoming';

            if ($step_number < $current_number || $this->current_step === 'success') {
                $state_class = 'is-complete';
            } elseif ($step_number === $current_number) {
                $state_class = 'is-current';
            }

            echo '<li class="gf-onboarding-progress-item ' . esc_attr($state_class) . '">';
            echo '<span class="gf-onboarding-progress-bead" aria-hidden="true"></span>';
            echo '<span class="gf-onboarding-progress-label">' . esc_html($this->getStepHeading($step_key)) . '</span>';
            echo '</li>';
        }
        echo '</ol>';
    }

    protected function getStepHeading(string $step_key = ''): string
    {
        $headings = [
            'welcome' => $this->lang->getText('onboarding_step_welcome'),
            'goal' => $this->lang->getText('onboarding_step_goal'),
            'starter' => $this->lang->getText('onboarding_step_starter'),
            'publish' => $this->lang->getText('onboarding_step_publish'),
            'success' => $this->lang->getText('onboarding_step_success'),
        ];

        if ($step_key === '') {
            $step_key = $this->current_step;
        }

        return $headings[$step_key] ?? $this->lang->getText('onboarding_step_welcome');
    }

    protected function renderSupportPanel()
    {
        $support_heading = $this->lang->getText('onboarding_what_next');
        $support_copy = $this->lang->getText('onboarding_what_next_body');

        if ($this->current_step === 'goal') {
            $support_heading = $this->lang->getText('onboarding_goal_help_heading');
            $support_copy = $this->lang->getText('onboarding_goal_help_body');
        } elseif ($this->current_step === 'starter') {
            $support_heading = $this->lang->getText('onboarding_starter_help_heading');
            $support_copy = $this->lang->getText('onboarding_starter_help_body');
        } elseif ($this->current_step === 'publish') {
            $support_heading = $this->lang->getText('onboarding_publish_help_heading');
            $support_copy = $this->lang->getText('onboarding_publish_help_body');
        } elseif ($this->current_step === 'success') {
            $support_heading = $this->lang->getText('onboarding_success_help_heading');
            $support_copy = $this->lang->getText('onboarding_success_help_body');
        }

        if ($this->isRegistrationStarterFlow() && $this->current_step === 'publish') {
            $support_heading = $this->lang->getText('onboarding_registration_publish_help_heading');
            $support_copy = $this->lang->getText('onboarding_registration_publish_help_body');
        } elseif ($this->isRegistrationStarterFlow() && $this->current_step === 'success') {
            $support_heading = $this->lang->getText('onboarding_registration_success_help_heading');
            $support_copy = $this->lang->getText('onboarding_registration_success_help_body');
        }

        $support_graphic = 'support-welcome.svg';
        if ($this->current_step === 'goal') {
            $support_graphic = 'support-goal.svg';
        } elseif ($this->current_step === 'starter') {
            $support_graphic = 'support-starter.svg';
        } elseif ($this->current_step === 'publish') {
            $support_graphic = 'support-publish.svg';
        } elseif ($this->current_step === 'success') {
            $support_graphic = 'support-success.svg';
        }

        echo '<aside class="gf-onboarding-support">';
        if ($this->feature_flags->isEnabled('graphics')) {
            $graphic_url = $this->config->getRootUrl() . 'admin/images/onboarding/' . $support_graphic;
            echo '<div class="gf-onboarding-support-graphic-wrap">';
            echo '<img src="' . esc_url($graphic_url) . '" alt="" class="gf-onboarding-support-graphic" />';
            echo '</div>';
        }

        echo '<h2 class="gf-onboarding-support-heading">' . esc_html($support_heading) . '</h2>';
        echo '<p class="gf-onboarding-support-copy">' . esc_html($support_copy) . '</p>';
        echo '<p class="gf-onboarding-support-link-row"><a class="gf-onboarding-support-link" href="' . esc_url($this->getDocumentationUrl()) . '" target="_blank" rel="noopener noreferrer">' . esc_html($this->lang->getText('onboarding_need_help_docs')) . '</a></p>';
        echo '</aside>';
    }

    protected function renderErrorNotice()
    {
        if ($this->error_message === '') {
            return;
        }

        echo '<div class="notice notice-error inline gf-onboarding-error-notice"><p>' . esc_html($this->error_message) . '</p></div>';
    }

    protected function renderPromiseList()
    {
        echo '<ul class="gf-onboarding-promise-list">';
        echo '<li>' . esc_html($this->lang->getText('onboarding_promise_line_one')) . '</li>';
        echo '<li>' . esc_html($this->lang->getText('onboarding_promise_line_two')) . '</li>';
        echo '<li>' . esc_html($this->lang->getText('onboarding_promise_line_three')) . '</li>';
        echo '</ul>';
    }

    protected function isRegistrationStarterFlow(): bool
    {
        return (string) ($this->current_state['selected_goal'] ?? '') === 'user_registration';
    }

    protected function renderWelcomeStep()
    {
        echo '<div class="gf-onboarding-card">';
        $this->renderPromiseList();

        echo '<div class="gf-onboarding-card-actions gf-onboarding-card-actions-split">';
        echo '<a class="btn btn-outline-secondary gf-onboarding-action-secondary" href="' . esc_url($this->feature_flags->getFormsPageUrl()) . '">' . esc_html($this->lang->getText('onboarding_continue_to_forms')) . '</a>';
        echo '<a class="btn btn-primary gf-onboarding-action-primary" href="' . esc_url($this->getCreateFormUrl()) . '">' . esc_html($this->lang->getText('start_setup')) . '</a>';
        echo '</div>';

        if ($this->canRenderImportEntry()) {
            $sources = $this->getImportEntrySources();
            $import_url = $this->getImportEntryUrl();
            $images_base = $this->config->getRootUrl() . 'admin/images/migration/';
            echo '<div class="gf-onboarding-welcome-import-entry">';
            echo '<span class="gf-onboarding-import-label">' . esc_html__('Switching from another plugin?', 'griffinforms-form-builder') . '</span>';
            echo '<span class="gf-onboarding-import-logos">';
            foreach ($sources as $source) {
                $logo = $source->getLogoUrl();
                if ($logo !== '') {
                    echo '<img src="' . esc_url($logo) . '" alt="' . esc_attr($source->getLabel()) . '" class="gf-onboarding-import-logo" title="' . esc_attr($source->getLabel()) . '">';
                }
            }
            echo '</span>';
            echo '<a href="' . esc_url($import_url) . '" class="gf-onboarding-import-link">' . esc_html__('Import your forms', 'griffinforms-form-builder') . '</a>';
            echo '</div>';
        }

        echo '</div>';
    }

    protected function renderGoalStep()
    {
        $goals = $this->starter_catalog->getGoals();
        $selected_goal = $this->current_state['selected_goal'];
        if ($selected_goal === '' || !isset($goals[$selected_goal])) {
            $selected_goal = array_key_first($goals);
        }

        echo '<form method="post" class="gf-onboarding-card gf-onboarding-form">';
        echo '<div class="gf-onboarding-card-header">';
        echo '<h2 class="gf-onboarding-card-heading">' . esc_html($this->lang->getText('onboarding_goal_heading')) . '</h2>';
        echo '<p class="gf-onboarding-card-copy">' . esc_html($this->lang->getText('onboarding_goal_body')) . '</p>';
        echo '</div>';

        echo '<div class="gf-onboarding-goal-grid">';
        foreach ($goals as $goal_key => $goal) {
            $checked = $selected_goal === $goal_key;
            echo '<label class="gf-onboarding-goal-card' . ($checked ? ' is-selected' : '') . '">';
            echo '<input type="radio" class="gf-onboarding-goal-input" name="goal_key" value="' . esc_attr($goal_key) . '"' . checked($checked, true, false) . ' />';
            if ($this->feature_flags->isEnabled('graphics')) {
                $icon_url = $this->config->getRootUrl() . 'admin/images/onboarding/' . rawurlencode((string) $goal['icon']);
                echo '<span class="gf-onboarding-goal-icon-wrap" aria-hidden="true">';
                echo '<img src="' . esc_url($icon_url) . '" alt="" class="gf-onboarding-goal-icon" />';
                echo '</span>';
            }
            echo '<span class="gf-onboarding-goal-title">' . esc_html($goal['label']) . '</span>';
            echo '<span class="gf-onboarding-goal-description">' . esc_html($goal['description']) . '</span>';
            echo '</label>';
        }
        echo '</div>';

        wp_nonce_field('griffinforms_onboarding_goal', 'gf_onboarding_nonce');
        echo '<input type="hidden" name="gf_onboarding_action" value="select_goal" />';

        echo '<div class="gf-onboarding-card-actions gf-onboarding-card-actions-split">';
        echo '<a class="btn btn-outline-secondary gf-onboarding-action-secondary" href="' . esc_url($this->getStepUrl('welcome')) . '">' . esc_html($this->lang->getText('back')) . '</a>';
        echo '<button type="submit" class="btn btn-primary gf-onboarding-action-primary">' . esc_html($this->lang->getText('onboarding_continue')) . '</button>';
        echo '</div>';
        echo '</form>';
    }

    protected function renderStarterStep()
    {
        $goal_key = $this->current_state['selected_goal'];
        $goal = $this->starter_catalog->getGoal($goal_key);

        if (!$goal) {
            $this->navigateTo($this->getStepUrl('goal'));
        }

        $selected_toggles = $this->starter_catalog->sanitizeToggleKeys($goal_key, $this->current_state['selected_toggles']);
        $field_keys = $this->starter_catalog->getStarterFieldKeys($goal_key, $selected_toggles);
        $toggle_definitions = $this->starter_catalog->getToggleDefinitions($goal_key);

        echo '<form method="post" class="gf-onboarding-card gf-onboarding-form">';
        echo '<div class="gf-onboarding-card-header">';
        echo '<h2 class="gf-onboarding-card-heading">' . esc_html($goal['label']) . '</h2>';
        echo '<p class="gf-onboarding-card-copy">' . esc_html($goal['description']) . '</p>';
        echo '</div>';

        echo '<div class="gf-onboarding-preview-grid">';
        echo '<section class="gf-onboarding-preview-panel">';
        echo '<h3 class="gf-onboarding-panel-heading">' . esc_html($this->lang->getText('onboarding_preview_heading')) . '</h3>';
        echo '<ul class="gf-onboarding-preview-list">';
        foreach ($field_keys as $field_key) {
            echo '<li>' . esc_html($this->starter_catalog->getFieldLabel($field_key)) . '</li>';
        }
        echo '</ul>';
        echo '</section>';

        echo '<section class="gf-onboarding-preview-panel">';
        echo '<h3 class="gf-onboarding-panel-heading">' . esc_html($this->lang->getText('onboarding_optional_fields_heading')) . '</h3>';
        if (!empty($toggle_definitions)) {
            echo '<div class="gf-onboarding-toggle-list">';
            foreach ($toggle_definitions as $toggle_key => $toggle) {
                $checked = in_array($toggle_key, $selected_toggles, true);
                echo '<label class="gf-onboarding-toggle">';
                echo '<input type="checkbox" name="toggle_keys[]" value="' . esc_attr($toggle_key) . '"' . checked($checked, true, false) . ' />';
                echo '<span class="gf-onboarding-toggle-text">';
                echo '<strong>' . esc_html($toggle['label']) . '</strong>';
                if ($toggle['description'] !== '') {
                    echo '<small>' . esc_html($toggle['description']) . '</small>';
                }
                echo '</span>';
                echo '</label>';
            }
            echo '</div>';
        } else {
            echo '<p class="gf-onboarding-panel-copy">' . esc_html($this->lang->getText('onboarding_optional_fields_none')) . '</p>';
        }
        echo '</section>';
        echo '</div>';

        if ($this->canRenderImportEntry()) {
            $this->renderStarterImportEntry();
        }

        wp_nonce_field('griffinforms_onboarding_starter', 'gf_onboarding_nonce');
        echo '<input type="hidden" name="gf_onboarding_action" value="create_starter" />';
        echo '<input type="hidden" name="goal_key" value="' . esc_attr($goal_key) . '" />';

        echo '<div class="gf-onboarding-card-actions gf-onboarding-card-actions-split">';
        echo '<a class="btn btn-outline-secondary gf-onboarding-action-secondary" href="' . esc_url($this->getStepUrl('goal')) . '">' . esc_html($this->lang->getText('back')) . '</a>';
        echo '<button type="submit" class="btn btn-primary gf-onboarding-action-primary">' . esc_html($this->lang->getText('onboarding_create_starter')) . '</button>';
        echo '</div>';
        echo '</form>';
    }

    protected function renderStarterImportEntry(): void
    {
        $source_labels = $this->getImportEntryLabels();

        echo '<section class="gf-onboarding-preview-panel gf-onboarding-import-entry">';
        echo '<h3 class="gf-onboarding-panel-heading">' . esc_html__('Already have forms in another plugin?', 'griffinforms-form-builder') . '</h3>';
        if ($source_labels !== '') {
            echo '<p class="gf-onboarding-panel-copy">' . esc_html(sprintf(__('We detected forms in %s. You can import them into GriffinForms instead of starting from a new starter.', 'griffinforms-form-builder'), $source_labels)) . '</p>';
        } else {
            echo '<p class="gf-onboarding-panel-copy">' . esc_html__('You can import existing forms into GriffinForms instead of starting from a new starter.', 'griffinforms-form-builder') . '</p>';
        }
        echo '<div class="gf-onboarding-card-actions">';
        echo '<a class="btn btn-outline-secondary gf-onboarding-action-secondary" href="' . esc_url($this->getImportEntryUrl()) . '">' . esc_html__('Import Existing Forms', 'griffinforms-form-builder') . '</a>';
        echo '</div>';
        echo '</section>';
    }

    protected function renderPublishStep()
    {
        $form_id = absint($this->current_state['last_created_form_id']);
        if ($form_id < 1) {
            $this->navigateTo($this->getStepUrl('starter'));
        }

        $selected_action = $this->current_state['selected_placement_action'] ?: 'create_and_add_to_new_page';
        $placement_target_type = $this->current_state['placement_target_type'] ?: 'page';
        $placement_target_id = absint($this->current_state['placement_target_id']);
        $page_title = is_string($this->current_state['placement_page_title']) && trim($this->current_state['placement_page_title']) !== ''
            ? $this->current_state['placement_page_title']
            : $this->getSuggestedPageTitle();

        $shortcode = $this->placement_service->getShortcode($form_id);
        $page_options = $this->placement_service->getContentOptions('page');
        $post_options = $this->placement_service->getContentOptions('post');

        echo '<form method="post" class="gf-onboarding-card gf-onboarding-form">';
        echo '<div class="gf-onboarding-card-header">';
        echo '<h2 class="gf-onboarding-card-heading">' . esc_html($this->lang->getText('onboarding_publish_heading')) . '</h2>';
        echo '<p class="gf-onboarding-card-copy">' . esc_html($this->lang->getText('onboarding_publish_body')) . '</p>';
        echo '</div>';

        echo '<div class="gf-onboarding-publish-grid">';
        echo '<label class="gf-onboarding-placement-card' . ($selected_action === 'create_and_add_to_new_page' ? ' is-selected' : '') . '">';
        echo '<input type="radio" name="placement_action" value="create_and_add_to_new_page"' . checked($selected_action, 'create_and_add_to_new_page', false) . ' />';
        echo '<strong>' . esc_html($this->lang->getText('onboarding_placement_new_page')) . ' <span class="gf-onboarding-inline-badge">' . esc_html($this->lang->getText('onboarding_recommended')) . '</span></strong>';
        echo '<span>' . esc_html($this->lang->getText('onboarding_placement_new_page_body')) . '</span>';
        echo '</label>';

        echo '<label class="gf-onboarding-placement-card' . ($selected_action === 'add_to_existing_content' ? ' is-selected' : '') . '">';
        echo '<input type="radio" name="placement_action" value="add_to_existing_content"' . checked($selected_action, 'add_to_existing_content', false) . ' />';
        echo '<strong>' . esc_html($this->lang->getText('onboarding_placement_existing')) . '</strong>';
        echo '<span>' . esc_html($this->lang->getText('onboarding_placement_existing_body')) . '</span>';
        echo '</label>';

        echo '<label class="gf-onboarding-placement-card' . ($selected_action === 'create_form_only' ? ' is-selected' : '') . '">';
        echo '<input type="radio" name="placement_action" value="create_form_only"' . checked($selected_action, 'create_form_only', false) . ' />';
        echo '<strong>' . esc_html($this->lang->getText('onboarding_placement_create_only')) . '</strong>';
        echo '<span>' . esc_html($this->lang->getText('onboarding_placement_create_only_body')) . '</span>';
        echo '</label>';
        echo '</div>';

        echo '<div class="gf-onboarding-publish-fields">';
        echo '<div class="gf-onboarding-input-group gf-onboarding-publish-field-group' . ($selected_action === 'create_and_add_to_new_page' ? '' : ' is-hidden') . '" data-gf-placement-fields="create_and_add_to_new_page">';
        echo '<label for="gf-onboarding-page-title">' . esc_html($this->lang->getText('onboarding_page_title')) . '</label>';
        echo '<input type="text" id="gf-onboarding-page-title" name="page_title" value="' . esc_attr($page_title) . '" class="regular-text" />';
        echo '</div>';

        echo '<div class="gf-onboarding-inline-fields gf-onboarding-publish-field-group' . ($selected_action === 'add_to_existing_content' ? '' : ' is-hidden') . '" data-gf-placement-fields="add_to_existing_content">';
        echo '<div class="gf-onboarding-input-group">';
        echo '<label for="gf-onboarding-placement-target-type">' . esc_html($this->lang->getText('onboarding_content_type')) . '</label>';
        echo '<select id="gf-onboarding-placement-target-type" name="placement_target_type">';
        echo '<option value="page"' . selected($placement_target_type, 'page', false) . '>' . esc_html($this->lang->getText('onboarding_content_type_page')) . '</option>';
        echo '<option value="post"' . selected($placement_target_type, 'post', false) . '>' . esc_html($this->lang->getText('onboarding_content_type_post')) . '</option>';
        echo '</select>';
        echo '</div>';

        echo '<div class="gf-onboarding-input-group">';
        echo '<label for="gf-onboarding-placement-target-id">' . esc_html($this->lang->getText('onboarding_content_target')) . '</label>';
        echo '<select id="gf-onboarding-placement-target-id" name="placement_target_id">';
        echo '<option value="0">' . esc_html__('Select content', 'griffinforms-form-builder') . '</option>';
        foreach ($page_options as $option) {
            echo '<option value="' . absint($option['id']) . '" data-gf-target-type="page"' . selected($placement_target_id, $option['id'], false) . '>' . esc_html('[Page] ' . $option['title'] . ' (' . $option['status'] . ')') . '</option>';
        }
        foreach ($post_options as $option) {
            echo '<option value="' . absint($option['id']) . '" data-gf-target-type="post"' . selected($placement_target_id, $option['id'], false) . '>' . esc_html('[Post] ' . $option['title'] . ' (' . $option['status'] . ')') . '</option>';
        }
        echo '</select>';
        echo '</div>';
        echo '</div>';
        echo '</div>';

        echo '<details class="gf-onboarding-shortcode-panel gf-onboarding-shortcode-disclosure">';
        echo '<summary class="gf-onboarding-shortcode-summary">' . esc_html($this->lang->getText('onboarding_shortcode_heading')) . '</summary>';
        echo '<div class="gf-onboarding-shortcode-content">';
        echo '<code class="gf-onboarding-shortcode">' . esc_html($shortcode) . '</code>';
        echo '<p class="gf-onboarding-panel-copy">' . esc_html($this->lang->getText('onboarding_manual_help')) . '</p>';
        echo '</div>';
        echo '</details>';

        wp_nonce_field('griffinforms_onboarding_publish', 'gf_onboarding_nonce');
        echo '<input type="hidden" name="gf_onboarding_action" value="complete_publish" />';

        echo '<div class="gf-onboarding-card-actions gf-onboarding-card-actions-split">';
        echo '<a class="btn btn-outline-secondary gf-onboarding-action-secondary" href="' . esc_url($this->getStepUrl('starter')) . '">' . esc_html($this->lang->getText('back')) . '</a>';
        echo '<button type="submit" class="btn btn-primary gf-onboarding-action-primary" data-gf-publish-submit data-gf-label-default="' . esc_attr($this->lang->getText('onboarding_publish_continue')) . '" data-gf-label-unpublished="' . esc_attr($this->lang->getText('onboarding_publish_continue_unpublished')) . '">' . esc_html($this->getPublishContinueLabel($selected_action)) . '</button>';
        echo '</div>';
        echo '</form>';
    }

    protected function renderSuccessStep()
    {
        $form_id = absint($this->current_state['last_created_form_id']);
        if ($form_id < 1) {
            $this->navigateTo($this->getStepUrl('welcome'));
        }

        $placement_result = is_array($this->current_state['placement_result']) ? $this->current_state['placement_result'] : [];
        $placement_action = $this->current_state['selected_placement_action'] ?: 'create_form_only';
        $placement_error = (string) ($this->current_state['placement_error'] ?? '');
        $shortcode = $this->placement_service->getShortcode($form_id);
        $success_copy = $this->lang->getText('onboarding_success_create_only');

        if (!empty($placement_result)) {
            $success_copy = $this->lang->getText('onboarding_success_placed');
        } elseif ($placement_error !== '') {
            $success_copy = $this->lang->getText('onboarding_success_manual_fallback');
        }

        echo '<div class="gf-onboarding-card gf-onboarding-success-card">';
        echo '<div class="gf-onboarding-card-header">';
        echo '<h2 class="gf-onboarding-card-heading">' . esc_html($this->lang->getText('onboarding_success_heading')) . '</h2>';
        echo '<p class="gf-onboarding-card-copy">' . esc_html($success_copy) . '</p>';
        echo '</div>';

        if ($placement_error !== '') {
            echo '<div class="notice notice-warning inline"><p>' . esc_html($placement_error) . '</p></div>';
        }

        if (!empty($placement_result)) {
            echo '<div class="gf-onboarding-success-meta">';
            echo '<div><strong>' . esc_html($this->lang->getText('onboarding_placed_in')) . ':</strong> ' . esc_html($this->getPlacementResultLabel($placement_result)) . '</div>';
            echo '</div>';
        }

        echo '<div class="gf-onboarding-shortcode-panel">';
        echo '<h3 class="gf-onboarding-panel-heading">' . esc_html($this->lang->getText('onboarding_shortcode_heading')) . '</h3>';
        echo '<code class="gf-onboarding-shortcode">' . esc_html($shortcode) . '</code>';
        echo '<p class="gf-onboarding-panel-copy">' . esc_html($this->lang->getText('onboarding_manual_help')) . '</p>';
        echo '</div>';

        echo '<div class="gf-onboarding-card-actions gf-onboarding-success-actions gf-onboarding-success-actions-primary">';
        if (!empty($placement_result['view_url'])) {
            echo '<a class="btn btn-primary gf-onboarding-action-primary" href="' . esc_url($placement_result['view_url']) . '" target="_blank" rel="noopener noreferrer">' . esc_html($this->lang->getText('onboarding_view_live_page')) . '</a>';
        } else {
            echo '<a class="btn btn-primary gf-onboarding-action-primary" href="' . esc_url($this->getBuilderUrl($form_id)) . '">' . esc_html($this->lang->getText('onboarding_edit_form')) . '</a>';
        }
        echo '<a class="btn btn-outline-secondary gf-onboarding-action-secondary" href="' . esc_url($this->feature_flags->getFormsPageUrl()) . '">' . esc_html($this->lang->getText('onboarding_finish')) . '</a>';
        echo '</div>';

        echo '<div class="gf-onboarding-card-actions gf-onboarding-success-actions gf-onboarding-success-actions-secondary">';
        if (!empty($placement_result['view_url'])) {
            echo '<a class="gf-onboarding-success-link" href="' . esc_url($this->getBuilderUrl($form_id)) . '">' . esc_html($this->lang->getText('onboarding_edit_form')) . '</a>';
        }
        echo '<a class="gf-onboarding-success-link" href="' . esc_url($this->getStepUrl('goal', ['entry_source' => 'manual'])) . '">' . esc_html($this->lang->getText('onboarding_create_another')) . '</a>';
        echo '</div>';
        echo '</div>';
    }

    protected function renderCurrentStep()
    {
        if ($this->current_step === 'goal') {
            $this->renderGoalStep();
            return;
        }

        if ($this->current_step === 'starter') {
            $this->renderStarterStep();
            return;
        }

        if ($this->current_step === 'publish') {
            $this->renderPublishStep();
            return;
        }

        if ($this->current_step === 'success') {
            $this->renderSuccessStep();
            return;
        }

        $this->renderWelcomeStep();
    }

    public function html()
    {
        $this->ensureAccessible();
        $this->setEntrySource();
        $this->processDismissAction();
        $this->maybeResetPreviewState();
        $this->markEntry();
        $this->setCurrentState();
        $this->processPostAction();
        $this->setCurrentState();
        $this->setCurrentStep();
        $this->syncCurrentStepState();

        echo '<div class="wrap gf-onboarding-wrap">';
        echo '<div class="gf-onboarding-hero">';
        echo '<div class="gf-onboarding-brand">';
        echo '<img class="gf-onboarding-brand-logo" src="' . esc_url($this->getBrandLogoUrl()) . '" alt="' . esc_attr__('GriffinForms', 'griffinforms-form-builder') . '" width="34" height="34" />';
        echo '</div>';
        if ($this->current_step === 'welcome') {
            echo '<div class="gf-onboarding-eyebrow">' . esc_html($this->lang->getText('onboarding_welcome_eyebrow')) . '</div>';
        }
        $this->pageHeading($this->lang->getText('heading', 'onboarding'), $this->lang->getText('onboarding_subtitle'));
        echo '<div class="gf-onboarding-hero-actions">';
        $this->renderProgress();
        echo '<a class="btn btn-outline-secondary btn-sm gf-onboarding-dismiss-link" href="' . esc_url($this->getDismissUrl()) . '" data-gf-onboarding-dismiss="1">' . esc_html($this->lang->getText('skip_for_now')) . '</a>';
        echo '</div>';
        echo '</div>';
        echo '<div class="gf-onboarding-shell">';
        echo '<div class="gf-onboarding-main">';
        $this->renderErrorNotice();
        $this->renderCurrentStep();
        echo '</div>';

        $this->renderSupportPanel();
        echo '</div>';
        echo '</div>';
    }

    public function __construct()
    {
        $this->setAll();
    }
}
