<?php

// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedNamespaceFound -- APD is the established namespace shared with the Pro add-on and retained for backward compatibility.
namespace APD\Admin;

use APD\Front\FrontAssets;
use APD\Front\Renderer;
use APD\Front\FrontContextBuilder;
use APD\Repositories\ProductConfigRepository;
use APD\Support\Json;
use APD\Support\RequestData;

defined('ABSPATH') || exit;

class DesignerStudioPage
{
    private array $metaKeys = [
        '_apd_mode',
        '_apd_theme',
        '_apd_layout',
        '_apd_modules',
        '_apd_permissions',
        '_apd_views',
        '_apd_drawing_zones',
        '_apd_fonts',
        '_apd_upload',
        '_apd_colors',
        '_apd_pricing_rules',
        '_apd_selection_menu',
        '_apd_ui',
        '_apd_front_behavior',
        '_apd_mobile_behavior',
        '_apd_initial_document',
    ];

    public function render() : void
    {
        if (! current_user_can('manage_asuka_designer')) {
            wp_die(esc_html__('You do not have permission to access the designer studio.', 'asuka-product-designer'));
        }

        $query = RequestData::query();
        $configId = absint($query['config_id'] ?? 0);
        $productId = absint($query['product_id'] ?? 0);

        if ($configId <= 0) {
            $this->renderEmptyState();
            return;
        }

        $repository = new ProductConfigRepository();
        $config = $repository->find($configId);
        if (! $config) {
            $this->renderEmptyState();
            return;
        }

        $assets = new FrontAssets();
        $assets->register();
        $assets->enqueue();

        $renderer = new Renderer(new FrontContextBuilder());
        $markup = $renderer->render([
            'id' => $configId,
            'product_id' => $productId,
            'mode' => 'admin',
            'height' => '860px',
        ]);

        $editUrl = admin_url('post.php?post=' . $configId . '&action=edit');
        $linkedProducts = $repository->linkedProducts($configId);
        ?>
        <div class="wrap apd-admin-shell apd-studio-page apd-studio-v7">
            <div class="apd-page-heading apd-page-heading-tight">
                <div>
                    <h1><?php esc_html_e('Designer Studio', 'asuka-product-designer'); ?></h1>
                    <p><?php esc_html_e('This is now the main product-builder workspace. Use the canvas to shape the real experience, then persist the resulting configuration for customer mode.', 'asuka-product-designer'); ?></p>
                </div>
                <div class="apd-inline-actions apd-inline-actions-wrap">
                    <a class="button button-secondary" href="<?php echo esc_url($editUrl); ?>"><?php esc_html_e('Classic editor', 'asuka-product-designer'); ?></a>
                    <a class="button button-secondary" href="<?php echo esc_url(admin_url('edit.php?post_type=apd_user_design&apd_config_id=' . $configId)); ?>"><?php esc_html_e('Saved designs', 'asuka-product-designer'); ?></a>
                </div>
            </div>

            <div class="apd-card apd-studio-intro-card">
                <div class="apd-studio-intro-grid">
                    <div>
                        <span class="apd-badge apd-badge-live"><?php esc_html_e('Canvas-first', 'asuka-product-designer'); ?></span>
                        <h2><?php echo esc_html($config['title'] ?: sprintf(/* translators: Placeholder values are populated from the current administration record. */ __('Config #%d', 'asuka-product-designer'), $configId)); ?></h2>
                        <p><?php esc_html_e('The studio below runs the same engine used on the frontend. Build the product here, capture the current document as the initial document, then tune permissions and modules for customer mode.', 'asuka-product-designer'); ?></p>
                    </div>
                    <div class="apd-studio-kpis">
                        <div class="apd-mini-stat"><strong><?php echo esc_html((string) $configId); ?></strong><span><?php esc_html_e('Config ID', 'asuka-product-designer'); ?></span></div>
                        <div class="apd-mini-stat"><strong><?php echo esc_html((string) count($this->decodeMeta($config['_apd_views'] ?? '', []))); ?></strong><span><?php esc_html_e('Views', 'asuka-product-designer'); ?></span></div>
                        <div class="apd-mini-stat"><strong><?php echo esc_html((string) count($linkedProducts)); ?></strong><span><?php esc_html_e('Linked products', 'asuka-product-designer'); ?></span></div>
                    </div>
                </div>
                <?php if ($linkedProducts) : ?>
                    <div class="apd-chip-row apd-studio-linked-row">
                        <?php foreach ($linkedProducts as $product) : ?>
                            <a class="apd-chip apd-chip-link" href="<?php echo esc_url($product['editUrl']); ?>"><?php echo esc_html($product['title']); ?></a>
                        <?php endforeach; ?>
                    </div>
                <?php endif; ?>
            </div>

            <div class="apd-studio-grid js-apd-studio" data-config-id="<?php echo esc_attr((string) $configId); ?>">
                <section class="apd-card apd-studio-stage-card">
                    <div class="apd-card-head apd-card-head-compact">
                        <div>
                            <h2><?php esc_html_e('Product builder canvas', 'asuka-product-designer'); ?></h2>
                            <p><?php esc_html_e('Compose the base product experience with the real designer. When your canvas state is ready, capture it as the initial document below.', 'asuka-product-designer'); ?></p>
                        </div>
                        <div class="apd-inline-actions apd-inline-actions-wrap">
                            <button type="button" class="button button-secondary" data-apd-sync-studio><?php esc_html_e('Sync canvas payload', 'asuka-product-designer'); ?></button>
                            <button type="button" class="button button-primary" data-apd-capture-document><?php esc_html_e('Use canvas as initial document', 'asuka-product-designer'); ?></button>
                        </div>
                    </div>
                    <div class="apd-studio-shell">
                        <?php echo $markup; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
                    </div>
                </section>

                <aside class="apd-card apd-studio-sidebar-card">
                    <div class="apd-card-head apd-card-head-compact">
                        <div>
                            <h2><?php esc_html_e('Studio controls', 'asuka-product-designer'); ?></h2>
                            <p><?php esc_html_e('Save the configuration from this workspace. Keep the advanced JSON nearby, but treat it as persisted data rather than the main editing surface.', 'asuka-product-designer'); ?></p>
                        </div>
                    </div>

                    <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" class="apd-studio-form">
                        <input type="hidden" name="action" value="apd_save_studio_config">
                        <input type="hidden" name="config_id" value="<?php echo esc_attr((string) $configId); ?>">
                        <?php wp_nonce_field('apd_save_studio_config_' . $configId, 'apd_studio_nonce'); ?>

                        <div class="apd-studio-panels js-apd-tabs" data-default-tab="basics">
                            <div class="apd-tab-nav apd-tab-nav-compact" role="tablist">
                                <button type="button" class="apd-tab-button is-active" data-tab="basics"><?php esc_html_e('Basics', 'asuka-product-designer'); ?></button>
                                <button type="button" class="apd-tab-button" data-tab="experience"><?php esc_html_e('Experience', 'asuka-product-designer'); ?></button>
                                <button type="button" class="apd-tab-button" data-tab="canvas"><?php esc_html_e('Canvas', 'asuka-product-designer'); ?></button>
                                <button type="button" class="apd-tab-button" data-tab="advanced"><?php esc_html_e('Advanced JSON', 'asuka-product-designer'); ?></button>
                            </div>

                            <section class="apd-tab-panel is-active" data-panel="basics">
                                <div class="apd-form-grid apd-form-grid-single">
                                    <label class="apd-field apd-field-stacked">
                                        <span><?php esc_html_e('Config title', 'asuka-product-designer'); ?></span>
                                        <input type="text" name="post_title" value="<?php echo esc_attr((string) ($config['title'] ?? '')); ?>">
                                        <small><?php esc_html_e('Use a clear product-builder name. This is the label used around the plugin and in WooCommerce bindings.', 'asuka-product-designer'); ?></small>
                                    </label>
                                    <label class="apd-field apd-field-stacked">
                                        <span><?php esc_html_e('Mode', 'asuka-product-designer'); ?></span>
                                        <select name="_apd_mode">
                                            <?php foreach (['standalone', 'customer', 'admin'] as $mode) : ?>
                                                <option value="<?php echo esc_attr($mode); ?>" <?php selected((string) ($config['_apd_mode'] ?? 'standalone') ?: 'standalone', $mode); ?>><?php echo esc_html($mode); ?></option>
                                            <?php endforeach; ?>
                                        </select>
                                        <small><?php esc_html_e('Use customer for the public-facing version, admin for internal experimentation, and standalone for generic embedding.', 'asuka-product-designer'); ?></small>
                                    </label>
                                    <label class="apd-field apd-field-stacked">
                                        <span><?php esc_html_e('Starter preset', 'asuka-product-designer'); ?></span>
                                        <select data-apd-studio-preset>
                                            <option value="blank"><?php esc_html_e('Blank starter', 'asuka-product-designer'); ?></option>
                                            <option value="tee"><?php esc_html_e('T-shirt starter', 'asuka-product-designer'); ?></option>
                                            <option value="poster"><?php esc_html_e('Poster starter', 'asuka-product-designer'); ?></option>
                                        </select>
                                        <small><?php esc_html_e('Presets update the structured JSON fields below and help you bootstrap a config faster.', 'asuka-product-designer'); ?></small>
                                    </label>
                                    <div class="apd-inline-actions apd-inline-actions-wrap">
                                        <button type="button" class="button button-secondary" data-apd-apply-studio-preset><?php esc_html_e('Apply preset to config', 'asuka-product-designer'); ?></button>
                                        <button type="button" class="button button-secondary" data-apd-open-json-tab><?php esc_html_e('Inspect advanced JSON', 'asuka-product-designer'); ?></button>
                                    </div>
                                </div>
                            </section>

                            <section class="apd-tab-panel" data-panel="experience">
                                <div class="apd-form-grid apd-form-grid-single">
                                    <?php $this->renderTextareaField('_apd_theme', __('Theme JSON', 'asuka-product-designer'), (string) ($config['_apd_theme'] ?? ''), __('Appearance tokens, palette hints, surfaces, and visual language for the studio and customer UI.', 'asuka-product-designer'), 9); ?>
                                    <?php $this->renderTextareaField('_apd_layout', __('Layout JSON', 'asuka-product-designer'), (string) ($config['_apd_layout'] ?? ''), __('Panels, toolbar areas, and stage height. Keep this aligned with the experience you want customers to get.', 'asuka-product-designer'), 9); ?>
                                    <?php $this->renderTextareaField('_apd_modules', __('Modules JSON', 'asuka-product-designer'), (string) ($config['_apd_modules'] ?? ''), __('Which modules are exposed in each UI zone. This is one of the main levers between admin mode and customer mode.', 'asuka-product-designer'), 10); ?>
                                    <?php $this->renderTextareaField('_apd_permissions', __('Permissions JSON', 'asuka-product-designer'), (string) ($config['_apd_permissions'] ?? ''), __('Permission map such as canAddText, canUploadImage, and canSwitchView.', 'asuka-product-designer'), 10); ?>
                                </div>
                            </section>

                            <section class="apd-tab-panel" data-panel="canvas">
                                <div class="apd-form-grid apd-form-grid-single">
                                    <?php $this->renderTextareaField('_apd_views', __('Views JSON', 'asuka-product-designer'), (string) ($config['_apd_views'] ?? ''), __('The product sides or canvases available to the designer.', 'asuka-product-designer'), 10); ?>
                                    <?php $this->renderTextareaField('_apd_drawing_zones', __('Drawing zones JSON', 'asuka-product-designer'), (string) ($config['_apd_drawing_zones'] ?? ''), __('Safe zones and printable zones per view.', 'asuka-product-designer'), 10); ?>
                                    <?php $this->renderTextareaField('_apd_initial_document', __('Initial document JSON', 'asuka-product-designer'), (string) ($config['_apd_initial_document'] ?? ''), __('This becomes the reusable base document. Use “Use canvas as initial document” to populate it from the current stage.', 'asuka-product-designer'), 14, ['data-apd-initial-document' => '1']); ?>
                                </div>
                            </section>

                            <section class="apd-tab-panel" data-panel="advanced">
                                <div class="apd-form-grid apd-form-grid-single">
                                    <?php $this->renderTextareaField('_apd_colors', __('Colors JSON', 'asuka-product-designer'), (string) ($config['_apd_colors'] ?? ''), __('Available colors, palette groups, or material swatches.', 'asuka-product-designer'), 8); ?>
                                    <?php $this->renderTextareaField('_apd_fonts', __('Fonts JSON', 'asuka-product-designer'), (string) ($config['_apd_fonts'] ?? ''), __('Fonts or font sources to expose to the editor.', 'asuka-product-designer'), 8); ?>
                                    <?php $this->renderTextareaField('_apd_upload', __('Upload JSON', 'asuka-product-designer'), (string) ($config['_apd_upload'] ?? ''), __('Upload strategy, endpoint, and fallback behavior.', 'asuka-product-designer'), 8); ?>
                                    <?php $this->renderTextareaField('_apd_selection_menu', __('Selection menu JSON', 'asuka-product-designer'), (string) ($config['_apd_selection_menu'] ?? ''), __('Contextual menu options shown when an object is selected.', 'asuka-product-designer'), 8); ?>
                                    <?php $this->renderTextareaField('_apd_ui', __('UI JSON', 'asuka-product-designer'), (string) ($config['_apd_ui'] ?? ''), __('Frontend UI settings such as view pagination mode or disabling view pagination.', 'asuka-product-designer'), 8); ?>
                                    <?php $this->renderTextareaField('_apd_front_behavior', __('Front behavior JSON', 'asuka-product-designer'), (string) ($config['_apd_front_behavior'] ?? ''), __('Frontend-specific toggles and restricted customer behavior.', 'asuka-product-designer'), 8); ?>
                                    <?php $this->renderTextareaField('_apd_mobile_behavior', __('Mobile behavior JSON', 'asuka-product-designer'), (string) ($config['_apd_mobile_behavior'] ?? ''), __('Overrides for smaller screens or mobile-specific UI simplifications.', 'asuka-product-designer'), 8); ?>
                                    <?php $this->renderTextareaField('_apd_pricing_rules', __('Pricing rules JSON', 'asuka-product-designer'), (string) ($config['_apd_pricing_rules'] ?? ''), __('Structured pricing rules consumed by the server side as the pricing engine matures.', 'asuka-product-designer'), 8); ?>
                                </div>
                            </section>
                        </div>

                        <div class="apd-studio-form-footer">
                            <div class="apd-studio-note">
                                <strong><?php esc_html_e('Suggested flow', 'asuka-product-designer'); ?></strong>
                                <p><?php esc_html_e('Build on the canvas, capture the document, save the config, then expose the same engine to customers with a reduced permission and module set.', 'asuka-product-designer'); ?></p>
                            </div>
                            <div class="apd-inline-actions apd-inline-actions-wrap">
                                <button type="submit" class="button button-primary button-large"><?php esc_html_e('Save studio config', 'asuka-product-designer'); ?></button>
                            </div>
                        </div>
                    </form>
                </aside>
            </div>
        </div>
        <?php
    }

    public function save() : void
    {
        if (! current_user_can('manage_asuka_designer')) {
            wp_die(esc_html__('You do not have permission to save studio data.', 'asuka-product-designer'));
        }

        $post = RequestData::post();
        $configId = absint($post['config_id'] ?? 0);
        if ($configId <= 0) {
            wp_die(esc_html__('Missing config ID.', 'asuka-product-designer'));
        }

        check_admin_referer('apd_save_studio_config_' . $configId, 'apd_studio_nonce');

        $title = sanitize_text_field((string) ($post['post_title'] ?? ''));
        if ($title !== '') {
            wp_update_post([
                'ID' => $configId,
                'post_title' => $title,
            ]);
        }

        $invalidJsonFields = [];

        foreach ($this->metaKeys as $key) {
            if (! array_key_exists($key, $post)) {
                continue;
            }

            $raw = (string) $post[$key];
            if ($key === '_apd_mode') {
                update_post_meta($configId, $key, sanitize_key($raw));
                continue;
            }

            $normalized = $this->sanitizeJson($raw);
            if ($normalized === null) {
                $invalidJsonFields[] = $this->labelForMetaKey($key);
                continue;
            }

            update_post_meta($configId, $key, wp_slash($normalized));
        }

        if ($invalidJsonFields !== []) {
            AdminNoticeStore::push(
                'designer_studio_' . $configId,
                sprintf(
                    /* translators: %s: comma-separated list of JSON field labels. */
                    __('Some JSON fields were not saved because they contain invalid JSON: %s.', 'asuka-product-designer'),
                    implode(', ', array_unique($invalidJsonFields))
                ),
                'error'
            );
        }

        $redirect = add_query_arg([
            'page' => 'apd-designer-studio',
            'config_id' => $configId,
            'updated' => '1',
        ], admin_url('admin.php'));

        wp_safe_redirect($redirect);
        exit;
    }

    public function renderAdminNotices() : void
    {
        $query = RequestData::query();
        if (sanitize_key((string) ($query['page'] ?? '')) !== 'apd-designer-studio') {
            return;
        }

        $configId = absint($query['config_id'] ?? 0);
        if ($configId <= 0) {
            return;
        }

        foreach (AdminNoticeStore::consume('designer_studio_' . $configId) as $notice) {
            $type = sanitize_html_class((string) ($notice['type'] ?? 'error'));
            $message = (string) ($notice['message'] ?? '');
            if ($message === '') {
                continue;
            }

            echo '<div class="notice notice-' . esc_attr($type) . ' is-dismissible"><p>' . esc_html($message) . '</p></div>';
        }
    }

    private function renderEmptyState() : void
    {
        ?>
        <div class="wrap apd-admin-shell apd-studio-page">
            <div class="apd-page-heading">
                <h1><?php esc_html_e('Designer Studio', 'asuka-product-designer'); ?></h1>
                <p><?php esc_html_e('Select an existing product config first. The studio is meant to become the main canvas-first configuration workspace for that config.', 'asuka-product-designer'); ?></p>
                <a class="button button-primary" href="<?php echo esc_url(admin_url('post-new.php?post_type=apd_product_config')); ?>"><?php esc_html_e('Create a product config', 'asuka-product-designer'); ?></a>
            </div>
        </div>
        <?php
    }

    private function renderTextareaField(string $name, string $label, string $value, string $hint, int $rows = 8, array $attributes = []) : void
    {
        $attrs = '';
        foreach ($attributes as $attr => $attrValue) {
            $attrs .= sprintf(' %s="%s"', esc_attr($attr), esc_attr((string) $attrValue));
        }
        ?>
        <label class="apd-field apd-field-stacked">
            <span><?php echo esc_html($label); ?></span>
            <textarea class="apd-codearea" name="<?php echo esc_attr($name); ?>" rows="<?php echo esc_attr((string) $rows); ?>" spellcheck="false"<?php echo $attrs; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>><?php echo esc_textarea($value); ?></textarea>
            <small><?php echo esc_html($hint); ?></small>
        </label>
        <?php
    }

    private function sanitizeJson(string $value) : ?string
    {
        return Json::normalize($value);
    }

    private function labelForMetaKey(string $key) : string
    {
        return match ($key) {
            '_apd_theme' => __('Theme JSON', 'asuka-product-designer'),
            '_apd_layout' => __('Layout JSON', 'asuka-product-designer'),
            '_apd_modules' => __('Modules JSON', 'asuka-product-designer'),
            '_apd_permissions' => __('Permissions JSON', 'asuka-product-designer'),
            '_apd_views' => __('Views JSON', 'asuka-product-designer'),
            '_apd_drawing_zones' => __('Drawing zones JSON', 'asuka-product-designer'),
            '_apd_fonts' => __('Fonts JSON', 'asuka-product-designer'),
            '_apd_upload' => __('Upload JSON', 'asuka-product-designer'),
            '_apd_colors' => __('Colors JSON', 'asuka-product-designer'),
            '_apd_pricing_rules' => __('Pricing rules JSON', 'asuka-product-designer'),
            '_apd_selection_menu' => __('Selection menu JSON', 'asuka-product-designer'),
            '_apd_ui' => __('UI JSON', 'asuka-product-designer'),
            '_apd_front_behavior' => __('Front behavior JSON', 'asuka-product-designer'),
            '_apd_mobile_behavior' => __('Mobile behavior JSON', 'asuka-product-designer'),
            '_apd_initial_document' => __('Initial document JSON', 'asuka-product-designer'),
            '_apd_initial_state' => __('Initial state JSON', 'asuka-product-designer'),
            default => $key,
        };
    }

    private function decodeMeta(string $value, array $fallback) : array
    {
        $decoded = json_decode($value, true);
        return is_array($decoded) ? $decoded : $fallback;
    }
}
