<?php

namespace app\controllers;

use Yii;
use yii\web\Controller;
//additional
use app\models\Store;
use app\models\ShopifyClient;
use app\models\Configurations;
use app\models\Orders;
use app\models\Refunds;
use SquareConnect;

class RefundController extends Controller
{
    public function beforeAction($action) {
        $this->enableCsrfValidation = false;
        return parent::beforeAction($action);
    }

    public function actionSync()
    {
        ignore_user_abort(true);
        ob_start();
        $serverProtocole = filter_input(INPUT_SERVER, 'SERVER_PROTOCOL', FILTER_SANITIZE_STRING);
        header($serverProtocole . ' 200 OK');
        header('Content-Encoding: none');
        header('Content-Length: ' . ob_get_length());
        header('Connection: close');
        ob_end_flush();
        ob_flush();
        flush();
        
        $webhookContent = '';
        $webhook = fopen('php://input', 'rb');
	while (!feof($webhook)) {
	    $webhookContent .= fread($webhook, 4096);
	}

        $logs = fopen("hooks_log.txt", "a") or die("Unable to open file!");
        fwrite($logs, "\n\n [".date("Y-m-d H:i:s A")."] Refund: $webhookContent\n\n");

        $shop = Yii::$app->request->get('shop');
	$_refund = json_decode($webhookContent, true);

        $order_id = $_refund['order_id'];
        //fwrite($logs, $order_id);
        //fwrite($logs, json_encode($_refund['transactions']));
        //fwrite($logs, json_encode($_refund['transactions'][0]));
        $currency = count($_refund['transactions']) > 0 ? $_refund['transactions'][0]['currency'] : "USD";
        $status = count($_refund['transactions']) > 0 ? $_refund['transactions'][0]['status'] : "";
        $transaction_id = count($_refund['transactions']) > 0 ? $_refund['transactions'][0]['id'] : "";
        //fwrite($logs, count($_refund['transactions']));
        $reason = $_refund['note'];
        $amount = 0;
        if(count($_refund['transactions']) > 0) {
            foreach($_refund['transactions'] as $transaction) {
                //fwrite($logs, $transaction['amount']);
                $amount += (int)($transaction['amount'] * 100);
            }
        }
  
        $order = Orders::find()->where(['order_id' => $order_id])->one();
//        $store = Store::find()->where(['shop' => $shop])->one();

        //fwrite($logs, $order->id);
        //fwrite($logs, $amount);
        if($order !== null) {// && $store !== null) {
//            fwrite($logs, 'under order \n\n');

            // check sandbox or live.
            $config = Configurations::find()->where(['meta_key' => $shop . '_square_detail'])->one();
            $square_config = unserialize($config->meta_value);
            if (isset($square_config['sandbox']) && $square_config['sandbox'] == '1') {
                $sandbox = TRUE;
            } else {
                $sandbox = FALSE;
            }

            // Set Square API credentials.
            $host = $sandbox ? 'https://connect.squareupsandbox.com' : 'https://connect.squareup.com';
            $access_token = $sandbox ? $square_config['sandbox_access_token'] : $square_config['live_access_token'];

            fwrite($logs, "{$config->id} -- ");
            # setup authorization
            $api_config = new \SquareConnect\Configuration();
            $api_config->setHost($host);
            $api_config->setAccessToken($access_token);
            $api_client = new \SquareConnect\ApiClient($api_config);

            # create an instance of the Payments API class
            $refund_api = new \SquareConnect\Api\RefundsApi($api_client);

            $body = new \SquareConnect\Model\RefundPaymentRequest();

            $amountMoney = new \SquareConnect\Model\Money();

            # Monetary amounts are specified in the smallest unit of the applicable currency.
            # This amount is in cents. It's also hard-coded for $1.00, which isn't very useful.
            $amountMoney->setAmount($amount);
            $amountMoney->setCurrency($currency);

            $body->setPaymentId($order->sequare_payment_id);
            $body->setAmountMoney($amountMoney);
            $body->setReason($reason);

            # Every payment you process with the SDK must have a unique idempotency key.
            # If you're unsure whether a particular payment succeeded, you can reattempt
            # it with the same idempotency key without worrying about double charging
            # the buyer.
            $body->setIdempotencyKey(uniqid());
            fwrite($logs, "\n\n $amount -- $currency -- $order->sequare_payment_id");

            try {
                $result = $refund_api->refundPayment($body);
//                fwrite($logs, json_encode($result->getRefund()));
                if($result->getErrors()) {
                    fwrite($logs, "\n Error from Square: ".json_encode($result->getErrors()));
                } else {
                    $model = new Refunds();
                    $model->store_id = $order->store_id;
                    $model->order_id = $order_id;
                    $model->refund_id = $_refund['order_id'];
                    $model->refund_status = $status;
                    $model->transaction_id = $transaction_id;
                    $model->square_refund_id = $result->getRefund()->getId();
                    $model->status = $result->getRefund()->getStatus();
                    $model->amount = $result->getRefund()->getAmountMoney()->getAmount();
                    $model->reason = $result->getRefund()->getReason();
                    $model->currency = $result->getRefund()->getAmountMoney()->getCurrency();
                    $model->save(false);
                }
                
                fwrite($logs, $result->getRefund()->getId()."--".$result->getRefund()->getStatus()."--".$result->getRefund()->getAmountMoney()->getAmount());
                return true;
            } catch (Exception $e) {
                fwrite($logs, "\n Exception from Square: ".$e->getMessage());
//                echo 'Exception when calling RefundsApi->refundPayment: ', $e->getMessage(), PHP_EOL;
            }
        }
        return true;
    }
}
