<?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\PostTypes\TemplatePostType;
use APD\Support\RequestData;

defined('ABSPATH') || exit;

class TemplateEditor
{
    private array $fields = [
        '_apd_mode' => ['label' => 'Mode', 'type' => 'select', 'options' => ['standalone', 'customer', 'admin']],
        '_apd_theme' => ['label' => 'Theme JSON', 'type' => 'json', 'rows' => 12],
        '_apd_layout' => ['label' => 'Layout JSON', 'type' => 'json', 'rows' => 12],
        '_apd_modules' => ['label' => 'Modules JSON', 'type' => 'json', 'rows' => 16],
        '_apd_permissions' => ['label' => 'Permissions JSON', 'type' => 'json', 'rows' => 12],
        '_apd_views' => ['label' => 'Views JSON', 'type' => 'json', 'rows' => 14],
        '_apd_drawing_zones' => ['label' => 'Drawing zones JSON', 'type' => 'json', 'rows' => 12],
        '_apd_fonts' => ['label' => 'Fonts JSON', 'type' => 'json', 'rows' => 10],
        '_apd_upload' => ['label' => 'Upload JSON', 'type' => 'json', 'rows' => 10],
        '_apd_colors' => ['label' => 'Colors JSON', 'type' => 'json', 'rows' => 10],
        '_apd_pricing_rules' => ['label' => 'Pricing rules JSON', 'type' => 'json', 'rows' => 12],
        '_apd_selection_menu' => ['label' => 'Selection menu JSON', 'type' => 'json', 'rows' => 8],
        '_apd_ui' => ['label' => 'UI JSON', 'type' => 'json', 'rows' => 8],
        '_apd_front_behavior' => ['label' => 'Front behavior JSON', 'type' => 'json', 'rows' => 8],
        '_apd_mobile_behavior' => ['label' => 'Mobile behavior JSON', 'type' => 'json', 'rows' => 8],
        '_apd_initial_document' => ['label' => 'Initial document JSON', 'type' => 'json', 'rows' => 14],
        '_apd_initial_state' => ['label' => 'Initial state JSON', 'type' => 'json', 'rows' => 14],
    ];

    public function registerMetaBoxes() : void
    {
        add_meta_box('apd_template_builder', __('Template builder', 'asuka-product-designer'), [$this, 'renderBuilder'], TemplatePostType::TYPE, 'normal', 'high');
        add_meta_box('apd_template_modules', __('Template modules', 'asuka-product-designer'), [$this, 'renderModulesBox'], TemplatePostType::TYPE, 'side', 'high');
    }

    public function save(int $postId) : void
    {
        $post = RequestData::post();
        if (! isset($post['apd_template_nonce']) || ! wp_verify_nonce(sanitize_text_field((string) $post['apd_template_nonce']), 'apd_save_template')) {
            return;
        }
        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
            return;
        }
        if (! current_user_can('edit_post', $postId)) {
            return;
        }
        foreach ($this->fields as $key => $field) {
            $raw = $post[$key] ?? null;
            if ($raw === null) {
                continue;
            }
            $value = is_string($raw) ? $raw : '';
            if ($field['type'] === 'json') {
                $normalized = $this->sanitizeJson($value);
                if ($normalized === null) {
                    continue;
                }
                $this->updateJsonPostMeta($postId, $key, $normalized);
                continue;
            }

            $value = sanitize_text_field($value);
            update_post_meta($postId, $key, $value);
        }
    }

    public function renderBuilder(\WP_Post $post) : void
    {
        wp_nonce_field('apd_save_template', 'apd_template_nonce');
        ?>
        <div class="apd-builder-page apd-template-builder-page" data-apd-template-editor="1">
            <div class="apd-builder-stage-shell js-apd-live-preview" data-post-id="<?php echo esc_attr((string) $post->ID); ?>">
                <div class="apd-preview-stage apd-builder-stage" id="apd-template-preview-<?php echo esc_attr((string) $post->ID); ?>"></div>
                <div class="apd-visually-hidden">
                    <select class="js-apd-starter-template" aria-hidden="true" tabindex="-1">
                        <option value="blank"><?php esc_html_e('Blank starter', 'asuka-product-designer'); ?></option>
                    </select>
                    <input type="text" class="js-apd-preview-height" value="820px" aria-hidden="true" tabindex="-1">
                    <button type="button" class="js-apd-refresh-preview" aria-hidden="true" tabindex="-1"><?php esc_html_e('Refresh canvas', 'asuka-product-designer'); ?></button>
                    <span class="js-apd-preview-status" aria-hidden="true"><?php esc_html_e('Canvas ready', 'asuka-product-designer'); ?></span>
                </div>
            </div>
            <div class="apd-visually-hidden apd-advanced-fields">
                <?php foreach (array_keys($this->fields) as $key) : ?>
                    <?php $this->renderHiddenField($post->ID, $key); ?>
                <?php endforeach; ?>
            </div>
        </div>
        <?php
    }

    public function renderModulesBox(\WP_Post $post) : void
    {
        $layout = $this->decodeJsonString((string) get_post_meta($post->ID, '_apd_layout', true));
        $modules = $this->moduleDefinitions();
        echo '<div class="apd-template-modules" data-apd-template-modules="1">';
        echo '<p>' . esc_html__('Create a reusable frontend menu template. The custom product editor stays independent; the selected template is only applied on the frontend runtime.', 'asuka-product-designer') . '</p>';
        echo '<p class="description">' . esc_html__('Choose the visible menus, their zone, label, type, and icon. Kind is derived automatically from the selected module key.', 'asuka-product-designer') . '</p>';
        foreach ($modules as $key => $label) {
            $item = $this->findLayoutItem($layout, $key);
            $enabled = is_array($item);
            $zone = (string) ($item['zone'] ?? $this->defaultZoneFor($key));
            $type = $this->normalizeDisplayType((string) ($item['type'] ?? 'floating'));
            $itemLabel = (string) ($item['label'] ?? $label);
            $icon = (string) ($item['icon'] ?? $this->defaultIconFor($key));
            $iconMode = $this->looksLikeImageUrl($icon) ? 'image' : 'text';
            $iconText = $iconMode === 'text' ? $icon : '';
            $iconImage = $iconMode === 'image' ? $icon : '';
            echo '<details class="apd-template-module"' . ($enabled ? ' open' : '') . '>';
            echo '<summary><strong>' . esc_html($label) . '</strong></summary>';
            echo '<div class="apd-template-module__body" data-apd-template-row="' . esc_attr($key) . '">';
            echo '<label class="apd-filter-check"><input type="checkbox" data-apd-template-enabled value="1" ' . checked($enabled, true, false) . '> <span>' . esc_html__('Enabled', 'asuka-product-designer') . '</span></label>';
            echo '<label class="apd-field"><span>' . esc_html__('Label', 'asuka-product-designer') . '</span><input type="text" data-apd-template-label value="' . esc_attr($itemLabel) . '"></label>';
            echo '<label class="apd-field"><span>' . esc_html__('Zone', 'asuka-product-designer') . '</span><select data-apd-template-zone>';
            foreach (['left','top','right','bottom'] as $zoneOption) {
                echo '<option value="' . esc_attr($zoneOption) . '" ' . selected($zone, $zoneOption, false) . '>' . esc_html($this->translateZoneOption((string) $zoneOption)) . '</option>';
            }
            echo '</select></label>';
            echo '<label class="apd-field"><span>' . esc_html__('Type', 'asuka-product-designer') . '</span><select data-apd-template-type>';
            foreach (['floating','drawer','modal','inline','popover','overlay','panel'] as $typeOption) {
                echo '<option value="' . esc_attr($typeOption) . '" ' . selected($type, $typeOption, false) . '>' . esc_html($this->translateDisplayType((string) $typeOption)) . '</option>';
            }
            echo '</select></label>';
            echo '<label class="apd-field"><span>' . esc_html__('Icon mode', 'asuka-product-designer') . '</span><select data-apd-template-icon-mode>';
            echo '<option value="text" ' . selected($iconMode, 'text', false) . '>' . esc_html__('Text / icon key', 'asuka-product-designer') . '</option>';
            echo '<option value="image" ' . selected($iconMode, 'image', false) . '>' . esc_html__('Media image URL', 'asuka-product-designer') . '</option>';
            echo '</select></label>';
            echo '<label class="apd-field"><span>' . esc_html__('Icon text', 'asuka-product-designer') . '</span><input type="text" data-apd-template-icon-text value="' . esc_attr($iconText) . '"></label>';
            echo '<div class="apd-media-field" data-apd-media-field="1">';
            echo '<label class="apd-field"><span>' . esc_html__('Icon image', 'asuka-product-designer') . '</span><input type="url" data-apd-template-icon-image value="' . esc_attr($iconImage) . '"></label>';
            echo '<div class="apd-inline-actions"><button type="button" class="button js-apd-media-pick" data-apd-media-open="1" data-apd-media-type="image">' . esc_html__('Select image', 'asuka-product-designer') . '</button><button type="button" class="button-link js-apd-media-clear" data-apd-media-clear="1">' . esc_html__('Clear', 'asuka-product-designer') . '</button></div>';
            echo '</div>';
            echo '</div>';
            echo '</details>';
        }
        echo '<p class="description">' . esc_html__('The generated layout JSON is saved with the template and loaded on the frontend when this template is selected on a custom product.', 'asuka-product-designer') . '</p>';
        echo '</div>';
    }

    private function renderHiddenField(int $postId, string $key) : void
    {
        $field = $this->fields[$key];
        $value = (string) get_post_meta($postId, $key, true);
        if ($field['type'] === 'select') {
            echo '<select name="' . esc_attr($key) . '" hidden>';
            foreach ($field['options'] as $option) {
                echo '<option value="' . esc_attr($option) . '" ' . selected($value ?: 'standalone', $option, false) . '>' . esc_html($this->translateModeOption((string) $option)) . '</option>';
            }
            echo '</select>';
            return;
        }
        echo '<textarea class="apd-codearea" name="' . esc_attr($key) . '" rows="' . esc_attr((string) ($field['rows'] ?? 8)) . '" hidden>' . esc_textarea($value) . '</textarea>';
    }

    private function sanitizeJson(string $value) : ?string
    {
        $trimmed = trim($value);
        if ($trimmed === '') {
            return '';
        }
        $decoded = json_decode($trimmed, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            return null;
        }
        $encoded = wp_json_encode($decoded, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        return is_string($encoded) ? $encoded : null;
    }

    private function updateJsonPostMeta(int $postId, string $key, string $json) : void
    {
        update_post_meta($postId, $key, wp_slash($json));
    }

    private function decodeJsonString(string $value) : array
    {
        $trimmed = trim($value);
        if ($trimmed === '') {
            return [];
        }
        $decoded = json_decode($trimmed, true);
        return is_array($decoded) ? $decoded : [];
    }

    private function findLayoutItem(array $layout, string $key) : ?array
    {
        foreach (['left', 'top', 'right', 'bottom'] as $zone) {
            $items = is_array($layout[$zone]['items'] ?? null) ? $layout[$zone]['items'] : [];
            foreach ($items as $item) {
                if (! is_array($item)) {
                    continue;
                }
                $id = (string) ($item['id'] ?? '');
                $kind = (string) ($item['kind'] ?? '');
                if ($id === $key || $kind === $this->kindFor($key)) {
                    return $item;
                }
            }
        }
        return null;
    }

    private function defaultZoneFor(string $key) : string
    {
        return in_array($key, ['magnifier', 'ruler', 'zoom', 'download'], true) ? 'top' : (in_array($key, ['layers'], true) ? 'right' : 'left');
    }

    private function defaultIconFor(string $key) : string
    {
        return match ($key) {
            'designs' => 'brush',
            'text' => 'text',
            'images' => 'images',
            'shapes' => 'customize',
            'layers' => 'layers',
            'magnifier' => 'magnifying-glass',
            'ruler' => 'ruler',
            'zoom' => 'zoom',
            'download' => 'download',
            default => $key,
        };
    }

    private function looksLikeImageUrl(string $value) : bool
    {
        return (bool) preg_match('#^(https?:)?//#', $value) || str_starts_with($value, '/');
    }

    private function normalizeDisplayType(string $value) : string
    {
        if (str_starts_with($value, 'panel-')) {
            return 'panel';
        }
        return in_array($value, ['floating','drawer','modal','inline','popover','overlay','panel'], true) ? $value : 'floating';
    }

    private function kindFor(string $key) : string
    {
        return $key === 'images' ? 'image' : $key;
    }



    private function translateModeOption(string $mode) : string
    {
        return match ($mode) {
            'standalone' => __('Standalone', 'asuka-product-designer'),
            'customer' => __('Customer', 'asuka-product-designer'),
            'admin' => __('Admin', 'asuka-product-designer'),
            default => $mode,
        };
    }

    private function translateZoneOption(string $zone) : string
    {
        return match ($zone) {
            'left' => __('Left', 'asuka-product-designer'),
            'right' => __('Right', 'asuka-product-designer'),
            'top' => __('Top', 'asuka-product-designer'),
            'bottom' => __('Bottom', 'asuka-product-designer'),
            default => $zone,
        };
    }

    private function translateDisplayType(string $type) : string
    {
        return match ($type) {
            'floating' => __('Floating', 'asuka-product-designer'),
            'drawer' => __('Drawer', 'asuka-product-designer'),
            'modal' => __('Modal', 'asuka-product-designer'),
            'inline' => __('Inline', 'asuka-product-designer'),
            'popover' => __('Popover', 'asuka-product-designer'),
            'overlay' => __('Overlay', 'asuka-product-designer'),
            'panel' => __('Panel', 'asuka-product-designer'),
            default => $type,
        };
    }
    private function moduleDefinitions() : array
    {
        return [
            'views' => __('Views', 'asuka-product-designer'),
            'designs' => __('Designs', 'asuka-product-designer'),
            'text' => __('Text', 'asuka-product-designer'),
            'images' => __('Images', 'asuka-product-designer'),
            'shapes' => __('Shapes', 'asuka-product-designer'),
            'layers' => __('Layers', 'asuka-product-designer'),
            'zoom' => __('Zoom', 'asuka-product-designer'),
            'download' => __('Download', 'asuka-product-designer'),
            'magnifier' => __('Magnifier', 'asuka-product-designer'),
            'ruler' => __('Ruler', 'asuka-product-designer'),
            'history' => __('History', 'asuka-product-designer'),
            'state' => __('State', 'asuka-product-designer'),
            'pricing' => __('Pricing', 'asuka-product-designer'),
            'pricingRules' => __('Pricing rules', 'asuka-product-designer'),
            'elements' => __('Elements', 'asuka-product-designer'),
            'product-parameters' => __('Product parameters', 'asuka-product-designer'),
            'assembly' => __('Spatial assembly', 'asuka-product-designer'),
            'drawingAreas' => __('Drawing areas', 'asuka-product-designer'),
            'marker' => __('Marker', 'asuka-product-designer'),
            'colors' => __('Colors', 'asuka-product-designer'),
            'studio' => __('Studio', 'asuka-product-designer'),
            'font-family' => __('Font family', 'asuka-product-designer'),
            'text-formatting' => __('Text formatting', 'asuka-product-designer'),
            'text-curve' => __('Text curve', 'asuka-product-designer'),
            'transform' => __('Transform', 'asuka-product-designer'),
            'upload-image' => __('Upload image', 'asuka-product-designer'),
            'pixabay-image' => __('Pixabay image', 'asuka-product-designer'),
            'pexels-image' => __('Pexels image', 'asuka-product-designer'),
            'facebook-image' => __('Facebook image', 'asuka-product-designer'),
            'qrcode-image' => __('QR Code image', 'asuka-product-designer'),
        ];
    }
}
