<?php

namespace apexl\Io\modules\payment\controllers;

use apexl\Config\Singleton;
use apexl\encryption\Encrypt;
use apexl\Io\includes\Controller;
use apexl\Io\includes\Routes;
use apexl\Io\includes\System;
use apexl\Io\modules\display\components\BasicLink;
use apexl\Io\modules\display\components\EntityDisplayTile;
use apexl\Io\modules\display\components\EntityFilteredDisplayTable;
use apexl\Io\modules\display\components\RowWrapper;
use apexl\Io\modules\payment\entities\paymentEntity;
use apexl\Io\modules\payment\entities\paymentTokenEntity;
use apexl\Io\modules\payment\entities\userCreditEntity;
use apexl\Io\modules\payment\providers\stripeProvider;
use apexl\Io\modules\payment\services\cardValidationService;

use apexl\Io\modules\payment\services\paymentService;
use apexl\Io\modules\payment\services\woocommerceIntegrationService;
use apexl\Io\modules\subscription\entities\subscriptionEntity;
use apexl\Io\modules\user\entities\userEntity;
use apexl\Io\modules\user\services\currentUser;
use apexl\Io\modules\user\services\userTools;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

class paymentTokenController extends Controller{

    protected $currentUser;

    public function __construct(currentUser $currentUser)
    {
        parent::__construct();
        $this->currentUser = $currentUser::getCurrentUser();
    }

    public function updatePaymentToken(Request $request, Response $response, $args)
    {
        $body = $request->getParsedBody();

        $paymentTokenEntity = new paymentTokenEntity();
        $paymentTokenEntity->load($body->tokenId);

        if ($this->currentUser->id != $paymentTokenEntity->user_id && !$this->currentUser->isAllowed('AccessGlobalEntities')
            || !isset($paymentTokenEntity->id)) {
            $this->output::addMessage('payment.token.edit', 'error', 'Not found');
            $this->output::addResponse($request, [], FALSE); // added so we can hook into this elsewhere.
            return System::asJson($response, [], 404);
        }

        $paymentTokenEntity->default_token = 0;
        if ($body->default_token) {
            $paymentTokenEntity->removeDefaultForUser($paymentTokenEntity->user_id); // Set default to 0 for all other tokens
            $paymentTokenEntity->default_token = 1;
        }
        $paymentTokenEntity->ref = trim($body->ref);
        $paymentTokenEntity->store();

        $this->output::addMessage(
            'payment.token.edit.complete',
            'success',
            "Card {$paymentTokenEntity->id} was updated."
        );
        $this->output::addMetadata(
            'payment.token.edit.redirect',
            'redirect',
            Routes::getRoutePattern('payment.display.payment-details')
        );


        return System::asJson($response, []);
    }

    public function deletePaymentToken(Request $request, Response $response, $args)
    {
        $body = $request->getParsedBody();

        $paymentTokenEntity = new paymentTokenEntity();
        $paymentTokenEntity->load($body->tokenId);

        if ($this->currentUser->id != $paymentTokenEntity->user_id && !$this->currentUser->isAllowed('AccessGlobalEntities') && !$this->currentUser->hasRole(1)
            || !isset($paymentTokenEntity->id)) {
            $this->output::addMessage('payment.token.delete', 'error', 'Not found');
            $this->output::addResponse($request, [], FALSE); // added so we can hook into this elsewhere.
            return System::asJson($response, [], 404);
        }

        $paymentTokenEntity->deleted = 1;
        $paymentTokenEntity->store();
        $this->output::addMessage('payment.token.delete.success', 'success',"Token #{$paymentTokenEntity->id} successfully deleted");
        $this->output::addMetadata(
            'payment.token.delete.redirect',
            'redirect',
            Routes::getRoutePattern('payment.display.payment-details')
        );

        return System::asJson($response, []);
    }

    public function paymentTokenListTableDataBasic(Request $request, Response $response, $args)
    {
        $params = $request->getQueryParams();
        $components = [];
        $config = Singleton::getInstance();
        $stripe = new stripeProvider();
        $paymentToken = new paymentTokenEntity();

        $userEntity = new userEntity();
        if (isset($args['userId']) && $args['userId'] > 0) {
            $userEntity->load($args['userId']);
        } else {
        $currentUser = currentUser::getCurrentUser();
        $email = $params['userEmail'] ?? $currentUser->email;
        $userEntity->getUserByEmail($email);
        }

        $tokens = $paymentToken->getByUser($userEntity->id);
        $paymentService = new paymentService();

        $entityData['tableHeader'] = ['#', 'Type', 'Name', 'Description', 'Default?'];

        $rows = [];
        foreach ($tokens as $token) {
            if ($token->setup_complete == 1 && $token->deleted == 0) {

                $providerData = $paymentService->getTokenProviderData($token);

                if (!is_null($providerData)) {
                    $description = ucfirst($providerData->funding) . ' card ending in **** '.$providerData->last4 . '<br>expires: '.$providerData->exp_month.'/'.$providerData->exp_year;
                    if ($token->abandoned == '1') {
                        $description .= '<br><span class="text-danger fw-bold">Disabled due to multiple failed payment attempts</span>';
                    }

                    $rows[] = [
                        'id' => $token->id,
                        'type' => $providerData->brand,
                        'name' => $token->ref,
                        'description' => ucfirst($providerData->funding) . $description,
                        'default' => $token->default_token ? '<strong>default</strong>' : '',
                    ];
                }
            }
        }

        $entityData['rows'] = $rows;
        $entityData['totalData'] = count($rows);

        return System::asJson($response, $entityData);
    }
}