<?php
declare (strict_types = 1);
namespace ProxyPay\Pages;

use Podeli\Payment\Client;
use Podeli\Payment\Methods;
use ProxyPay\Core\Page;
use ProxyPay\Core\Retailcrm;
use ProxyPay\Core\Utils;
use ProxyPay\Traits\Log;

class Callback extends Page
{
	use Log;

	public function actionIndex()
	{

		$post = $_REQUEST;

		$shopData = $this->db->pQuery("
			SELECT
				c.url, c.settings, s.settings as shop_settings
			FROM shops as s
			LEFT JOIN clients as c on c.client_id=s.client_id
			WHERE s.shop_id=:shop_id: and s.client_id=:client_id:", [
			'shop_id'   => $post['shop_id'] ?? '',
			'client_id' => $post['client_id'] ?? '',
		])->fetch_assoc();

		if (!$shopData) {
			throw new \Exception("Shop not found", 1);
		}

		$result = $this->db->pQuery("SELECT * FROM transactions where payment_id=:uuid:", ['uuid' => $post['uuid'] ?? '']);
		$data   = $result->fetch_assoc();

		$transactionInfo = Utils::decode($data['info'], $post['uuid'] . $this->config->cipher_key);

		$shopSettings = Utils::decode($shopData['shop_settings'], $this->config->cipher_key);

		$settings = Utils::decode($shopData['settings'], $this->config->cipher_key);

		$api = new Client($shopSettings['login'], $shopSettings['password']);
		$api->setCertPath($shopSettings['cert_text']);
		$api->setKeyPath($shopSettings['key_text']);
		$api->useCurl();
		if ($shopSettings['sandbox']) {
			$api->setSandboxMode();
		}

		$method = new Methods\Info($api);
		$method->setOrderId($post['uuid']);
		$info = $method->execute();

		if (!$info) {
			throw new \Exception('Order Not found');
		}

		//$info['shop_id'] = intval($post['shop_id']);
		$transactionInfo = array_merge($transactionInfo, $info);

		$infoEncoded = Utils::encode($transactionInfo, $post['uuid'] . $this->config->cipher_key);
		$this->db->pQuery("REPLACE INTO transactions (payment_id, info) values (:uuid:,:info:)", [
			'uuid' => $post['uuid'],
			'info' => $infoEncoded,
		]);

		$invoice = [];

		if ($info['order']['status'] == 'WAIT_FOR_COMMIT') {
			list($date) = explode('.', $info['order']['date']);
			$date       = date('Y-m-d H:i:s', strtotime($date) + 6 * 60 * 60);
			$invoice    = [
				'invoiceUuid' => $post['uuid'],
				'amount'      => $info['order']['amount'],
				'status'      => 'waitingForCapture',
				//'expiredAt'   => $date,
				'cancellable' => true,
			];
		}

		if ($info['order']['status'] == 'COMPLETED' && !empty($info['refund'])) {
			$refund  = end($info['refund']);
			$invoice = [
				'invoiceUuid' => $post['uuid'],
				'status'      => 'refundSucceeded',
				'refund'      => [
					'status' => 'succeeded',
					'id'     => $refund['id'],
					'amount' => $refund['totalRefundedAmount'],
				],
			];
		}

		if ($info['order']['status'] == 'REFUNDED') {
			$refund  = end($info['refund']);
			$invoice = [
				'invoiceUuid' => $post['uuid'],
				'status'      => 'refundSucceeded',
				'refund'      => [
					'status' => 'succeeded',
					'id'     => $refund['id'],
					'amount' => $refund['totalRefundedAmount'],
				],
			];
		}

		if ($info['order']['status'] == 'REJECTED') {
			$invoice = [
				'invoiceUuid' => $post['uuid'],
				'status'      => 'canceled',
			];
		}

		if ($info['order']['status'] == 'COMPLETED' && empty($info['refund'])) {

			$invoice = [
				'invoiceUuid' => $post['uuid'],
				'amount'      => $info['order']['amount'],
				'status'      => 'succeeded',
				'refundable'  => true,
			];
		}

		$this->log($invoice, 'callback');

		if (!empty($invoice)) {
			$this->log([$shopData['url'], $settings['key']], 'callback response');
			$api = new Retailcrm($shopData['url'], $settings['key']);
			$res = $api->updateInvoice($invoice);
			$this->log($res, 'callback response');
		}
	}

}
