<?php

namespace Civi\DataProcessor\FieldOutputHandler;

use \Civi\DataProcessor\DataSpecification\FieldSpecification;
use \Civi\DataProcessor\FieldOutputHandler\AbstractSimpleFieldOutputHandler;
use \Civi\DataProcessor\FieldOutputHandler\FieldOutput;
use CRM_Dataprocessor_ExtensionUtil as E;

class ConditionallyMapStrings extends AbstractSimpleFieldOutputHandler {

  private $conditions;
  private $replacements;
  private $default;

  private $dataFields = 6;

  /**
   * When this handler has additional configuration you can add
   * the fields on the form with this function.
   *
   * @param \CRM_Core_Form $form
   * @param array $field
   */
  public function buildConfigurationForm(\CRM_Core_Form $form, $field = array()) {
    parent::buildConfigurationForm($form, $field);
    for ($i = 1; $i < $this->dataFields; ++$i) {
      $form->add('text', "condition_{$i}", E::ts("{$i}. input comparison"), FALSE);
      $form->add('text', "replacement_{$i}", E::ts("{$i}. input replacement"), FALSE);
    }
    $form->add('text', "default", E::ts("Default fallback, if no condition matches."), FALSE);


    // set the default values
    if (isset($field['configuration'])) {
      $configuration = $field['configuration'];
      $defaults = array();
      for ($i = 1; $i < $this->dataFields; ++$i) {
        if (isset($configuration["condition_{$i}"])) {
          $defaults["condition_{$i}"] = $configuration["condition_{$i}"];
        }
        if (isset($configuration["replacement_{$i}"])) {
          $defaults["replacement_{$i}"] = $configuration["replacement_{$i}"];
        }
      }
      if (isset($configuration['default'])) {
        $defaults['default'] = $configuration['default'];
      }

      $form->setDefaults($defaults);
    }
  }

  /**
   * Process the submitted values and create a configuration array
   *
   * @param $submittedValues
   * @return array
   */
  public function processConfiguration($submittedValues) {

    $configuration = parent::processConfiguration($submittedValues);
    // register the fields to the QuickForm
    for ($i = 1; $i < $this->dataFields; ++$i) {
      if (isset($submittedValues["condition_{$i}"])) {
        $configuration["condition_{$i}"] = $submittedValues["condition_{$i}"];
      }
      if (isset($submittedValues["replacement_{$i}"])) {
        $configuration["replacement_{$i}"] = $submittedValues["replacement_{$i}"];
      }
    }
    if (isset($submittedValues['default'])) {
      $configuration['default'] = $submittedValues['default'];
    }

    return $configuration;
  }

  /**
   * @return string
   */
  protected function getFieldTitle() {
    return E::ts('Input field');
  }

  public function getConfigurationTemplateFileName() {
    return "CRM/Dataprocessor/Form/Field/Configuration//ConditionallyMapStringsOutputHandler.tpl";
  }

  /**
   * Initialize the processor
   *
   * @param String $alias
   * @param String $title
   * @param array $configuration
   * @param \Civi\DataProcessor\ProcessorType\AbstractProcessorType $processorType
   */
  public function initialize($alias, $title, $configuration) {
    parent::initialize($alias, $title, $configuration);
    $this->outputFieldSpec = new FieldSpecification($alias, 'String', $title, null, $alias);
    $this->initializeConfiguration($configuration);
  }

  /**
   * @param array $configuration
   *
   * @return void
   */
  protected function initializeConfiguration($configuration) {
    for ($i = 1; $i < $this->dataFields; ++$i) {
      $replacement = "replacement_{$i}";
      $condition = "condition_{$i}";
      if (isset($configuration[$condition])) {
        $this->conditions[$condition] = $configuration[$condition];
      }
      if (isset($configuration[$replacement])) {
        $this->replacements[$replacement] = $configuration[$replacement];
      }
    }
    if (isset($configuration['default'])) {
      $this->default = $configuration['default'];
    }
  }

  /**
   * Returns the formatted value
   *
   * @param $rawRecord
   * @param $formattedRecord
   *
   * @return \Civi\DataProcessor\FieldOutputHandler\FieldOutput
   */
  public function formatField($rawRecord, $formattedRecord) {

    $inputField = $rawRecord[$this->inputFieldSpec->alias];

    // set the default value
    if (!empty($this->default)) {
      $result = $this->default;
    }
    else {
      $result = $inputField;
    }

    // check all conditions and replace with the replacement string, if a match is found
    for ($i = 1; $i < $this->dataFields; ++$i) {
      $replacement = "replacement_{$i}";
      $condition = "condition_{$i}";
      if (!empty($this->conditions[$condition]) && $this->conditions[$condition] === $inputField) {
        $result = $this->replacements[$replacement];
        break 1;
      }
    }

    return new FieldOutput($result);
  }
}