<?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\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";
        }

        return $errors;
    }
}
