<?php

namespace GriffinForms\Includes\Onboarding;

use GriffinForms\Traits\Singleton;

class PreviewPage extends \GriffinForms\Format
{
    use Singleton;

    public const OPTION_NAME = 'griffinforms_preview_page_id';
    public const PAGE_SLUG = 'griffinforms-form-preview';
    public const PAGE_TITLE = 'GriffinForms Form Preview';
    public const PAGE_META_KEY = '_griffinforms_preview_page';

    public function getOptionName(): string
    {
        return self::OPTION_NAME;
    }

    public function registerHooks(): void
    {
        add_filter('show_admin_bar', [$this, 'maybeHideAdminBar']);
        add_filter('body_class', [$this, 'addPreviewBodyClass']);
        add_action('wp_head', [$this, 'renderPreviewModeStyles'], 99);
    }

    public function maybeHideAdminBar($show): bool
    {
        if (isset($_GET['gf_preview_form']) && absint(wp_unslash($_GET['gf_preview_form'])) > 0) {
            return false;
        }

        return (bool) $show;
    }

    public function addPreviewBodyClass(array $classes): array
    {
        if (isset($_GET['gf_preview_form']) && absint(wp_unslash($_GET['gf_preview_form'])) > 0) {
            $classes[] = 'griffinforms-preview-mode';
        }

        return $classes;
    }

    public function renderPreviewModeStyles(): void
    {
        if (!isset($_GET['gf_preview_form']) || absint(wp_unslash($_GET['gf_preview_form'])) < 1) {
            return;
        }

        echo '<style id="griffinforms-preview-mode-css">';
        echo 'body.griffinforms-preview-mode header,';
        echo 'body.griffinforms-preview-mode footer,';
        echo 'body.griffinforms-preview-mode .site-header,';
        echo 'body.griffinforms-preview-mode .site-footer,';
        echo 'body.griffinforms-preview-mode .entry-title,';
        echo 'body.griffinforms-preview-mode .post-title,';
        echo 'body.griffinforms-preview-mode .wp-block-post-title { display:none !important; }';
        echo 'body.griffinforms-preview-mode #wpadminbar { display:none !important; }';
        echo 'body.griffinforms-preview-mode { margin-top:0 !important; padding-top:0 !important; }';
        echo 'body.griffinforms-preview-mode .site,';
        echo 'body.griffinforms-preview-mode #page,';
        echo 'body.griffinforms-preview-mode .wp-site-blocks { min-height:100vh; }';
        echo 'body.griffinforms-preview-mode .wp-site-blocks,';
        echo 'body.griffinforms-preview-mode .wp-block-post-content,';
        echo 'body.griffinforms-preview-mode .entry-content,';
        echo 'body.griffinforms-preview-mode .site-content,';
        echo 'body.griffinforms-preview-mode #content,';
        echo 'body.griffinforms-preview-mode #primary,';
        echo 'body.griffinforms-preview-mode main { overflow: visible !important; }';
        echo '@media (min-width: 768px) {';
        echo 'body.griffinforms-preview-mode .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)) {';
        echo '--wp--style--global--content-size: 1024px !important;';
        echo 'max-width: 1024px !important;';
        echo '}';
        echo '}';
        echo '</style>';
    }

    public function getPageId(): int
    {
        return absint($this->settings->getOption(self::OPTION_NAME, 0));
    }

    public function ensurePage(): int
    {
        $page_id = $this->getPageId();
        $page = $page_id > 0 ? get_post($page_id) : null;

        if ($page instanceof \WP_Post && $page->post_type === 'page' && $page->post_status !== 'trash') {
            $this->syncPage($page->ID);
            return (int) $page->ID;
        }

        $existing_ids = get_posts([
            'post_type' => 'page',
            'post_status' => ['publish', 'draft', 'pending', 'future', 'private'],
            'fields' => 'ids',
            'posts_per_page' => 1,
            'meta_key' => self::PAGE_META_KEY,
            'meta_value' => 1,
            'orderby' => 'ID',
            'order' => 'ASC',
        ]);

        if (!empty($existing_ids)) {
            $existing = get_post((int) $existing_ids[0]);
            if ($existing instanceof \WP_Post && $existing->post_status !== 'trash') {
                $this->syncPage($existing->ID);
                update_option(self::OPTION_NAME, (int) $existing->ID, false);
                return (int) $existing->ID;
            }
        }

        $existing = get_page_by_path(self::PAGE_SLUG, OBJECT, 'page');
        if ($existing instanceof \WP_Post && $existing->post_status !== 'trash' && (int) get_post_meta($existing->ID, self::PAGE_META_KEY, true) === 1) {
            $this->syncPage($existing->ID);
            update_option(self::OPTION_NAME, (int) $existing->ID, false);
            return (int) $existing->ID;
        }

        $new_page_id = wp_insert_post([
            'post_type' => 'page',
            'post_status' => 'draft',
            'post_title' => self::PAGE_TITLE,
            'post_name' => self::PAGE_SLUG,
            'post_content' => $this->getPageContent(),
            'post_author' => (int) get_current_user_id(),
        ], true);

        if (is_wp_error($new_page_id) || (int) $new_page_id <= 0) {
            return 0;
        }

        update_post_meta((int) $new_page_id, self::PAGE_META_KEY, 1);
        update_option(self::OPTION_NAME, (int) $new_page_id, false);

        return (int) $new_page_id;
    }

    public function getPreviewUrl(int $form_id): string
    {
        $form_id = absint($form_id);
        if ($form_id < 1) {
            return '';
        }

        $page_id = $this->ensurePage();
        if ($page_id < 1) {
            return '';
        }

        $preview_url = get_preview_post_link($page_id);
        if (!$preview_url) {
            $preview_url = get_permalink($page_id);
        }

        if (!$preview_url) {
            return '';
        }

        return add_query_arg('gf_preview_form', $form_id, $preview_url);
    }

    public function getPageContent(): string
    {
        return "<!-- wp:griffinforms/form /-->";
    }

    protected function syncPage(int $page_id): void
    {
        $page_id = absint($page_id);
        if ($page_id < 1) {
            return;
        }

        $page = get_post($page_id);
        if (!$page instanceof \WP_Post) {
            return;
        }

        $desired_content = $this->getPageContent();
        if (
            $page->post_title !== self::PAGE_TITLE ||
            $page->post_name !== self::PAGE_SLUG ||
            trim((string) $page->post_content) !== trim($desired_content) ||
            $page->post_status !== 'draft'
        ) {
            wp_update_post([
                'ID' => $page_id,
                'post_type' => 'page',
                'post_status' => 'draft',
                'post_title' => self::PAGE_TITLE,
                'post_name' => self::PAGE_SLUG,
                'post_content' => $desired_content,
            ]);
        }

        if ((int) get_post_meta($page_id, self::PAGE_META_KEY, true) !== 1) {
            update_post_meta($page_id, self::PAGE_META_KEY, 1);
        }
    }
}
