<?php
namespace SabaiApps\Directories\Component\Voting\Controller;

use SabaiApps\Directories\Component\Form;
use SabaiApps\Directories\Context;
use SabaiApps\Directories\Component\Voting\Model\Vote;

abstract class AbstractVotes extends Form\Controller {

	protected function _doGetFormSettings( Context $context, array &$formStorage ) {
		// Init form
		$form = array(
			'votes' => array(
				'#type'      => 'tableselect',
				'#header'    => $this->_getHeaders( $context ),
				'#multiple'  => true,
				'#js_select' => true,
				'#options'   => array(),
				'#class'     => 'drts-data-table',
			),
		);
		// Set submit buttons
		$this->_submitButtons        = $this->_getSubmitButtons( $context );
		$this->_submitButtonsOptions = array( 'margin' => 3 );

		// Ajax options
		$this->_ajaxSubmit            = true;
		$this->_ajaxOnSuccess         = 'function (result, target, trigger) {' . $this->_getAjaxOnSuccessJs( $context ) . '}';
		$this->_ajaxOnSuccessRedirect = false;

		// Init variables
		$sortable_headers = $this->_getSortableHeaders( $context );
		$sort             = $context->getRequest()->asStr( 'sort', $this->_getDefaultHeader( $context ), $sortable_headers );
		$order            = $context->getRequest()->asStr( 'order', 'DESC', array( 'ASC', 'DESC' ) );

		// Set sortable headers
		$this->_makeTableSortable( $context, $form['votes'], $sortable_headers, $sort, $order, $this->_getSortableHeaderParams( $context ) );

		// Add rows
		foreach ( $this->_getVotes( $context, 100, 0, $sort, $order ) as $vote ) {
			if ( $row = $this->_getVoteRow( $context, $vote, $form['votes']['#header'] ) ) {
				$form['votes']['#options'][ $vote->id ] = $row;
			}
		}

		$form['sort']  = array(
			'#type'  => 'hidden',
			'#value' => $sort,
		);
		$form['order'] = array(
			'#type'  => 'hidden',
			'#value' => $order,
		);

		return $form;
	}

	protected function _getAjaxOnSuccessJs( Context $context ) {
		return 'if (!result.deleted) return;
var table = $(".drts-voting-dashboardvotes");
result.deleted.forEach(function (val) {
    var row = table.find("tr[data-row-id=\'" + val + "\']");
    if (row.length) DRTS.Form.deleteTableRow(row);
});';
	}

	public function submitForm( Form\Form $form, Context $context ) {
		$attr = array();
		if ( ! empty( $form->values['votes'] ) ) {
			switch ( $form->values['_action'] ) {
				case 'delete':
					$attr['deleted'] = array();
					foreach ( $votes = $this->getModel( 'Vote', 'Voting' )
						->id_in( $form->values['votes'] )
						->fieldName_is( 'voting_' . $this->_getVotingType( $context ) )
						->fetch()
						->with( 'Entity' )
					as $vote ) {
						$entity = $vote->Entity;
						$vote->markRemoved()->commit();
						if ( $entity ) {
							$this->Voting_Votes_recalculate( $entity, 'voting_' . $this->_getVotingType( $context ) );
						}
						$attr['deleted'][] = $vote->id;
					}
					break;
			}
		}

		$context->setSuccess( $this->_getSuccessUrl( $context ), $attr );
	}

	protected function _getSuccessUrl( Context $context ) {
		return $context->getRoute();
	}

	protected function _getSubmitButtons( Context $context ) {
		return array(
			'_action' => array(
				'#type'    => 'select',
				'#options' => array(
					''       => __( 'Bulk Actions', 'directories-pro' ),
					'delete' => __( 'Delete', 'directories-pro' ),
				),
				'#weight'  => 1,
			),
			'apply'   => array(
				'#btn_label' => __( 'Apply', 'directories-pro' ),
				'#btn_size'  => 'small',
				'#weight'    => 10,
			),
		);
	}

	abstract protected function _getHeaders( Context $context );
	abstract protected function _getDefaultHeader( Context $context );

	protected function _getSortableHeaders( Context $context ) {
		return array();
	}

	protected function _getSortableHeaderParams( Context $context ) {
		return array();
	}

	protected function _getVotes( Context $context, $limit, $offset, $sort, $order ) {
		return $this->_getQuery( $context )->fetch( $limit, $offset, $sort, $order );
	}

	protected function _getQuery( Context $context ) {
		return $this->getModel( 'Vote', 'Voting' )->fieldName_is( 'voting_' . $this->_getVotingType( $context ) );
	}

	abstract protected function _getVoteRow( Context $context, Vote $vote, array $tableHeaders );

	abstract protected function _getVotingType( Context $context );
}
