<?php

class HappyForms_Part_RadioExtended extends HappyForms_Part_Radio {

	private $class_name = 'HappyForms_Part_RadioExtended';

	public function __construct() {
		parent::__construct();
	}

	public function hook() {
		remove_filter( 'happyforms_stringify_part_value', array( self::$parent, 'stringify_value' ), 10, 3 );

		add_filter( 'happyforms_part_input_after', array( $this, 'append_input' ), 10, 2 );
		add_filter( 'happyforms_stringify_part_value', array( $this, 'stringify_value' ), 10, 3 );
		add_filter( 'happyforms_frontend_dependencies', array( $this, 'script_dependencies' ), 10, 2 );
		add_filter( 'happyforms_part_class', array( $this, 'html_part_class' ), 10, 3 );
		add_filter( 'happyforms_part_frontend_template_path_radio', array( $this, 'set_template_path' ) );
	}

	public function get_customize_fields() {
		$fields = parent::get_customize_fields();

		$fields['other_option'] = array(
			'default' => 0,
			'sanitize' => 'happyforms_sanitize_checkbox'
		);

		$fields['other_option_label'] = array(
			'default' => __( 'Other', 'happyforms' ),
			'sanitize' => 'sanitize_text_field'
		);

		$fields['other_option_placeholder'] = array(
			'default' => '',
			'sanitize' => 'sanitize_text_field'
		);

		$fields['display_as_letters'] = array(
			'default' => 0,
			'sanitize' => 'happyforms_sanitize_checkbox'
		);

		return happyforms_get_part_customize_fields( $fields, $this->type );
	}

	public function sanitize_value( $part = array(), $form = array(), $request = array() ) {
		$sanitized_value = $this->get_default_value( $part );
		$part_name = happyforms_get_part_name( $part, $form );

		if ( isset( $request[$part_name] ) ) {
			$value_array = json_decode( stripslashes( $request[$part_name] ) );

			if ( ! is_array( $value_array ) ) {
				return parent::sanitize_value( $part, $form, $request );
			}

			$sanitized_value = array();
			$sanitized_value[0] = intval( $value_array[0] );
			$sanitized_value[1] = sanitize_text_field( $value_array[1] );
		}

		return $sanitized_value;
	}

	public function validate_value( $value, $part = array(), $form = array() ) {
		$validated_value = $value;

		if ( ! is_array( $validated_value ) ) {
			$validated_value = parent::validate_value( $value, $part, $form );

			if ( is_wp_error( $validated_value ) ) {
				return $validated_value;
			}

			return $this->validate_option_limits( $validated_value, $part, $form );
		}

		if ( 1 === $part['required'] && empty( $validated_value[0] ) ) {
			return new WP_Error( 'error', happyforms_get_validation_message( 'no_selection' ) );
		}

		if ( ! empty( $validated_value[0] ) ) {
			if ( ! is_numeric( $validated_value[0] ) ) {
				return new WP_Error( 'error', happyforms_get_validation_message( 'field_invalid' ) );
			}
		}

		if ( '' === $validated_value[1] ) {
			return new WP_Error( 'error', happyforms_get_validation_message( 'field_invalid' ) );
		}

		return $validated_value;
	}

	public function stringify_value( $value, $part, $form, $force = false ) {
		if ( $this->type === $part['type'] || $force ) {
			$original_value = $value;

			if ( ! is_array( $value ) ) { // standard options
				$value = parent::stringify_value( $value, $part, $form, $force );

				if ( $this->display_choices_as_letters( $part ) ) {
					$original_value = intval( $original_value );

					if ( isset( $part['options'][$original_value] ) ) {
						$option = $part['options'][$original_value];
						$letter = happyforms_get_part_choice_letter( $option, $part );
						$value = "{$letter}) {$value}";
					}
				}
			} else { // other option
				$value = ( ! empty( $value[1] ) ) ? $value[1] : '';

				if ( $this->display_choices_as_letters( $part ) ) {
					$letter = happyforms_get_part_choice_letter( '', $part );
					$value = "{$letter}) {$value}";
				}
			}
		}

		return $value;
	}

	public function append_input( $part, $form ) {
		if ( $this->type !== $part['type'] ) {
			return;
		}

		if ( 1 == $part['other_option'] ) {
			require( happyforms_get_include_folder() . '/templates/parts/frontend-radio-other-option.php' );
		}
	}

	public function script_dependencies( $deps, $forms ) {
		$contains_radio = false;
		$form_controller = happyforms_get_form_controller();

		foreach ( $forms as $form ) {
			if ( $form_controller->get_first_part_by_type( $form, $this->type ) ) {
				$contains_radio = true;
				break;
			}
		}

		if ( ! happyforms_is_preview() && ! $contains_radio ) {
			return $deps;
		}

		wp_register_script(
			'happyforms-radio-ext',
			happyforms_get_plugin_url() . 'inc/assets/js/frontend/radio-extended.js',
			array(), HAPPYFORMS_VERSION, true
		);

		$deps[] = 'happyforms-radio-ext';

		return $deps;
	}

	public function customize_enqueue_scripts( $deps = array() ) {
		parent::customize_enqueue_scripts( $deps );

		wp_enqueue_script(
			'part-radio-extended',
			happyforms_get_plugin_url() . 'inc/assets/js/parts/part-radio-extended.js',
			$deps, HAPPYFORMS_VERSION, true
		);
	}

	public function html_part_class( $class, $part, $form ) {
		parent::html_part_class( $class, $part, $form );

		if ( $this->type === $part['type'] ) {
			if ( 1 == $part['display_as_letters'] ) {
				$class[] = 'happyforms-part-choice--display-as-letters';
			}
		}

		return $class;
	}

	public function set_template_path( $template_path ) {
		$template_path = happyforms_get_include_folder() . '/templates/parts/frontend-radio-extended.php';

		return $template_path;
	}

	public function display_choices_as_letters( $part ) {
		if ( 1 == $part['display_as_letters'] ) {
			return true;
		}

		return false;
	}

	private function validate_option_limits( $value, $part, $form ) {
		foreach( $part['options'] as $o => $option ) {
			$option = wp_parse_args( $option, happyforms_upgrade_get_option_limiter()->get_option_fields() );

			if ( ! $option['limit_submissions'] || $o !== intval( $value ) ) {
				continue;
			}

			$limit = intval( $option['limit_submissions_amount'] );
			$form_id = $form['ID'];
			$option_id = $option['id'];
			$count = happyforms_get_message_controller()->count_by_option( $form_id, $option_id, $limit );

			if ( $count === $limit ) {
				return new WP_Error( 'error', happyforms_get_validation_message( 'field_invalid' ) );
			}
		}

		return $value;
	}

}
