<?php
namespace SabaiApps\Directories\Component\PaymentGateway\FieldType;

use SabaiApps\Directories\Component\Field\Type\AbstractType;
use SabaiApps\Directories\Component\Field\Type\IColumnable;
use SabaiApps\Directories\Component\Field\Type\IRestrictable;
use SabaiApps\Directories\Component\Field\IField;
use SabaiApps\Directories\Component\Entity\Type\IEntity;
use SabaiApps\Directories\Application;
use SabaiApps\Directories\Component\Field\Type\IContent;
use SabaiApps\Directories\Component\Field\Type\SaveNotesTrait;

class DiscountFieldType extends AbstractType implements
	IColumnable,
	IRestrictable,
	IContent {

	use SaveNotesTrait;

	protected function _fieldTypeInfo() {
		return array(
			'label'      => __( 'Discount Information', 'directories-pro' ),
			'creatable'  => false,
			'disablable' => false,
			'requirable' => false,
		);
	}

	public function fieldTypeSchema( array $settings = array() ) {
		return array(
			'columns' => array(
				'discount_type'   => array(
					'type'    => Application::COLUMN_VARCHAR,
					'length'  => 20,
					'notnull' => true,
					'was'     => 'discount_type',
					'default' => '',
				),
				'discount_value'  => array(
					'type'    => Application::COLUMN_DECIMAL,
					'notnull' => true,
					'length'  => 10,
					'scale'   => 2,
					'was'     => 'discount_value',
					'default' => 0,
				),
				'discount_code'   => array(
					'type'    => Application::COLUMN_VARCHAR,
					'length'  => 50,
					'notnull' => true,
					'was'     => 'code',
					'default' => '',
				),
				'max_redemptions' => array(
					'type'    => Application::COLUMN_INTEGER,
					'length'  => 3,
					'notnull' => true,
					'was'     => 'max_redemptions',
					'default' => 0,
				),
				'usage_count'     => array(
					'type'    => Application::COLUMN_INTEGER,
					'length'  => 3,
					'notnull' => true,
					'was'     => 'usage_count',
					'default' => 0,
				),
				'active'          => array(
					'type'    => Application::COLUMN_INTEGER,
					'length'  => 1,
					'notnull' => true,
					'was'     => 'active',
					'default' => 1,
				),
				'usage_history'   => array(
					'type'    => Application::COLUMN_JSON,
					'notnull' => false,
					'default' => null,
				),
				'starts_at'       => array(
					'type'     => Application::COLUMN_INTEGER,
					'notnull'  => true,
					'unsigned' => true,
					'was'      => 'starts_at',
					'default'  => 0,
					'length'   => 10,
				),
				'expires_at'      => array(
					'type'     => Application::COLUMN_INTEGER,
					'notnull'  => true,
					'unsigned' => true,
					'was'      => 'expires_at',
					'default'  => 0,
					'length'   => 10,
				),
			),
			'indexes' => array(
				'discount_type' => array(
					'fields' => array( 'discount_type' => array( 'sorting' => 'ascending' ) ),
					'was'    => 'discount_type',
				),
				'active_period' => array(
					'fields' => array(
						'active'     => array( 'sorting' => 'ascending' ),
						'starts_at'  => array( 'sorting' => 'ascending' ),
						'expires_at' => array( 'sorting' => 'ascending' ),
					),
					'was'    => 'active_period',
				),
				'discount_code' => array(
					'fields' => array( 'discount_code' => array( 'sorting' => 'ascending' ) ),
					'was'    => 'discount_code',
					'unique' => true,
				),
			),
		);
	}

	public function fieldTypeOnSaveValues( IField $field, array $values, ?array $currentValues = null, array &$extraArgs = array() ) {
		$value = array_shift( $values ); // single entry allowed for this field
		if ( ! is_array( $value ) ) {
			if ( $value === null ) {
				return; // do nothing
			}

			return array( false ); // delete
		}

		// Make sure required properties are set
		foreach ( array( 'discount_type', 'discount_value' ) as $required_key ) {
			if ( ! isset( $value[ $required_key ] ) ) {
				if ( empty( $currentValues[0][ $required_key ] ) ) {
					return array( false ); // delete
				}

				$value[ $required_key ] = $currentValues[0][ $required_key ];
			} elseif ( empty( $value[ $required_key ] ) ) {
				return array( false ); // delete
			}
		}

		// Keep current values unless explicitly changed
		foreach ( array( 'active' => 1 ) as $key => $default_value ) {
			if ( isset( $value[ $key ] ) ) {
				continue;
			}

			$value[ $key ] = $currentValues[0][ $key ] ?? $default_value;
		}

		// Update usage history
		$this->_saveNotes( $value, $currentValues, 'usage_history' );

		return array( $value );
	}

	public function fieldColumnableInfo( IField $field ) {
		return array(
			'discount_type'  => array(
				'label' => __( 'Discount type', 'directories-pro' ),
			),
			'description'    => array(
				'label' => __( 'Description', 'directories-pro' ),
			),
			'discount_value' => array(
				'label' => __( 'Discount value', 'directories-pro' ),
			),
			'discount_code'  => array(
				'label' => __( 'Discount code', 'directories-pro' ),
			),
			'usage'          => array(
				'label' => __( 'Usage / Limit', 'directories-pro' ),
			),
			'status'         => array(
				'label' => __( 'Status', 'directories-pro' ),
			),
			'date_range'     => array(
				'label' => __( 'Date range', 'directories-pro' ),
			),
		);
	}

	public function fieldColumnableColumn( IField $field, IEntity $entity, $column = '' ) {
		if ( ! $value = $entity->getSingleFieldValue( $field->getFieldName() ) ) {
			return;
		}

		switch ( $column ) {
			case 'discount_type':
				$discount_types = $this->_application->PaymentGateway_Util_discountTypes();
				return isset( $discount_types[ $value['discount_type'] ] ) ? $this->_application->H( $discount_types[ $value['discount_type'] ] ) : '<span class="' . DRTS_BS_PREFIX . 'text-danger">' . $this->_application->H( $value['discount_type'] ) . '</span>';
			case 'discount_value':
				if ( ! isset( $value['discount_type'], $value['discount_value'] ) ) {
					return '';
				}
				if ( $value['discount_type'] === 'percentage' ) {
					return $this->_application->H( $value[ $column ] ) . '%';
				} else {
					return $this->_application->System_Currency_format( $value['discount_value'], $this->_application->Payment_Components_impl( 'default' )->paymentGetCurrency() );
				}
			case 'discount_code':
				return isset( $value[ $column ] ) ? '<code class="' . DRTS_BS_PREFIX . 'user-select-all">' . $this->_application->H( $value[ $column ] ) . '</code>' : '';
			case 'description':
				return $this->_application->System_Text_summarize( $entity->getContent(), 80 );
			case 'usage':
				return ( isset( $value['usage_count'] ) ? (int) $value['usage_count'] : 0 ) . '/'
					. ( empty( $value['max_redemptions'] ) ? __( 'Unlimited', 'directories-pro' ) : (int) $value['max_redemptions'] );
			case 'status':
				return '<span role="button" class="drts-action-button drts-payment-set-plan-status ' . DRTS_BS_PREFIX . 'text-' . ( $value['active'] == 1 ? 'success' : 'muted' ) . '"'
					. ' data-action-url="' . $this->_application->AdminUrl( '/_drts/paymentgateway/set_discount_status', array(), '', '&' ) . '"'
					. ' data-action-token="' . $this->_application->Form_Form_createToken( 'paymentgateway_admin_discounts', 1800, true ) . '"'
					. ' data-action-data-id="' . $entity->getId() . '"'
					. ' title="' . $this->_application->H( $value['active'] == 1 ? __( 'Active', 'directories-pro' ) : __( 'Inactive', 'directories-pro' ) ) . '">'
					. '<i class="fas fa-check-circle fa-xl"></i></span>';
			case 'date_range':
				if ( empty( $value['starts_at'] ) && empty( $value['expires_at'] ) ) {
					return '';
				}

				$ret = '';
				if ( ! empty( $value['starts_at'] ) ) {
					$ret .= $this->_application->H( $this->_application->System_Date( $value['starts_at'] ) );
				}
				$ret .= ' - ';
				if ( ! empty( $value['expires_at'] ) ) {
					$ret .= $this->_application->H( $this->_application->System_Date( $value['expires_at'] ) );
				}
				return $ret;
		}
	}

	public function fieldRestrictableOptions( IField $field ) {
		return array(
			'discount_type' => array(
				'' => array( 'label' => __( 'Discount type', 'directories-pro' ) ),
			) + $this->_application->PaymentGateway_Util_discountTypes(),
			'active'        => array(
				'' => array( 'label' => __( 'Status', 'directories-pro' ) ),
				1  => __( 'Active', 'directories-pro' ),
				0  => __( 'Inactive', 'directories-pro' ),
			),
		);
	}

	public function fieldRestrictableRestrict( IField $field, $value, $name ) {
		return array( 'column' => $name );
	}

	public function fieldContent( IField $field, array $values ) {
		return $values[0]['description'] ?? null;
	}
}
