<?php

namespace CelerSearch\Shortcodes;

defined( 'ABSPATH' ) || exit;

use CelerSearch\Repositories\ViewRepository;
use CelerSearch\Views\SearchView;
use CelerSearch\Views\ViewRenderer;

/**
 * [celersearch] shortcode
 *
 * Maps shortcode attributes to SearchView config and delegates rendering.
 *
 * Supports two modes:
 * 1. View-based: [celersearch view="3"] - loads config from saved view in database
 * 2. Inline: [celersearch index_id="5" limit="12"] - inline configuration (legacy/fallback)
 *
 * When using view attribute, inline attributes can still override saved config.
 */
class SearchShortcode extends AbstractShortcode {

	/**
	 * @inheritDoc
	 */
	public function get_tag(): string {
		return 'celersearch';
	}

	/**
	 * @inheritDoc
	 */
	protected function get_defaults(): array {
		return [
			'view'            => 0,
			'index_id'        => 0,
			'limit'           => 12,
			'placeholder'     => __( 'Search...', 'celersearch' ),
			'class'           => '',
			'show_facets'     => 'true',
			'highlight'       => 'true',
			'debounce'        => 300,
			'min_chars'       => 2,
			'mode'            => 'live',
			'initial_display' => 'search_only',
		];
	}

	/**
	 * @inheritDoc
	 */
	protected function render( array $atts, ?string $content ): string {
		// If view ID is provided, load saved config from database
		if ( ! empty( $atts['view'] ) ) {
			$view_id = absint( $atts['view'] );
			$repo    = new ViewRepository();
			$view_config = $repo->find( $view_id );

			if ( ! $view_config ) {
				if ( current_user_can( 'manage_options' ) ) {
					return ViewRenderer::render( 'search/error', [
						'errors' => [
							/* translators: %d: view ID */
							sprintf( __( 'View with ID %d not found.', 'celersearch' ), $view_id )
						]
					], null );
				}
				return '';
			}

			// Build config from saved view
			$saved_config = $view_config->getConfig();
			$config = array_merge(
				[
					'index_id'        => $view_config->getIndexId(),
					'limit'           => $saved_config['limit'] ?? 12,
					'placeholder'     => $saved_config['placeholder'] ?? __( 'Search...', 'celersearch' ),
					'class'           => $saved_config['class'] ?? '',
					'show_facets'     => $saved_config['show_facets'] ?? true,
					'highlight'       => $saved_config['highlight'] ?? true,
					'debounce'        => $saved_config['debounce'] ?? 300,
					'min_chars'       => $saved_config['min_chars'] ?? 2,
					'mode'            => $saved_config['mode'] ?? 'live',
					'initial_display' => $saved_config['initial_display'] ?? 'search_only',
					'default_sort'    => $saved_config['default_sort'] ?? '',
				],
				// Inline attributes override saved config (except 'view' itself)
				$this->get_override_atts( $atts )
			);
		} else {
			// Legacy mode: use inline attributes directly
			$config = $atts;
		}

		$view   = new SearchView( $config );
		$errors = $view->validate();

		if ( ! empty( $errors ) ) {
			if ( current_user_can( 'manage_options' ) ) {
				return ViewRenderer::render( 'search/error', [ 'errors' => $errors ], $view );
			}

			return '';
		}

		return $view->render();
	}

	/**
	 * Get non-default attributes that should override saved view config
	 *
	 * @param array $atts Shortcode attributes.
	 * @return array Attributes that were explicitly set (not defaults).
	 */
	private function get_override_atts( array $atts ): array {
		$defaults = $this->get_defaults();
		$overrides = [];

		foreach ( $atts as $key => $value ) {
			// Skip the 'view' attribute itself
			if ( $key === 'view' ) {
				continue;
			}

			// Only include if different from default (meaning it was explicitly set)
			if ( isset( $defaults[ $key ] ) && $value != $defaults[ $key ] ) {
				$overrides[ $key ] = $value;
			}
		}

		return $overrides;
	}
}
