<?php
/**
 * Copyright (C) 2023  Jaap Jansma (jaap.jansma@civicoop.org)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

namespace Civi\DataProcessor\FieldOutputHandler;

use Civi\DataProcessor\DataSpecification\FieldSpecification;
use CRM_Core_Exception;
use CRM_Core_Form;
use CRM_Dataprocessor_ExtensionUtil as E;

class DateMonthSegmentFieldOutputHandler extends AbstractSimpleSortableFieldOutputHandler {

  /**
   * @var \DateTime
   */
  protected $dateRangeStart;

  /**
   * @var \DateTime
   */
  protected $dateRangeEnd;

  protected $textBeforeRange;

  protected $textAfterRange;

  protected $textInRange;

  /**
   * Initialize the processor
   *
   * @param String $alias
   * @param String $title
   * @param array $configuration
   */
  public function initialize($alias, $title, $configuration): void {
    parent::initialize($alias, $title, $configuration);
    $this->dateRangeStart = new \DateTime();
    $this->dateRangeStart->setTime(0, 0, 0);
    $this->dateRangeEnd = new \DateTime();
    $this->dateRangeEnd->setTime(23, 59, 59);
    $this->dateRangeStart->modify('-' . $configuration['date_range_start'] . ' month');
    $this->dateRangeEnd->modify('-' . $configuration['date_range_end'] . ' month');
    $this->textBeforeRange = $configuration['text_before_range'];
    $this->textAfterRange = $configuration['text_after_range'];
    $this->textInRange = $configuration['text_within_range'];
  }

  /**
   * Returns the data type of this field
   *
   * @return String
   */
  protected function getType() {
    return 'String';
  }

  /**
   * Returns the formatted value
   *
   * @param $rawRecord
   * @param $formattedRecord
   *
   * @return \Civi\DataProcessor\FieldOutputHandler\FieldOutput
   */
  public function formatField($rawRecord, $formattedRecord) {
    $dateValue = $rawRecord[$this->inputFieldSpec->alias] ?? '';
    $formattedValue = '';
    if (!empty($dateValue)) {
      $date = new \DateTime($dateValue);
      if ($date < $this->dateRangeStart) {
        $formattedValue = $this->textBeforeRange;
      } elseif ($date > $this->dateRangeEnd) {
        $formattedValue = $this->textAfterRange;
      } else {
        $formattedValue = $this->textInRange;
      }
    }
    $output = new FieldOutput($formattedValue);
    $output->formattedValue = $formattedValue;
    return $output;
  }


  /**
   * @param \CRM_Core_Form $form
   * @param array $field
   *
   * @return void
   */
  public function buildConfigurationForm(CRM_Core_Form $form, $field=array()): void {
    parent::buildConfigurationForm($form, $field);
    try {
      $form->add('text', 'date_range_start', E::ts('Start of Date Range (months ago)'), TRUE);
      $form->add('text', 'date_range_end', E::ts('End of Date Range (months ago)'), TRUE);
      $form->add('text', 'text_before_range', E::ts('Text before date range'), TRUE);
      $form->add('text', 'text_after_range', E::ts('Text after date range'), true);
      $form->add('text', 'text_within_range', E::ts('Text within date range'), true);
    } catch (CRM_Core_Exception $e) {
    }
    if (isset($field['configuration'])) {
      $configuration = $field['configuration'];
      $defaults = array();
      if (isset($configuration['date_range_start'])) {
        $defaults['date_range_start'] = $configuration['date_range_start'];
      }
      if (isset($configuration['date_range_end'])) {
        $defaults['date_range_end'] = $configuration['date_range_end'];
      }
      if (isset($configuration['text_before_range'])) {
        $defaults['text_before_range'] = $configuration['text_before_range'];
      }
      if (isset($configuration['text_after_range'])) {
        $defaults['text_after_range'] = $configuration['text_after_range'];
      }
      if (isset($configuration['text_within_range'])) {
        $defaults['text_within_range'] = $configuration['text_within_range'];
      }
      $form->setDefaults($defaults);
    }
  }

  /**
   * Process the submitted values and create a configuration array
   *
   * @param $submittedValues
   *
   * @return array
   */
  public function processConfiguration($submittedValues): array {
    $configuration = parent::processConfiguration($submittedValues);
    $configuration['date_range_start'] = $submittedValues['date_range_start'];
    $configuration['date_range_end'] = $submittedValues['date_range_end'];
    $configuration['text_before_range'] = $submittedValues['text_before_range'];
    $configuration['text_after_range'] = $submittedValues['text_after_range'];
    $configuration['text_within_range'] = $submittedValues['text_within_range'];
    return $configuration;
  }

  /**
   * When this handler has configuration specify the template file name
   * for the configuration form.
   *
   * @return string|null
   */
  public function getConfigurationTemplateFileName():? string {
    return "CRM/Dataprocessor/Form/Field/Configuration/DateMonthSegmentFieldOutputHandler.tpl";
  }


  /**
   * Callback function for determining whether this field could be handled by this output handler.
   *
   * @param \Civi\DataProcessor\DataSpecification\FieldSpecification $field
   * @return bool
   */
  public function isFieldValid(FieldSpecification $field): bool {
    if ($field->type == 'Date' || $field->type == 'Timestamp') {
      return true;
    }
    return false;
  }

}
