<?php

namespace WPSN\SEO;

defined('ABSPATH') || exit;

final class SchemaTypeLibrary
{
    /**
     * @return array<string,array{label:string,description:string,template:string}>
     */
    public static function presets(): array
    {
        $presets = [
            'faq' => [
                'label' => __('FAQ', 'wp-seo-next'),
                'description' => __('FAQPage with starter questions and answers. Replace the placeholder copy with your real FAQ content.', 'wp-seo-next'),
                'template' => <<<'JSON'
{
  "@type": "FAQPage",
  "@id": %permalink|suffix(#faq)|json%,
  "mainEntity": [
    {
      "@type": "Question",
      "name": "Add your first question here",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Add the answer here."
      }
    },
    {
      "@type": "Question",
      "name": "Add your second question here",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Add the answer here."
      }
    }
  ]
}
JSON,
            ],
            'howto' => [
                'label' => __('HowTo', 'wp-seo-next'),
                'description' => __('HowTo with starter steps. Good for tutorials, setup guides, and step-by-step instructions.', 'wp-seo-next'),
                'template' => <<<'JSON'
{
  "@type": "HowTo",
  "@id": %permalink|suffix(#howto)|json%,
  "name": %title|json%,
  "description": %excerpt|json%,
  "step": [
    {
      "@type": "HowToStep",
      "name": "Step 1",
      "text": "Describe the first step here."
    },
    {
      "@type": "HowToStep",
      "name": "Step 2",
      "text": "Describe the second step here."
    },
    {
      "@type": "HowToStep",
      "name": "Step 3",
      "text": "Describe the third step here."
    }
  ]
}
JSON,
            ],
            'event' => [
                'label' => __('Event', 'wp-seo-next'),
                'description' => __('Event with starter dates, venue, and offer placeholders. Replace every placeholder before publishing.', 'wp-seo-next'),
                'template' => <<<'JSON'
{
  "@type": "Event",
  "@id": %permalink|suffix(#event)|json%,
  "name": %title|json%,
  "description": %excerpt|json%,
  "startDate": "2026-04-01T19:00:00+00:00",
  "endDate": "2026-04-01T21:00:00+00:00",
  "eventStatus": "https://schema.org/EventScheduled",
  "eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode",
  "location": {
    "@type": "Place",
    "name": "Venue name",
    "address": {
      "@type": "PostalAddress",
      "streetAddress": "123 Main Street",
      "addressLocality": "City",
      "addressRegion": "Region",
      "postalCode": "12345",
      "addressCountry": "US"
    }
  },
  "offers": {
    "@type": "Offer",
    "url": %permalink|json%,
    "price": "49.00",
    "priceCurrency": "USD",
    "availability": "https://schema.org/InStock",
    "validFrom": "2026-03-15T10:00:00+00:00"
  }
}
JSON,
            ],
            'recipe' => [
                'label' => __('Recipe', 'wp-seo-next'),
                'description' => __('Recipe with starter ingredients and instructions. Replace timings, nutrition, and ingredients with real values.', 'wp-seo-next'),
                'template' => <<<'JSON'
{
  "@type": "Recipe",
  "@id": %permalink|suffix(#recipe)|json%,
  "name": %title|json%,
  "description": %excerpt|json%,
  "author": {
    "@type": "Person",
    "name": %author_name|json%
  },
  "datePublished": %date|json%,
  "prepTime": "PT15M",
  "cookTime": "PT30M",
  "totalTime": "PT45M",
  "recipeYield": "4 servings",
  "recipeCategory": "Dinner",
  "recipeCuisine": "Mediterranean",
  "recipeIngredient": [
    "1 ingredient",
    "2 ingredient",
    "3 ingredient"
  ],
  "recipeInstructions": [
    {
      "@type": "HowToStep",
      "text": "Describe the first cooking step here."
    },
    {
      "@type": "HowToStep",
      "text": "Describe the second cooking step here."
    }
  ]
}
JSON,
            ],
            'review' => [
                'label' => __('Review', 'wp-seo-next'),
                'description' => __('Review with rating placeholders. Use only when the page actually contains a visible review that matches the markup.', 'wp-seo-next'),
                'template' => <<<'JSON'
{
  "@type": "Review",
  "@id": %permalink|suffix(#review)|json%,
  "name": %title|json%,
  "reviewBody": %excerpt|json%,
  "author": {
    "@type": "Person",
    "name": %author_name|json%
  },
  "itemReviewed": {
    "@type": "Thing",
    "name": %title|json%
  },
  "reviewRating": {
    "@type": "Rating",
    "ratingValue": "5",
    "bestRating": "5",
    "worstRating": "1"
  }
}
JSON,
            ],
            'product' => [
                'label' => __('Product', 'wp-seo-next'),
                'description' => __('Product schema for affiliate landing pages, software offers, or other product pages that are not already covered by the plugin’s WooCommerce Product graph.', 'wp-seo-next'),
                'template' => <<<'JSON'
{
  "@type": "Product",
  "@id": %permalink|suffix(#affiliate-product)|json%,
  "name": %title|json%,
  "description": %excerpt|json%,
  "url": %permalink|json%,
  "brand": {
    "@type": "Brand",
    "name": "Brand name"
  },
  "sku": "sku-123",
  "offers": {
    "@type": "Offer",
    "url": %permalink|json%,
    "price": "49.00",
    "priceCurrency": "USD"
  }
}
JSON,
            ],
            'comparison' => [
                'label' => __('Comparison / ItemList', 'wp-seo-next'),
                'description' => __('ItemList schema for product roundups, “best of” pages, and affiliate comparison pages with multiple ranked products or comparison-table rows.', 'wp-seo-next'),
                'template' => <<<'JSON'
{
  "@type": "ItemList",
  "@id": %permalink|suffix(#comparison)|json%,
  "name": %title|json%,
  "description": %excerpt|json%,
  "itemListOrder": "https://schema.org/ItemListOrderAscending",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "name": "First product",
      "item": {
        "@type": "Product",
        "name": "First product",
        "url": %permalink|json%,
        "offers": {
          "@type": "Offer",
          "price": "49.00",
          "priceCurrency": "USD"
        }
      }
    },
    {
      "@type": "ListItem",
      "position": 2,
      "name": "Second product",
      "item": {
        "@type": "Product",
        "name": "Second product",
        "url": %permalink|json%,
        "offers": {
          "@type": "Offer",
          "price": "79.00",
          "priceCurrency": "USD"
        }
      }
    }
  ]
}
JSON,
            ],
            'service' => [
                'label' => __('Service', 'wp-seo-next'),
                'description' => __('Service schema for service pages. Replace provider, area served, and offer details to match the page.', 'wp-seo-next'),
                'template' => <<<'JSON'
{
  "@type": "Service",
  "@id": %permalink|suffix(#service)|json%,
  "name": %title|json%,
  "description": %excerpt|json%,
  "url": %permalink|json%,
  "provider": {
    "@type": "Organization",
    "name": %sitename|json%
  },
  "areaServed": {
    "@type": "AdministrativeArea",
    "name": "Primary service area"
  },
  "offers": {
    "@type": "Offer",
    "url": %permalink|json%,
    "priceCurrency": "USD",
    "price": "100.00"
  }
}
JSON,
            ],
        ];

        $presets = apply_filters('wpsn/schema/type_library/presets', $presets);
        if (!is_array($presets)) {
            return [];
        }

        $out = [];
        foreach ($presets as $slug => $preset) {
            $slug = sanitize_key((string) $slug);
            if ($slug === '' || !is_array($preset)) {
                continue;
            }

            $label = isset($preset['label']) ? trim((string) $preset['label']) : '';
            $description = isset($preset['description']) ? trim((string) $preset['description']) : '';
            $template = isset($preset['template']) ? SchemaCustomJsonLdResolver::sanitizeRaw((string) $preset['template']) : '';
            if ($label === '' || $template === '') {
                continue;
            }

            $out[$slug] = [
                'label' => $label,
                'description' => $description,
                'template' => $template,
            ];
        }

        return $out;
    }

    public static function renderPicker(string $targetId): void
    {
        $presets = self::presets();
        if (empty($presets)) {
            return;
        }

        echo '<div class="wpsn-schema-library-picker" data-target="' . esc_attr($targetId) . '" style="margin: 0 0 10px; padding: 12px; border: 1px solid #dcdcde; border-radius: 4px; background: #fff;">';
        echo '<p style="margin:0 0 8px;"><strong>' . esc_html__('Schema type library', 'wp-seo-next') . '</strong></p>';
        echo '<p class="description" style="margin:0 0 8px;">' . esc_html__('Pick a starter template for FAQ, HowTo, Event, Recipe, Review, Product, Comparison, or Service. Loading a starter replaces the current JSON-LD in the target field.', 'wp-seo-next') . '</p>';
        echo '<p style="margin:0 0 8px;">';
        echo '<select class="widefat wpsn-schema-library-select">';
        echo '<option value="">' . esc_html__('Choose a starter template…', 'wp-seo-next') . '</option>';
        foreach ($presets as $slug => $preset) {
            echo '<option value="' . esc_attr($slug) . '">' . esc_html((string) $preset['label']) . '</option>';
        }
        echo '</select>';
        echo '</p>';
        echo '<div class="wpsn-schema-library-preview" style="display:none; margin: 0 0 8px;">';
        echo '<p class="description wpsn-schema-library-preview-description" style="margin:0 0 6px;"></p>';
        echo '<pre class="wpsn-schema-library-preview-code" style="margin:0; padding:10px; max-height:180px; overflow:auto; background:#f6f7f7; border:1px solid #dcdcde; white-space:pre-wrap;"></pre>';
        echo '</div>';
        echo '<p style="margin:0;"><button type="button" class="button wpsn-schema-library-insert">' . esc_html__('Load starter template', 'wp-seo-next') . '</button></p>';
        echo '</div>';
    }

    public static function renderInlineScript(): void
    {
        static $rendered = false;
        if ($rendered) {
            return;
        }
        $rendered = true;

        $presets = [];
        foreach (self::presets() as $slug => $preset) {
            $presets[$slug] = [
                'label' => (string) ($preset['label'] ?? ''),
                'description' => (string) ($preset['description'] ?? ''),
                'template' => (string) ($preset['template'] ?? ''),
            ];
        }

        $payload = wp_json_encode($presets, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        if (!is_string($payload) || $payload === '') {
            return;
        }

        $replaceMessage = esc_js(__('Replace the current JSON-LD in this field with the selected starter template?', 'wp-seo-next'));
        ?>
        <script>
        (function () {
            var presets = <?php echo $payload; ?>;

            function updatePicker(picker) {
                var select = picker.querySelector('.wpsn-schema-library-select');
                var preview = picker.querySelector('.wpsn-schema-library-preview');
                var description = picker.querySelector('.wpsn-schema-library-preview-description');
                var code = picker.querySelector('.wpsn-schema-library-preview-code');
                if (!select || !preview || !description || !code) {
                    return;
                }

                var preset = presets[select.value] || null;
                if (!preset) {
                    preview.style.display = 'none';
                    description.textContent = '';
                    code.textContent = '';
                    return;
                }

                preview.style.display = '';
                description.textContent = preset.description || '';
                code.textContent = preset.template || '';
            }

            function bindPicker(picker) {
                if (!picker || picker.getAttribute('data-wpsn-schema-library-bound') === '1') {
                    return;
                }
                picker.setAttribute('data-wpsn-schema-library-bound', '1');

                var select = picker.querySelector('.wpsn-schema-library-select');
                var button = picker.querySelector('.wpsn-schema-library-insert');
                var targetId = picker.getAttribute('data-target') || '';
                if (!select || !button || !targetId) {
                    return;
                }

                select.addEventListener('change', function () {
                    updatePicker(picker);
                });

                button.addEventListener('click', function () {
                    var preset = presets[select.value] || null;
                    if (!preset) {
                        return;
                    }

                    var target = document.getElementById(targetId);
                    if (!target) {
                        return;
                    }

                    var current = (target.value || '').trim();
                    var incoming = (preset.template || '').trim();
                    if (current && current !== incoming && !window.confirm('<?php echo $replaceMessage; ?>')) {
                        return;
                    }

                    target.value = preset.template || '';
                    target.dispatchEvent(new Event('input', { bubbles: true }));
                    target.dispatchEvent(new Event('change', { bubbles: true }));
                });

                updatePicker(picker);
            }

            var pickers = document.querySelectorAll('.wpsn-schema-library-picker');
            for (var i = 0; i < pickers.length; i += 1) {
                bindPicker(pickers[i]);
            }
        }());
        </script>
        <?php
    }
}
