<?php

namespace Limb_Chatbot\Includes\Factories;

use Limb_Chatbot\Includes\Integrations\WooCommerce\Services\Discovery_Scenarios\WC_Discovery_Scenario_Interface;
use Limb_Chatbot\Includes\Integrations\WooCommerce\Services\Discovery_Scenarios\WC_Filters_Only_Discovery_Scenario;
use Limb_Chatbot\Includes\Integrations\WooCommerce\Services\Discovery_Scenarios\WC_Keyword_Only_Discovery_Scenario;
use Limb_Chatbot\Includes\Integrations\WooCommerce\Services\Discovery_Scenarios\WC_Keyword_With_Filters_Discovery_Scenario;

class WC_Search_Scenario_Handler_Factory {
	private const SCENARIO_KEYWORD_ONLY = 'keyword_only';
	private const SCENARIO_KEYWORD_WITH_FILTERS = 'keyword_with_filters';
	private const SCENARIO_FILTERS_ONLY = 'filters_only';
	private string $scenario;

	/**
	 * Make discovery scenario handler instance based on query and filters.
	 *
	 * @param $query
	 * @param $filters
	 *
	 * @return WC_Discovery_Scenario_Interface
	 */
	public function make( $query, $filters ): WC_Discovery_Scenario_Interface {
		$scenario = $this->resolve_scenario( $query, $filters );
		$this->set_scenario( $scenario );

		return $this->get_scenario_handler( $scenario );
	}


	/**
	 * Resolve scenario for discovery execution.
	 *
	 * @param  string  $query
	 * @param  array  $filters
	 *
	 * @return string
	 */
	private function resolve_scenario( string $query, array $filters ): string {
		$has_query   = '' !== trim( $query );
		$has_filters = ! $this->filters_are_empty( $filters );

		if ( $has_query && $has_filters ) {
			return self::SCENARIO_KEYWORD_WITH_FILTERS;
		}
		if ( $has_query ) {
			return self::SCENARIO_KEYWORD_ONLY;
		}

		return self::SCENARIO_FILTERS_ONLY;
	}

	/**
	 * Check whether filters are empty.
	 *
	 * @param  array  $filters
	 *
	 * @return bool
	 */
	private function filters_are_empty( array $filters ): bool {
		return empty( $filters['categories'] ) && empty( $filters['tags'] ) && empty( $filters['brands'] );
	}

	private function set_scenario( string $scenario ) {
		$this->scenario = $scenario;
	}

	/**
	 * Resolve scenario handler instance.
	 *
	 * @param  string  $scenario
	 *
	 * @return WC_Discovery_Scenario_Interface
	 */
	private function get_scenario_handler( string $scenario ): WC_Discovery_Scenario_Interface {
		switch ( $scenario ) {
			case self::SCENARIO_KEYWORD_WITH_FILTERS:
				return new WC_Keyword_With_Filters_Discovery_Scenario();
			case self::SCENARIO_FILTERS_ONLY:
				return new WC_Filters_Only_Discovery_Scenario();
			case self::SCENARIO_KEYWORD_ONLY:
			default:
				return new WC_Keyword_Only_Discovery_Scenario();
		}
	}

	public function get_scenario(): ?string {
		return $this->scenario ?? null;
	}
}