<?php

namespace WpieFw\Settings\Iterator;

use WpieFw\Helpers\WpieMultilangHelper;
use WpieFw\Settings\WpieSettingsValues;
use WpieFw\Settings\Iterator\WpieAbstractSetting;
use WpieFw\Settings\Parser\WpieAbstractSettingsParser;
use WpieFw\Multilang\WpieMultilangProcessor;

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

final class WpieSettingMultilang extends WpieAbstractSetting
{
	/**
	 * @var WpieMultilangProcessor
	 */
	private $multilangProcessor;

	/**
	 * Constructor
	 *
	 * @param string $idx
	 * @param WpieAbstractSettingsParser $parser
	 * @param WpieSettingsValues $values
	 *
	 * @throws \WpieFw\Exceptions\WpieInvalidArgumentException if $idx param is not given
	 */
	public function __construct( string $idx, WpieAbstractSettingsParser $parser, WpieSettingsValues $values, WpieMultilangProcessor $multilangProcessor )
	{
		$this->multilangProcessor = $multilangProcessor;

		parent::__construct( $idx, $parser, $values );
	}

	/**
	 * {@inheritDoc}
	 * @see \WpieFw\Settings\Iterator\WpieAbstractSetting::initStack()
	 */
	protected function initStack()
	{
		if( $this->isNew ) {
			// set the default values as the stack
			$this->stack = $this->getDefaults();
			// add meta data to the stack
			$this->stack[self::IDX] = $this->idx;
			$this->stack[self::PRIO] = $this->priority;
			$this->stack[self::IS_DEFAULT] = $this->isDefault;
		} else {
			// check if current settings option array is with multi language keys
			if( $this->isLanguaged && in_array( $this->multilangProcessor->activeLocale, $this->storedKeys ) ) {
				$this->stack = $this->stored[$this->multilangProcessor->activeLocale];
			} elseif( $this->isLanguaged && !in_array( $this->multilangProcessor->activeLocale, $this->storedKeys ) ) {
				$this->stack = $this->stored[$this->firstLocale];
				$this->dataToPersist = $this->stored + [ $this->multilangProcessor->activeLocale => $this->stored[$this->firstLocale] ];
			} elseif( !$this->isLanguaged ) {
				$this->stack = $this->stored;
				$this->dataToPersist = [ $this->multilangProcessor->activeLocale => $this->stored ];
				$this->isLanguaged = true;
			}

			// get meta data from the stack
			$this->priority = ( isset( $this->stack[self::PRIO] ) ) ? $this->stack[self::PRIO] : $this->priority;
			$this->isDefault = ( isset( $this->stack[self::IS_DEFAULT] ) ) ? $this->stack[self::IS_DEFAULT] : $this->isDefault;
		}
	}

	/**
	 * Add an entry to the stack for the active locale
	 *
	 * @param string $key
	 * @param mixed $value
	 * @param boolean $persist
	 *
	 * @return \WpieFw\Settings\Iterator\WpieSetting
	 */
	public function set( string $key, $value, $persist = false )
	{
		$this->stack[$key] = $value;

		if( $persist ) {
			if( isset( $this->stored[$this->multilangProcessor->activeLocale] ) ) {
				$data = $this->stored;
				$data[$this->multilangProcessor->activeLocale] = $this->stack;
			} else {
				$data = [$this->multilangProcessor->activeLocale => $this->stack];
			}

			$this->persistWith( $data );
		}

		return $this;
	}

	/**
	 * Merge the current stack with a temporary backup stack
	 *
	 * @param array $backup
	 *
	 * @uses array_merge
	 *
	 * @return array the merged stack
	 */
	protected function doMergeSettingsTmp( array $backup = [] )
	{
	  $merged = [];
	  foreach( $this->multilangProcessor->locales as $locale ) {
		if( isset( $backup[$locale] ) ) {
		  $backupLocale = $backup[$locale];
		} elseif( isset( $backup[$this->multilangProcessor->defaultLocale] ) ) {
			$backupLocale = $backup[$this->multilangProcessor->defaultLocale];
		} else {
		  $backupLocale = $backup[WpieMultilangHelper::getFirstLocaleFromOption( $backup ) ];
		}

		$merged[$locale] = array_merge( $this->stack, $backupLocale );
	  }

	  $this->stack = $merged[$this->multilangProcessor->activeLocale];
	  $this->dataToPersist = $merged;
	}
}