<?php
/**
 * Full-screen 3D floor visualizer page.
 *
 * Renders entirely outside the active theme (no get_header()/get_footer())
 * because the visualizer UI is a self-contained full-viewport app.
 * A <base href> pointing at the plugin's root keeps all relative paths in
 * app.js / config.json resolving correctly.
 *
 * Accessed via: ?tilvora_configure=<project_id>
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

add_action( 'template_redirect', 'tilvora_maybe_render_configurator_page' );

function tilvora_maybe_render_configurator_page() {
	if ( ! get_query_var( TILVORA_QUERY_VAR ) ) {
		return;
	}

	$project_id = absint( get_query_var( TILVORA_QUERY_VAR ) );

	if ( ! $project_id || ! tilvora_is_enabled_for_project( $project_id ) ) {
		wp_die(
			esc_html__( 'This visualizer link is not valid.', 'tilvora-3d-flooring-visualizer' ),
			'',
			[ 'response' => 404 ]
		);
	}

	tilvora_render_configurator_html( $project_id );
	exit;
}

function tilvora_register_configurator_assets( $base_url ) {
	wp_enqueue_style( 'tilvora-configurator', $base_url . 'assets/css/style.css', [], TILVORA_VERSION );

	// Import map — must be in <head> before any module script.
	// Uses a stub src file so WordPress outputs a real <script> tag and fires
	// the script_loader_tag filter, which replaces it with the importmap.
	// Paths must be absolute: importmap URLs resolve against the document URL,
	// not the plugin directory, so relative paths would break on any WP page.
	$importmap = wp_json_encode( [
		'imports' => [
			'three'         => $base_url . 'assets/js/three/build/three.module.min.js',
			'three/addons/' => $base_url . 'assets/js/three/examples/jsm/',
		],
	] );
	wp_register_script( 'tilvora-importmap', $base_url . 'assets/js/importmap-stub.js', [], TILVORA_VERSION, false );
	wp_enqueue_script( 'tilvora-importmap' );

	wp_enqueue_script( 'tilvora-configurator-app', $base_url . 'assets/js/app.js', [], TILVORA_VERSION, true );
	wp_script_add_data( 'tilvora-configurator-app', 'type', 'module' );

	wp_enqueue_script( 'tilvora-quote-modal', $base_url . 'assets/js/quote-modal.js', [], TILVORA_VERSION, true );

	add_filter( 'script_loader_tag', function ( $tag, $handle ) use ( $importmap ) {
		if ( 'tilvora-importmap' === $handle ) {
			return '<script type="importmap">' . $importmap . "</script>\n";
		}
		if ( 'tilvora-configurator-app' === $handle && false === strpos( $tag, 'type=' ) ) {
			$tag = str_replace( '<script ', '<script type="module" ', $tag );
		}
		return $tag;
	}, 10, 2 );
}

function tilvora_render_configurator_html( $project_id ) {
	$base_url        = trailingslashit( TILVORA_PLUGIN_URL );
	$project_title   = get_the_title( $project_id );
	$config_feed_url = tilvora_get_config_feed_url( $project_id );
	$back_url        = home_url( '/' );

	tilvora_register_configurator_assets( $base_url );

	$ajax_data = [
		'ajaxUrl'      => admin_url( 'admin-ajax.php' ),
		'quoteNonce'   => wp_create_nonce( 'tilvora_quote_request' ),
		'projectId'    => $project_id,
		'backUrl'      => $back_url,
		'materialsUrl' => tilvora_get_materials_feed_url(),
	];

	$config_feed_url_js = wp_json_encode( $config_feed_url );

	wp_add_inline_script( 'tilvora-configurator-app', 'window.configuratorAjax = ' . wp_json_encode( $ajax_data ) . ';', 'before' );

	$loader_timeout_script = 'window._batforgeBootTimeout = setTimeout(function () {' . "\n"
		. "\tvar loader = document.getElementById('loader');" . "\n"
		. "\tif (loader && !loader.classList.contains('out')) {" . "\n"
		. "\t\tdocument.getElementById('loader-spinner').style.display = 'none';" . "\n"
		. "\t\tdocument.getElementById('loader-text').style.display = 'none';" . "\n"
		. "\t\tdocument.getElementById('loader-error').style.display = 'flex';" . "\n"
		. "\t}" . "\n"
		. '}, 60000);';
	wp_add_inline_script( 'tilvora-configurator-app', $loader_timeout_script, 'before' );

	$ui_text_script = "(function () {" . "\n"
		. "\tfetch(" . $config_feed_url_js . ")" . "\n"
		. "\t\t.then(function (r) { return r.json(); })" . "\n"
		. "\t\t.then(function (cfg) {" . "\n"
		. "\t\t\tvar t = cfg && cfg.uiText;" . "\n"
		. "\t\t\tif (!t) return;" . "\n"
		. "\t\t\tvar map = {" . "\n"
		. "\t\t\t\t'ui-brand':           t.brand," . "\n"
		. "\t\t\t\t'ui-loader-brand':    t.brand," . "\n"
		. "\t\t\t\t'ui-subtitle':        t.subtitle," . "\n"
		. "\t\t\t\t'ui-reset-view':      t.resetView," . "\n"
		. "\t\t\t\t'ui-export-png':      t.exportPng," . "\n"
		. "\t\t\t\t'ui-add-to-cart':     t.addToCart," . "\n"
		. "\t\t\t\t'ui-reset-all':       t.resetAll," . "\n"
		. "\t\t\t\t'ui-total-price-label': t.totalPriceLabel" . "\n"
		. "\t\t\t};" . "\n"
		. "\t\t\tObject.keys(map).forEach(function (id) {" . "\n"
		. "\t\t\t\tvar val = map[id]; var el = document.getElementById(id);" . "\n"
		. "\t\t\t\tif (el && val) el.textContent = val;" . "\n"
		. "\t\t\t});" . "\n"
		. "\t\t}).catch(function () {});" . "\n"
		. '})();';
	wp_add_inline_script( 'tilvora-configurator-app', $ui_text_script, 'before' );

	$theme_toggle_script = "(function () {" . "\n"
		. "\tvar KEY = 'noor-theme';" . "\n"
		. "\tvar root = document.documentElement;" . "\n"
		. "\tvar btn = document.getElementById('btn-theme-toggle');" . "\n"
		. "\tvar moonIcon = document.getElementById('theme-icon-moon');" . "\n"
		. "\tvar sunIcon = document.getElementById('theme-icon-sun');" . "\n\n"
		. "\tfunction applyTheme(theme) {" . "\n"
		. "\t\tif (theme === 'light') {" . "\n"
		. "\t\t\troot.setAttribute('data-theme', 'light');" . "\n"
		. "\t\t\tmoonIcon.style.display = 'none'; sunIcon.style.display = '';" . "\n"
		. "\t\t\tbtn.title = 'Switch to dark theme';" . "\n"
		. "\t\t} else {" . "\n"
		. "\t\t\troot.removeAttribute('data-theme');" . "\n"
		. "\t\t\tmoonIcon.style.display = ''; sunIcon.style.display = 'none';" . "\n"
		. "\t\t\tbtn.title = 'Switch to light theme';" . "\n"
		. "\t\t}" . "\n"
		. "\t}" . "\n\n"
		. "\tvar saved = null;" . "\n"
		. "\ttry { saved = localStorage.getItem(KEY); } catch (e) {}" . "\n"
		. "\tapplyTheme(saved === 'light' ? 'light' : 'dark');" . "\n\n"
		. "\tbtn.addEventListener('click', function () {" . "\n"
		. "\t\tvar next = root.getAttribute('data-theme') === 'light' ? 'dark' : 'light';" . "\n"
		. "\t\tapplyTheme(next);" . "\n"
		. "\t\ttry { localStorage.setItem(KEY, next); } catch (e) {}" . "\n"
		. "\t});" . "\n"
		. '})();';
	wp_add_inline_script( 'tilvora-configurator-app', $theme_toggle_script, 'before' );

	$config_url_rewrite_script = "(function () {" . "\n"
		. "\ttry {" . "\n"
		. "\t\tvar u = new URL(window.location.href);" . "\n"
		. "\t\tu.searchParams.set('config', " . $config_feed_url_js . ");" . "\n"
		. "\t\twindow.history.replaceState(null, '', u.toString());" . "\n"
		. "\t} catch (e) {}" . "\n"
		. '})();';
	wp_add_inline_script( 'tilvora-configurator-app', $config_url_rewrite_script, 'before' );
	?>
<!DOCTYPE html>
<html lang="<?php echo esc_attr( get_locale() ); ?>">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title><?php /* translators: %s: project title */ echo esc_html( sprintf( __( 'Design — %s', 'tilvora-3d-flooring-visualizer' ), $project_title ) ); ?></title>

  <base href="<?php echo esc_url( $base_url ); ?>" />

  <?php wp_print_styles( [ 'tilvora-configurator' ] ); ?>
  <?php wp_print_scripts( [ 'tilvora-importmap' ] ); ?>

  <link rel="modulepreload" href="assets/js/three/build/three.module.min.js" />
  <link rel="modulepreload" href="assets/js/three/examples/jsm/controls/OrbitControls.js" />
  <link rel="modulepreload" href="assets/js/three/examples/jsm/loaders/GLTFLoader.js" />
  <link rel="modulepreload" href="assets/js/three/examples/jsm/loaders/DRACOLoader.js" />
  <link rel="preload" href="<?php echo esc_url( $config_feed_url ); ?>" as="fetch" crossorigin="anonymous" />
</head>
<body>

  <canvas id="canvas"></canvas>

  <div id="drop-overlay">
    <div class="noor-drop-msg">
      <svg width="52" height="52" viewBox="0 0 52 52" fill="none">
        <rect x="6" y="6" width="40" height="40" rx="10" stroke="currentColor" stroke-width="2.5"/>
        <path d="M26 16v20M18 28l8-8 8 8" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
      </svg>
      <strong>Drop .glb file to load</strong>
      <span>Draco compression supported</span>
    </div>
  </div>

  <div id="loader">
    <div class="noor-loader-brand" id="ui-loader-brand">Tilvora</div>
    <div class="noor-spinner" id="loader-spinner"></div>
    <span class="noor-loader-text" id="loader-text">Initialising 3D Scene…</span>
    <div class="noor-loader-error" id="loader-error" style="display:none">
      <svg width="32" height="32" viewBox="0 0 32 32" fill="none" style="color:#fbbf24;margin-bottom:4px">
        <circle cx="16" cy="16" r="14" stroke="currentColor" stroke-width="2"/>
        <path d="M16 9v9M16 22v1.5" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"/>
      </svg>
      <p class="noor-loader-err-title">Failed to load 3D engine</p>
      <div class="noor-loader-err-steps">
        <p>Please refresh the page. If the issue continues, contact us so we can take a look.</p>
      </div>
    </div>
  </div>

  <!-- ── TOP BAR ── -->
  <header class="noor-topbar">
    <div class="noor-topbar-left">
      <a href="<?php echo esc_url( $back_url ); ?>" class="noor-logo" style="text-decoration:none;color:inherit;">
        <span id="ui-brand">Tilvora</span>
      </a>
      <div class="noor-topbar-sep"></div>
      <span class="noor-topbar-sub" id="ui-subtitle"><?php echo esc_html( $project_title ); ?></span>
    </div>
    <div class="noor-topbar-right">
      <button class="noor-btn noor-btn-ghost" id="btn-reset-cam">
        <svg width="13" height="13" viewBox="0 0 13 13" fill="none">
          <path d="M2 6.5C2 4.01 4.01 2 6.5 2C7.76 2 8.9 2.5 9.73 3.3" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/>
          <path d="M11 6.5C11 8.99 8.99 11 6.5 11C5.24 11 4.1 10.5 3.27 9.7" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/>
          <path d="M9.5 1.5l.23 1.8-1.73.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/>
          <path d="M3.5 11.5l-.23-1.8 1.73-.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/>
        </svg>
        <span id="ui-reset-view">Reset View</span>
      </button>
      <button class="noor-btn noor-btn-ghost" id="btn-theme-toggle" title="Switch to light theme" aria-label="Toggle light/dark theme">
        <svg id="theme-icon-moon" width="16" height="16" viewBox="0 0 13 13" fill="none">
          <path d="M10.8 7.6A5 5 0 1 1 5.4 2.2a4.1 4.1 0 0 0 5.4 5.4z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/>
        </svg>
        <svg id="theme-icon-sun" width="16" height="16" viewBox="0 0 13 13" fill="none" style="display:none">
          <circle cx="6.5" cy="6.5" r="2.6" stroke="currentColor" stroke-width="1.3"/>
          <path d="M6.5 0.8v1.6M6.5 10.6v1.6M0.8 6.5h1.6M10.6 6.5h1.6M2.4 2.4l1.1 1.1M9.5 9.5l1.1 1.1M2.4 10.6l1.1-1.1M9.5 3.5l1.1-1.1" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/>
        </svg>
      </button>
      <div class="noor-topbar-sep"></div>
      <button class="noor-btn noor-btn-primary" id="btn-export">
        <svg width="13" height="13" viewBox="0 0 13 13" fill="none">
          <path d="M6.5 1.5v7M6.5 8.5L4 6M6.5 8.5L9 6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
          <path d="M1.5 10.5v1h10v-1" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
        </svg>
        <span id="ui-export-png">Export PNG</span>
      </button>
    </div>
  </header>

  <!-- ════════════════ PANEL ════════════════ -->
  <aside class="noor-panel" id="panel">

    <div class="noor-panel-handle" id="panel-handle">
      <div class="noor-handle-bar"></div>
    </div>

    <nav class="noor-tabs" id="tab-nav"></nav>

    <div class="noor-panel-body" id="panel-body"></div>

    <div class="noor-price-bar" id="price-bar">
      <div class="noor-price-breakdown" id="price-breakdown"></div>
      <div class="noor-price-main">
        <div class="noor-price-info">
          <div class="noor-price-lbl" id="ui-total-price-label">Total price</div>
          <div class="noor-price-total" id="price-total">—</div>
        </div>
        <button class="noor-btn-cart" id="btn-add-to-cart" aria-label="Get a Quote">
          <svg class="noor-btn-cart-icon" width="15" height="15" viewBox="0 0 16 16" fill="none" aria-hidden="true">
            <path d="M13 2H3a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/>
            <path d="M5 6h6M5 9h4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
          </svg>
          <span class="noor-btn-cart-text" id="ui-add-to-cart">Get a Quote</span>
          <span class="noor-btn-cart-added" aria-live="polite">✓ Sent!</span>
          <span class="noor-btn-cart-spinner" aria-hidden="true"></span>
        </button>
      </div>
    </div>

    <div class="noor-panel-footer">
      <button class="noor-btn noor-btn-ghost noor-btn-sm" id="btn-reset-cfg">↺ <span id="ui-reset-all">Reset All</span></button>
      <span class="noor-cfg-hash" id="cfg-hash">CFG-#——————</span>
    </div>

  </aside>

  <div class="noor-toast" id="toast">
    <svg width="13" height="13" viewBox="0 0 13 13" fill="none">
      <path d="M2 6.5L5.5 10L11 4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
    </svg>
    <span id="toast-msg">Done</span>
  </div>

  <!-- ════════════════ QUOTE MODAL ════════════════ -->
  <div id="fv-quote-overlay" role="presentation">
    <div id="fv-quote-modal" role="dialog" aria-modal="true" aria-labelledby="fv-modal-title">

      <div class="fv-modal-header">
        <div>
          <div class="fv-modal-title" id="fv-modal-title">Request a Quote</div>
          <div class="fv-modal-subtitle">We'll get back to you within 1 business day</div>
        </div>
        <button class="fv-modal-close" id="fv-quote-close" aria-label="Close quote form">
          <svg width="11" height="11" viewBox="0 0 11 11" fill="none">
            <path d="M1 1l9 9M10 1L1 10" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/>
          </svg>
        </button>
      </div>

      <div class="fv-modal-tile-preview">
        <div class="fv-sel-chips" id="fv-q-selections">
          <div class="fv-sel-chip" id="fv-q-selections-empty">
            <div class="fv-sel-thumb-ph">
              <svg width="18" height="18" viewBox="0 0 20 20" fill="none">
                <rect x="2" y="2" width="7" height="7" rx="1.5" stroke="currentColor" stroke-width="1.4"/>
                <rect x="11" y="2" width="7" height="7" rx="1.5" stroke="currentColor" stroke-width="1.4"/>
                <rect x="2" y="11" width="7" height="7" rx="1.5" stroke="currentColor" stroke-width="1.4"/>
                <rect x="11" y="11" width="7" height="7" rx="1.5" stroke="currentColor" stroke-width="1.4"/>
              </svg>
            </div>
            <div class="fv-sel-text">
              <div class="fv-sel-value">No selection yet</div>
            </div>
          </div>
        </div>
        <span class="fv-your-design-badge">Your Design</span>
      </div>

      <form id="fv-quote-form" novalidate>
        <div class="fv-modal-body">

          <div class="fv-form-section">
            <div class="fv-form-section-title">Your Details</div>
            <div class="fv-field">
              <label for="fv-q-name">Full Name <span class="fv-req">*</span></label>
              <input type="text" id="fv-q-name" required autocomplete="name" placeholder="Jane Smith" />
            </div>
            <div class="fv-field">
              <label for="fv-q-email">Email Address <span class="fv-req">*</span></label>
              <input type="email" id="fv-q-email" required autocomplete="email" placeholder="jane@example.com" />
            </div>
            <div class="fv-fields-2col">
              <div class="fv-field" style="margin:0">
                <label for="fv-q-phone">Phone</label>
                <input type="tel" id="fv-q-phone" autocomplete="tel" placeholder="+44 7700 900000" />
              </div>
              <div class="fv-field" style="margin:0">
                <label for="fv-q-postcode">Postcode</label>
                <input type="text" id="fv-q-postcode" autocomplete="postal-code" placeholder="SW1A 1AA" />
              </div>
            </div>
          </div>

          <div class="fv-form-section" style="margin-bottom:0">
            <div class="fv-form-section-title">Additional Notes</div>
            <div class="fv-field" style="margin:0">
              <label for="fv-q-notes">Notes <span style="font-weight:400;color:var(--noor-text-3)">(optional)</span></label>
              <textarea id="fv-q-notes" rows="3" placeholder="Installation date, special requirements, number of rooms…"></textarea>
            </div>
          </div>

        </div>

        <div class="fv-modal-footer">
          <div id="fv-q-error"></div>
          <button type="submit" class="fv-btn-quote" id="fv-q-submit">Request a Quote</button>
          <p class="fv-modal-privacy">No payment required &nbsp;·&nbsp; Free consultation &nbsp;·&nbsp; No spam</p>
        </div>
      </form>

      <div id="fv-quote-success">
        <div class="fv-success-icon">
          <svg width="26" height="26" viewBox="0 0 26 26" fill="none">
            <path d="M5 13l6 6L21 7" stroke="#34d399" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/>
          </svg>
        </div>
        <div class="fv-success-title">Quote Request Sent!</div>
        <div class="fv-success-sub">We'll review your design and send you a personalised quote within 1 business day.</div>
        <div class="fv-success-tile" id="fv-success-tile-name"></div>
        <button class="fv-success-close-btn" id="fv-success-close">Close</button>
      </div>

    </div>
  </div><!-- #fv-quote-overlay -->

  <?php wp_print_scripts( [ 'tilvora-configurator-app', 'tilvora-quote-modal' ] ); ?>
</body>
</html>
	<?php
}
