<?php
declare(strict_types=1);

/*
 * Orderly product SSR helper for PHP hosts.
 *
 * Deploy this file next to the built static shop output, including product.html.
 * The script rewrites clean product URLs to a real HTML response, injects
 * declarative SSR fallback content into <orderly-product-detail-page>, and then
 * lets the browser web component hydrate the live product view.
 *
 * Optional environment variables:
 * - ORDERLY_PRODUCT_TEMPLATE: path to built product.html. Defaults to ./product.html.
 * - ORDERLY_PRODUCT_ORIGIN: prefix for compact product slugs. Defaults to https://orderly.shop/.
 * - ORDERLY_PRODUCT_SNAPSHOT_ENDPOINT: internal JSON endpoint returning product snapshot data.
 * - ORDERLY_PRODUCT_SNAPSHOT_TIMEOUT: snapshot endpoint timeout in seconds. Defaults to 2.
 */

$shareUrl = orderly_product_share_url();
$snapshot = orderly_load_product_snapshot($shareUrl);
$templatePath = getenv('ORDERLY_PRODUCT_TEMPLATE') ?: __DIR__ . '/product.html';
$html = is_file($templatePath)
    ? file_get_contents($templatePath)
    : orderly_minimal_product_template();

if ($html === false) {
    http_response_code(500);
    header('Content-Type: text/plain; charset=UTF-8');
    echo 'Could not read product template.';
    exit;
}

$html = orderly_inject_product_page($html, $shareUrl, $snapshot);
$html = orderly_inject_meta($html, $shareUrl, $snapshot);

header('Content-Type: text/html; charset=UTF-8');
echo $html;

function orderly_product_share_url(): string
{
    $value = $_GET['url'] ?? '';
    if (!is_string($value) || $value === '') {
        $path = parse_url($_SERVER['REQUEST_URI'] ?? '', PHP_URL_PATH);
        $value = is_string($path) ? ltrim($path, '/') : '';
    }

    $value = trim(rawurldecode($value));
    if ($value === '') {
        return '';
    }

    if (preg_match('~^https?://~i', $value) === 1) {
        return $value;
    }

    $origin = getenv('ORDERLY_PRODUCT_ORIGIN') ?: 'https://orderly.shop/';
    return rtrim($origin, '/') . '/' . ltrim($value, '/');
}

function orderly_load_product_snapshot(string $shareUrl): ?array
{
    $endpoint = getenv('ORDERLY_PRODUCT_SNAPSHOT_ENDPOINT') ?: '';
    if ($endpoint === '' || $shareUrl === '') {
        return null;
    }

    $separator = str_contains($endpoint, '?') ? '&' : '?';
    $url = $endpoint . $separator . 'url=' . rawurlencode($shareUrl);
    $timeout = (float) (getenv('ORDERLY_PRODUCT_SNAPSHOT_TIMEOUT') ?: '2');
    $context = stream_context_create([
        'http' => [
            'method' => 'GET',
            'timeout' => $timeout,
            'header' => "Accept: application/json\r\n",
        ],
    ]);
    $json = @file_get_contents($url, false, $context);
    if ($json === false || $json === '') {
        return null;
    }

    $data = json_decode($json, true);
    return is_array($data) ? $data : null;
}

function orderly_inject_product_page(string $html, string $shareUrl, ?array $snapshot): string
{
    $fallback = orderly_render_product_fallback($shareUrl, $snapshot);
    $component = '<orderly-product-detail-page data-orderly-ssr share-url="' . orderly_e($shareUrl) . '">' . "\n"
        . $fallback . "\n"
        . '</orderly-product-detail-page>';

    $result = preg_replace(
        '~<orderly-product-detail-page\b[^>]*>.*?</orderly-product-detail-page>~is',
        $component,
        $html,
        1,
        $count
    );

    if ($result !== null && $count > 0) {
        return $result;
    }

    return str_replace('</body>', $component . "\n</body>", $html);
}

function orderly_render_product_fallback(string $shareUrl, ?array $snapshot): string
{
    $title = orderly_snapshot_value($snapshot, 'title') ?: orderly_title_from_share_url($shareUrl);
    $brand = orderly_snapshot_value($snapshot, 'brand');
    $price = orderly_snapshot_value($snapshot, 'priceText');
    $description = orderly_snapshot_value($snapshot, 'description');
    $imageUrl = orderly_sized_image_url(orderly_snapshot_value($snapshot, 'imageUrl'), 900, 900);
    $titleMarkup = orderly_e($title);

    $image = $imageUrl !== ''
        ? '<div class="orderly-ssr-product-detail__image"><img src="' . orderly_e($imageUrl) . '" alt="' . orderly_e($title) . '" loading="eager"></div>'
        : '';
    $brandMarkup = $brand !== '' ? '<p data-orderly-field="brand">' . orderly_e($brand) . '</p>' : '';
    $priceMarkup = $price !== '' ? '<p data-orderly-field="price">' . orderly_e($price) . '</p>' : '';
    $descriptionMarkup = $description !== '' ? '<p data-orderly-field="description">' . orderly_e($description) . '</p>' : '';

    return <<<HTML
      <article slot="content-before" class="orderly-ssr-product-detail" data-orderly-ssr-fallback data-orderly-product>
        {$image}
        <section class="orderly-ssr-product-detail__text">
          {$brandMarkup}
          <h1 data-orderly-field="title">{$titleMarkup}</h1>
          {$priceMarkup}
          {$descriptionMarkup}
        </section>
      </article>
HTML;
}

function orderly_inject_meta(string $html, string $shareUrl, ?array $snapshot): string
{
    $title = orderly_snapshot_value($snapshot, 'title') ?: orderly_title_from_share_url($shareUrl);
    $description = orderly_snapshot_value($snapshot, 'description');
    $imageUrl = orderly_sized_image_url(orderly_snapshot_value($snapshot, 'imageUrl'), 900, 900);

    $html = preg_replace('~<title>.*?</title>~is', '<title>' . orderly_e($title) . '</title>', $html, 1) ?? $html;
    $html = orderly_upsert_head_tag($html, '~<meta\s+name=["\']description["\'][^>]*>~i', '<meta name="description" content="' . orderly_e($description ?: $title) . '">');
    $html = orderly_upsert_head_tag($html, '~<link\s+rel=["\']canonical["\'][^>]*>~i', '<link rel="canonical" href="' . orderly_e($shareUrl) . '">');
    $html = orderly_upsert_head_tag($html, '~<meta\s+property=["\']og:title["\'][^>]*>~i', '<meta property="og:title" content="' . orderly_e($title) . '">');
    $html = orderly_upsert_head_tag($html, '~<meta\s+property=["\']og:url["\'][^>]*>~i', '<meta property="og:url" content="' . orderly_e($shareUrl) . '">');
    if ($description !== '') {
        $html = orderly_upsert_head_tag($html, '~<meta\s+property=["\']og:description["\'][^>]*>~i', '<meta property="og:description" content="' . orderly_e($description) . '">');
    }
    if ($imageUrl !== '') {
        $html = orderly_upsert_head_tag($html, '~<meta\s+property=["\']og:image["\'][^>]*>~i', '<meta property="og:image" content="' . orderly_e($imageUrl) . '">');
    }
    return $html;
}

function orderly_upsert_head_tag(string $html, string $pattern, string $tag): string
{
    if (preg_match($pattern, $html) === 1) {
        return preg_replace($pattern, $tag, $html, 1) ?? $html;
    }
    return str_replace('</head>', '    ' . $tag . "\n  </head>", $html);
}

function orderly_snapshot_value(?array $snapshot, string $key): string
{
    $value = $snapshot[$key] ?? '';
    return is_scalar($value) ? trim((string) $value) : '';
}

function orderly_sized_image_url(string $url, int $width, int $height): string
{
    if ($url === '' || stripos($url, 'data:') === 0) {
        return $url;
    }
    $hash = '';
    $hashPos = strpos($url, '#');
    if ($hashPos !== false) {
        $hash = substr($url, $hashPos);
        $url = substr($url, 0, $hashPos);
    }
    $query = [];
    $queryPos = strpos($url, '?');
    $path = $url;
    if ($queryPos !== false) {
        $path = substr($url, 0, $queryPos);
        parse_str(substr($url, $queryPos + 1), $query);
    }
    $query['width'] = (string) $width;
    $query['height'] = (string) $height;
    return $path . '?' . http_build_query($query) . $hash;
}

function orderly_title_from_share_url(string $shareUrl): string
{
    $path = parse_url($shareUrl, PHP_URL_PATH);
    $name = is_string($path) ? basename($path, '.html') : 'Produkt';
    $name = preg_replace('~-[a-z0-9]{8,}$~i', '', $name) ?? $name;
    $name = str_replace(['-', '_'], ' ', $name);
    return ucwords($name ?: 'Produkt');
}

function orderly_minimal_product_template(): string
{
    return <<<'HTML'
<!doctype html>
<html lang="da">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Produkt</title>
    <script src="/node_modules/@orderlyshop/web-components/dist/browser/orderly-web-components.global.js"></script>
    <script>
      OrderlyWebComponents.configureShop({
        defaultShop: { baseUrl: "https://service.orderly.shop" }
      });
    </script>
  </head>
  <body></body>
</html>
HTML;
}

function orderly_e(string $value): string
{
    return htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}
