<?php

namespace Inoby\WPBS;

use WPBS_Form;
use Inoby_Config;

class FormExtend {
  public function init() {
    add_filter("wpbs_form_available_field_types", [$this, "add_custom_form_fields"]);
    add_filter("wpbs_form_outputter_form_before", [$this, "add_custom_form_fields_to_output"], 10, 3);
    add_filter("wpbs_form_validator_custom_field_validation", [$this, "validate_custom_fields"], 10, 5);
    add_filter("inoby_accommodation_metaboxes", [$this, "add_accommodation_maximum_capacity_metaboxes"]);
    add_filter("wpbs_get_forms", [$this, "override_form_fields"], 10, 3);
    add_filter("wpbs_form_ajax_nonce", "__return_false");
    add_filter("wpbs_pricing_item_modifier", [$this, "modify_prices"], 10, 3);
    add_filter("wpbs_get_checkout_tax", [$this, "calculate_meta_price_taxes"], 10, 8);

    if (Inoby_Config::wpbs_extend()["datepicker"] ?? false) {
      // setup ajax
      require_once __DIR__ . "/class-inoby-wpbs-form-extend-datepicker-ajax.php";
      FormExtendDatepickerAjax::init();

      // enable on frontend
      add_filter("inoby_localize_core_script", function ($vars) {
        $vars["wpbs_extend"]["datepicker"] = true;

        return $vars;
      });
    }
  }

  /**
   * Add custom form fields to admin form builder
   *
   * @param array $fields
   * @return array
   */
  public function add_custom_form_fields($fields) {
    $fields["capacity"] = [
      "type" => "capacity",
      "group" => "basic",
      "supports" => [
        "primary" => ["label", "required"],
        "secondary" => ["placeholder", "value", "description", "layout", "class", "hide_label"],
      ],
      "values" => [],
    ];

    $fields["date_selection"] = [
      "type" => "date_selection",
      "group" => "basic",
      "supports" => [
        "primary" => ["label"],
        "secondary" => ["class", "hide_label"],
      ],
      "values" => [],
    ];

    $fields["meta_price"] = [
      "type" => "meta_price",
      "group" => "pricing",
      "supports" => [
        "primary" => ["label", "value"],
        "secondary" => [],
      ],
      "values" => [],
    ];

    return $fields;
  }

  /**
   * Adds hooks to custom field output filter actions
   *
   * @param string $output
   * @param \WPBS_Form $form
   * @param array $args
   * @return void
   */
  public function add_custom_form_fields_to_output($output, $form, $args) {
    require_once __DIR__ . "/class-inoby-wpbs-form-outputter.php";
    $custom_field_types = $this->get_custom_field_types();
    $form_outputter = new \Inoby\WPBS\Form_Outputter($form, $args);
    $form_outputter->hook_custom_field_outputers($custom_field_types);

    return $output;
  }

  /**
   * Validate custom fields
   * When error, this should return array with
   * $errors
   *  ["error"] = true
   *  ["error_message"] = "error message"
   *
   *
   * @param array|bool $errors
   * @param \WPBS_Form $form
   * @param \WPBS_Calendar $calendar
   * @param string $language
   * @param array $form_fields
   * @return void
   */
  public function validate_custom_fields($errors, $form, $calendar, $language, $form_fields) {
    foreach ($form_fields as $field) {
      if ($field["type"] === "capacity") {
        $errors = $this->validate_capacity_field($errors, $field, $calendar);
      }
    }

    return $errors;
  }

  /**
   * Validate capacity field
   *
   * @param array|bool $errors
   * @param array $field
   * @param \WPBS_Calendar $calendar
   * @return void
   */
  public function validate_capacity_field($errors, $field, $calendar) {
    $accomodation_id = wpbs_get_calendar_meta($calendar->get("id"), "calendar_link_internal", true);

    if ($accomodation_id) {
      $max_capacity = rwmb_meta("accommodation_maximum_capacity", [], $accomodation_id);
      if ($field["user_value"] ?? false) {
        if ((int) $field["user_value"] > (int) $max_capacity) {
          $errors["error"] = true;
          $errors["error_message"] = __("Toto ubytovanie má maximálnu kapacitu", "inoby") . " $max_capacity " . ($max_capacity < 5 ? __("osoby", "inoby") : __("osôb", "inoby"));
        }
      } else {
        $errors["error"] = true;
        $errors["error_message"] = __("Zadajte počet osôb", "inoby");
      }
    }

    return $errors;
  }

  /**
   * Add capacity metaboxes to accomodation post-type
   *
   * @param array $metaboxes
   * @return void
   */
  public function add_accommodation_maximum_capacity_metaboxes(array $metaboxes) {
    $metaboxes["fields"][] = [
      "id" => "accommodation_maximum_capacity",
      "name" => __("Maximum capacity", "inoby"),
      "type" => "number",
      "tab" => "important_info",
    ];

    return $metaboxes;
  }

  function override_form_fields($forms, $args, $count) {
    if (!is_admin() || $count) {
      return $forms;
    }

    $edited = [];
    foreach ($forms as $form) {
      $arr = $form->to_array();
      foreach ($arr["fields"] as $key => $field) {
        /**
         * Hack to allow capacity and meta_price fields in price calculations
         */
        if ($field["type"] == "capacity" || $field["type"] == "meta_price") {
          $arr["fields"][$key]["type"] = "dropdown";
        }
      }
      $edited[] = new WPBS_Form((object) $arr);
    }
    return $edited;
  }

  function modify_prices($price, $prices, $type) {
    if ($type == "extras_price") {
    }
    return $price;
  }

  private function get_custom_field_types() {
    return array_map(function ($field) {
      return $field["type"];
    }, $this->add_custom_form_fields([]));
  }

  /**
   * Calculate meta price taxes
   *
   * @param int $tax_value
   * @param string $tax_name
   * @param int $calendar_id
   * @param array $form_args
   * @param WPBS_Form $form
   * @param array $form_fields
   * @param int $start_date
   * @param int $end_date
   * @return void
   */
  public function calculate_meta_price_taxes($tax_value, $tax_name, $calendar_id, $form_args, $form, $form_fields, $start_date, $end_date) {
    $settings = get_option("wpbs_settings");

    foreach ($settings["payment_tax_name"] as $i => $_tax_name) {
      if ($_tax_name == $tax_name) {
        $tax_multiplication_field = isset($settings["payment_tax_multiplication"][$i]) && !empty($settings["payment_tax_multiplication"][$i]) ? $settings["payment_tax_multiplication"][$i] : false;

        if ($tax_multiplication_field !== false) {
          list($tax_form_id, $tax_form_field_id) = explode("_", $tax_multiplication_field);
          if ($form->get("id") == $tax_form_id) {
            foreach ($form_fields as $form_field) {
              if ($form_field["id"] != $tax_form_field_id) {
                continue;
              }

              if ($form_field["type"] == "meta_price") {
                $accomodation_id = wpbs_get_calendar_meta($calendar_id, "calendar_link_internal", true);
                if ($accomodation_id) {
                  $meta_value = rwmb_meta($form_field["values"]["default"]["value"], null, $accomodation_id);
                  if (!empty($meta_value)) {
                    // do not multiply with $tax_value ($tax_value is always 0)
                    return floatval($meta_value);
                  }
                }
              }
            }
          }
        }
      }
    }

    return $tax_value;
  }
}
