<?php

namespace Larabookir\Gateway\Saman;

use Larabookir\Gateway\Enum;
use SoapClient;
use Larabookir\Gateway\PortAbstract;
use Larabookir\Gateway\PortInterface;
use Illuminate\Support\Facades\Input;
class Saman extends PortAbstract implements PortInterface
{
	/**
	 * Url of saman gateway web service
	 *
	 * @var string
	 */
	protected $serverUrl = 'https://sep.shaparak.ir/payments/referencepayment.asmx?WSDL';

	/**
	 * Address of CURL server for get Token
	 *
	 * @var string
	 */
	protected $serverTokenUrl = 'https://sep.shaparak.ir/Payments/InitPayment.asmx?WSDL';

	/**
	 * Address of gate for redirect
	 *
	 * @var string
	 */
	protected $gateUrl = 'https://sep.shaparak.ir/Payment.aspx';

	/**
	 * Form generated by sadad gateway
	 *
	 * @var string
	 */
	private $form = '';


	/**
	 * {@inheritdoc}
	 */
	public function set($amount)
	{
		$this->amount = intval($amount);

		return $this;
	}

	/**
	 * {@inheritdoc}
	 */
	public function ready()
	{
		$this->sendPayRequest();

		return $this;
	}

	public function defaultSettings() {
		return [
			'MID' => $this->config->get('gateway.saman.merchantId'),

		];
	}

	/**
	 * {@inheritdoc}
	 */
	public function redirect()
	{
		$redirectUrl = $this->getCallback();
		$invoiceNumber = $this->transactionId();
        $token = $this->refId();
		$amount = $this->amount;
        $url = $this->gateUrl;

		return view('gateway::saman-redirector')->with(compact('url', 'redirectUrl', 'token'));
	}

	/**
	 * {@inheritdoc}
	 */
	public function verify($transaction)
	{
		parent::verify($transaction);

		$this->verifyPayment();

		return $this;
	}

	/**
	 * Sets callback url
	 * @param $url
	 */
	function setCallback($url)
	{
		$this->callbackUrl = $url;
		return $this;
	}

	/**
	 * Gets callback url
	 * @return string
	 */
	function getCallback()
	{
		if (!$this->callbackUrl)
			$this->callbackUrl = $this->config->get('gateway.saman.callback-url');

		return $this->makeCallback($this->callbackUrl, ['transaction_id' => $this->transactionId()]);
	}

	/**
	 * Send pay request to server
	 *
	 * @return void
	 *
	 * @throws SadadException
	 */
	protected function sendPayRequest()
	{
		$this->newTransaction();

		$this->form = '';

		try {
			$amount = $this->amount;
			$soapClient = new SoapClient($this->serverTokenUrl);

			if (!$soapClient) {
				throw new MerchantException("NoSOAP", 407);
			}

			$response = $soapClient->RequestToken($this->config->get('gateway.saman.merchantId'),$this->transactionId(),$this->amount);

		} catch (\SoapFault $e) {
			$this->transactionFailed();
			$this->newLog('SoapFault', $e->getMessage());
			throw $e;
		}

		if (!isset($response)) {
			$this->newLog(SamanResult::INVALID_RESPONSE_CODE, SamanResult::INVALID_RESPONSE_MESSAGE);
			throw new SamanException(SamanResult::INVALID_RESPONSE_MESSAGE, SamanResult::INVALID_RESPONSE_CODE);
		}

		$this->refId = $response;

		$this->transactionSetRefId();
	}

	/**
	 * Verify user payment from bank server
	 *
	 * @throws SamanException
	 */
	protected function verifyPayment()
	{
		try {
			$soap = new SoapClient($this->serverUrl);

            $this->refId = Input::get('RefNum');
            $this->trackingCode = Input::get('TRACENO');
            $this->cardNumber = Input::get('SecurePan');
			$result = $soap->VerifyTransaction($this->refId(),$this->config->get('gateway.saman.merchantId'));
			if($this->amount != $result){
    			$this->newLog(Enum::TRANSACTION_FAILED, Enum::TRANSACTION_FAILED_TEXT);
				throw new SamanException(Enum::TRANSACTION_FAILED_TEXT, $result);
			}
		} catch (\SoapFault $e) {
			$this->transactionFailed();
			$this->newLog('SoapFault', $e->getMessage());
			throw $e;
		}

		if (empty($result))
			throw new SamanException('در دریافت اطلاعات از بانک خطایی رخ داده است.');

		//$this->newLog($statusResult, $message['fa']);

		if ($result > 0) {
			$this->transactionSetRefId();
			$this->transactionSucceed();
		} else {
			$this->transactionFailed();
			throw new SamanException('عدم تطابق مبلغ با بانک', $result);
		}
	}

	/**
	 * Register error to error list
	 *
	 * @param int $code
	 * @param string $message
	 *
	 * @return array|null
	 *
	 * @throws SamanException
	 */
	private function getMessage($code, $message)
	{
		$result = SamanResult::codeResponse($code, $message);
		if (!$result) {
			$result = array(
				'code' => SamanResult::UNKNOWN_CODE,
				'message' => SamanResult::UNKNOWN_MESSAGE,
				'fa' => 'خطای ناشناخته',
				'en' => 'Unknown Error',
				'retry' => false
			);
		}

		return $result;
	}
}
