<?php
namespace Mtc\Plugins\Judopay\Classes;

use Basket;
use Mtc\Core\Models\CountryState;
use Mtc\Modules\BlackList\Classes\BlackList;
use Mtc\Modules\Members\Models\Member;
use Mtc\Plugins\AccountVerifier\Classes\AccountVerifier;
use Mtc\Plugins\AccountVerifier\Classes\AccountVerifierSettings;
use Mtc\Shop\Order;
use Mtc\Shop\Order\Note;

class Judopay
{
    public const NAME = 'Judopay';
    public const SUCCESS_URL = SITE_URL . '/shop/checkout/judopay/webhook/success/';
    public const CANCEL_URL = SITE_URL . '/shop/checkout/judopay/webhook/cancel/';
    public const REDIRECT_URL = SITE_URL . '/shop/checkout/judopay/process/';

    public static function form()
    {
        $twig = app('twig');

        echo $twig->render('Judopay/form.twig', [
            'dev'       => config('judopay.testmode'),
        ]);
    }

    public static function canExpressCheckout()
    {
        global $member;

        $basket = new Basket();

        $basket->Go_Basket();

        return !empty($member->id) && ($basket->require_id_check ? !empty($member->passed_id_check) : true);
    }

    public static function saveOrderPayment($method, \Order $order, array $data)
    {
        $payment = JudopayPayment::query()->create([
            'order_id'                  => $order->getId(),
            'receipt_id'                => $data['receiptId'],
            'type'                      => $data['type'],
            'acquirer_transaction_id'   => $data['acquirerTransactionId'] ?? NULL,
            'amount'                    => $data['amount'],
            'currency'                  => $data['currency'],
            'trx_ref'                   => $data['yourPaymentReference'],
            'method'                    => $method,
        ]);

        \Mtc\Shop\Order::query()
            ->where('id', $order->getId())
            ->update([
                'order_ref'     => $payment->ref,
            ]);

        return $payment;
    }

    public static function getService($config = NULL)
    {
        return new JudopayService($config ?: judopayConfig());
    }

    public static function initializePayment(\Order $order)
    {
        $payment = JudopayPayment::query()
            ->where('order_id', $order->getId())
            ->first();

        if(empty($payment)) return;

        $order->judopay_payment = $payment;
        $order->order_ref = $order->order_ref ?? NULL ?: $payment->ref;
        $order->payment_gateway = self::NAME;
        $order->amount_paid = $payment->amount;

        switch ($payment->method) {
            case 'apay':
                $order->payment_gateway = 'Apple Pay';
                $order->payment_icon = '/plugins/Judopay/images/payment/apay.png';
                break;
            case 'gpay':
                $order->payment_gateway = 'Google Pay';
                $order->payment_icon = '/plugins/Judopay/images/payment/gpay.png';
                break;
            default:
                $order->payment_gateway = 'JudoPay';
                $order->payment_icon = '/plugins/Judopay/images/payment/judo.png';
                break;
        }

        return true;
    }

    public static function finalizePayment(string $method, \Order $order, array $payment)
    {
        if(!empty($order->paid)
            || ($payment['result'] ?? '') !== 'Success') {
            return false;
        }

        self::saveOrderPayment($method, $order, $payment);
        $order->markPaid(self::NAME);
        $order->sendOrderConfirmation();

        if (defined('PPC_TRACKING') && PPC_TRACKING) {
            track('sale', $order->getTotalCost(), $order->ref, $order->keywords);
        }

        return true;
    }

    public static function displayPaymentDetails(\Order $order)
    {
        if(empty($payment = $order->judopay_payment ?? NULL)) return;

        echo app('twig')->render('Judopay/admin/payment.twig', [
            'payment'       => $payment,
        ]);
    }

    public static function handleRefund($order_id, $amount)
    {
        $amount = number_format($amount, 2);
        $judoay_payment = JudopayPayment::query()
            ->where('order_id', $order_id)
            ->firstOrFail();
        $order = optional(Order::query()->find($order_id));
        $site = $order->info->multisite__site_id ?? 'none';
        $judoay = self::getService(config("judopay.s{$site}"));
        $refund = $judoay->createRefund([
            'receiptId' => $judoay_payment->receipt_id,
            'amount' => $amount,
            'yourPaymentReference' => $judoay_payment->trx_ref . '-REFUND-' . time()
        ]);
        $res = ($refund['receiptId'] ?? 'error');

        Note::query()
            ->create([
                'order_id' => $order_id,
                'note' => 'A Judopay refund request for £' . $amount . ' has been sent and the following response has been received: ' . $res,
            ]);
    }

    public static function validateBasket(\Basket $basket) {
        global $basket_countries;

        /** @var Member $member */

        $errors = $basket->validate([
            'terms'     => true,
            'basket'    => (array) $basket,
        ], $basket_countries, CountryState::getCountryStateList());

        $blacklist = new BlackList();
        $blacklist_flag_type = $blacklist->isBlacklisted([
            'telephone'     => $basket->info['contact_no'],
            'email'         => $basket->info['email'],
            'address'       => $basket->address['billing']['postcode']
        ]);

        if($blacklist_flag_type > 0) {
            $basket->addBasketFlag($blacklist_flag_type);
        }

        if ($blacklist_flag_type === BlackList::HARD_BLACKLIST_FLAG) {
            $errors['terms'] = "We're sorry we are unable to process this order due to suspected account misuse. If you think this is an error, please contact us";
        }

        if (ACCOUNT_VERIFIER) {
            if (
                VERIFY_EMAIL &&
                !AccountVerifier::emailVerified($basket->info['email']) &&
                AccountVerifierSettings::query()->where('code', 'enable_email_verification')->where('value', '1')->count() > 0
            ) {
                $errors['info']['email'] = 'Please verify your email address before proceeding!';
            }
            if (
                VERIFY_SMS &&
                !AccountVerifier::phoneVerified($basket->info['phone_prefix'] . $basket->info['contact_no']) &&
                AccountVerifierSettings::query()->where('code', 'enable_phone_verification')->where('value', '1')->count() > 0
            ) {
                $errors['info']['contact_no'] = 'Please verify your phone number before proceeding!';
            }
        }

        return $errors;
    }
}