<?php
namespace apexl\Io\modules\subscriptionDisplay\controllers;

use apexl\Io\includes\Controller;
use apexl\Io\includes\Routes;
use apexl\Io\includes\System;
use apexl\Io\modules\company\entities\companyEntity;
use apexl\Io\modules\display\components\ButtonBar;
use apexl\Io\modules\display\components\CardEntityFilteredDisplayTable;
use apexl\Io\modules\display\components\ColWrapper;
use apexl\Io\modules\display\components\ContentTitle;
use apexl\Io\modules\display\components\DisplayTable;
use apexl\Io\modules\display\components\EntityFilteredDisplayTable;
use apexl\Io\modules\display\components\FormComponent;
use apexl\Io\modules\display\components\genericComponents;
use apexl\Io\modules\display\components\RowWrapper;
use apexl\Io\modules\display\includes\Forms;
use apexl\Io\modules\display\services\Render;
use apexl\Io\modules\formbuilder\entities\formEntity;
use apexl\Io\modules\formbuilder\includes\checkboxField;
use apexl\Io\modules\formbuilder\includes\inputField;

use apexl\Io\modules\formbuilder\includes\selectField;
use apexl\Io\modules\formbuilder\includes\toggleField;
use apexl\Io\modules\product\entities\productEntity;
use apexl\Io\modules\subscription\entities\subscriptionEntity;
use apexl\Io\modules\subscription\services\subscriptionService;
use apexl\Io\modules\user\entities\userEntity;
use apexl\Io\modules\subscriptionDisplay\components\viewTiles;
use apexl\Io\modules\user\services\currentUser;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

class adminSubscriptionController extends Controller
{
    /** @var Render */
    protected $render;

    public function __construct(Render $render)
    {
        parent::__construct();
        $this->render = $render;
    }

    public function overview(Request $request, Response $response)
    {
        $table = new EntityFilteredDisplayTable((new subscriptionEntity()));
        $table->src(Routes::getRoutePattern('subscription.wordpress.order.data'));
        $table->setFilters('orderBy[]=missing_sims&orderBy[]=DESC&orderBy[]=subscription.id&orderBy[]=DESC');
        $table->addFilterForm('subscriptionDisplay.form.subscriptions.filter', null, 5, true, "Filter Subscriptions");

        //render
        $this->render::setPageTitle('Payment Credit Card Subscriptions');
        $this->output::addResponse($request, $this->render::build($table));
        return System::asJson($response);
    }

    public function subscriptionViewSingle(Request $request, Response $response, $id){

        //Subscription tile
        $subscription = new subscriptionEntity();
        $subscription->load($id['id']);

        $buttonBar = new ButtonBar();
        $buttonBar->setEntity($subscription);

        $panel = (new RowWrapper())->addClass('manageForm-wrapper')
            ->addComponent(viewTiles::subscriptionViewTile($subscription));
        $this->render::setPageTitle('Subscription #'.$subscription->id);
        $this->output::addResponse($request, $this->render::build([$buttonBar, $panel]));

        return System::asJson($response);
    }

    /**
     * @param Request $request
     * @param Response $response
     * @param array $args
     * @return Response
     * @throws \Exception
     */
    public function createUpdateSubscription(Request $request, Response $response, $args = []){
        $title = 'Create a subscription';
        $subscriptionEntity = new subscriptionEntity();

        if($id = $args[$subscriptionEntity->primaryKey] ?? FALSE){
            $subscriptionEntity->load($id);
            $title = 'Edit subscription #'. $subscriptionEntity->id;
            //Info Bar
            $infoBar = (new RowWrapper());
            $userEntity = new userEntity();
            $userEntity->load($subscriptionEntity->user_id);
            $userTitle = genericComponents::ContentTitle('User', $userEntity->first_name. ' '.$userEntity->last_name, 5, 'col');
            $userEmail = genericComponents::ContentTitle('Email', $userEntity->email, 5, 'col');


            $productEntity = new productEntity();
            $productEntity->load($subscriptionEntity->product_id);
            $productTitle = genericComponents::ContentTitle('Product', $productEntity->product_name, 5, 'col');
            $infoBar->addComponent($userTitle);
            $infoBar->addComponent($userEmail);
            if (class_exists('apexl\Io\modules\company\entities\companyEntity')) {
                $companyEntity = new companyEntity();
                $companyEntity->loadByUser($subscriptionEntity->user_id);
                $companyTitle = genericComponents::ContentTitle('Company', $companyEntity->CompanyName, 5, 'col');
            $infoBar->addComponent($companyTitle);
            }
            $infoBar->addComponent($productTitle);
        }

        $buttonBar = new ButtonBar();
        $buttonBar->setEntity($subscriptionEntity, $args[$subscriptionEntity->primaryKey]?'Edit':'Create');


        $form1 = (new FormComponent())->setID('subscriptionCreate1')->src(Routes::getRoutePattern('subscriptionDisplay.form.subscriptions.createUpdate', $args));

        $components = [];
        $components[] = $buttonBar;
        if($args[$subscriptionEntity->primaryKey] ?? FALSE){
            $components[] = $infoBar;
        }

        $components[] = $form1;

        $this->render::setPageTitle($title);
        $this->render::setActive("modal");
        $this->output::addResponse($request, $this->render::build($components));
        return System::asJson($response);
    }

    public function changeSubscription(Request $request, Response $response, $args = [])
    {
        $subscriptionEntity = new subscriptionEntity();
        $subscriptionEntity->load($args['id']);
        if (!isset($subscriptionEntity->id)) {
            return System::asJson($response, [], 404);
        }

        $currentUser = currentUser::getCurrentUser();
        if(!$currentUser->isAllowed('ManageUsers') && !$currentUser->isAllowed('UpdateSubscriptions') && $currentUser->id != $subscriptionEntity->user_id) {
            return System::asJson($response, [], 403);
        }

        $subscriptionInfo = viewTiles::subscriptionDetailsTable($subscriptionEntity);
        $changeTile = viewTiles::changeSubscriptionTile($subscriptionEntity, $args);

        $rowWrapper = (new RowWrapper())
            ->addComponent((new ColWrapper())
                ->addComponent($subscriptionInfo)
            )->addComponent((new ColWrapper())
                ->addComponents([$changeTile])
            );

        $this->render::setActive("modal");
        $this->output::addResponse($request, $this->render::build($rowWrapper));

        return System::asJson($response);
    }

    public function restartSubscription(Request $request, Response $response, $args = [])
    {
        $subId = $args['subscriptionId'] ?? $args['id'];

        $subscriptionEntity = new subscriptionEntity();
        $subscriptionEntity->load($subId);
        if (!isset($subscriptionEntity->id)) {
            return System::asJson($response, [], 404);
        }

        $currentUser = currentUser::getCurrentUser();
        if(!$currentUser->isAllowed('ManageUsers') && !$currentUser->isAllowed('UpdateSubscriptions') && $currentUser->id != $subscriptionEntity->user_id) {
            return System::asJson($response, [], 403);
        }

        $subscriptionInfo = viewTiles::subscriptionDetailsTable($subscriptionEntity, 'Previous Subscription Details');
        $restartTile = viewTiles::restartSubscriptionTile($subscriptionEntity, $args);

        $rowWrapper = (new RowWrapper())
            ->addComponent((new ColWrapper())
                ->addComponent($subscriptionInfo)
            )->addComponent((new ColWrapper())
                ->addComponents([$restartTile])
            );

        $this->render::setActive("modal");
        $this->output::addResponse($request, $this->render::build($rowWrapper));

        return System::asJson($response);
    }

    public function changeSubscriptionForm(Request $request, Response $response, $args){

        $subscription = new subscriptionEntity();
        $subscription->load($args['id']);

        $form = new formEntity();
        $form->setId('ChangeSubscription');
        $form->setMethod('post');
        $form->setActionUrl(Routes::getRoutePattern('subscription.change', $args));
        $form->setSubmitText('Save');
        $productEntity = new productEntity();
        $products = $productEntity->getAll();
        $options = [];
        foreach ($products as $product) {
            if (trim($product->product_name) != "" && $product->price > 0 && $subscription->product_id != $product->id && $product->frontend_id > 0) {
                $options[$product->id] = $product->product_name . " - £{$product->price} exc. VAT per month";
            }
        }
        $form->addField((new selectField('product_id', $options))->setPlaceholder('Please select one...')->setLabel("New Product*")->isRequired()->addClass('w-100'));
        $form->addField((new checkboxField('acceptTerms'))->setLabel("I have read and agree to the above terms and conditions and understand that I will be billed immediately for one months subscription fee*"));
        $form->addField((new inputField("subscription_id"))->setValue($args['id'])->setInputType('hidden'));

        return System::asJson($response, $form->getBuiltFormArray());
    }

    public function restartSubscriptionForm(Request $request, Response $response, $args){

        $subscription = new subscriptionEntity();
        $subscription->load($args['id']);

        $form = new formEntity();
        $form->setId('RestartSubscription');
        $form->setMethod('post');
        $form->setActionUrl(Routes::getRoutePattern('subscription.restart', $args));
        $form->setSubmitText('Save');
        $productEntity = new productEntity();
        $products = $productEntity->getAll();
        $options = [];
        foreach ($products as $product) {
            if (trim($product->product_name) != "" && $product->price > 0 && $product->frontend_id > 0) {
                $options[$product->id] = $product->product_name . " - £{$product->price} exc. VAT per month";
            }
        }
        $form->addField((new selectField('product_id', $options))->setValue($subscription->product_id)->setLabel("Product*")->isRequired()->addClass('w-100'));
        $form->addField((new checkboxField('acceptTerms'))->setLabel("I have read and agree to the above terms and conditions and understand that I will be billed immediately for one months subscription fee*"));
        $form->addField((new inputField("prevous_subscription_id"))->setValue($args['id'])->setInputType('hidden'));
        $form->addField((new inputField("meta"))->setValue($args['meta'])->setInputType('hidden'));

        return System::asJson($response, $form->getBuiltFormArray());
    }

    public function suspendSubscription(Request $request, Response $response, $args = [])
    {
        $subId = $args['subscriptionId'] ?? $args['id'];

        $subscriptionEntity = new subscriptionEntity();
        $subscriptionEntity->load($subId);
        if (!isset($subscriptionEntity->id)) {
            return System::asJson($response, [], 404);
        }

        $currentUser = currentUser::getCurrentUser();
        if(!$currentUser->isAllowed('ManageUsers') && !$currentUser->isAllowed('UpdateSubscriptions') && $currentUser->id != $subscriptionEntity->user_id) {
            return System::asJson($response, [], 403);
        }

        $subscriptionInfo = viewTiles::subscriptionDetailsTable($subscriptionEntity);
        $suspendTile = viewTiles::suspendSubscriptionTile($subscriptionEntity);

        $rowWrapper = (new RowWrapper())
            ->addComponent((new ColWrapper())
                ->addComponent($subscriptionInfo)
            )->addComponent((new ColWrapper())
                ->addComponents([$suspendTile])
            );

        $this->render::setActive("modal");
        $this->output::addResponse($request, $this->render::build($rowWrapper));

        return System::asJson($response);
    }

    /**
     * @param Request $request
     * @param Response $response
     * @param $args
     * @return Response
     */
    public function createUpdateSubscriptionForm(Request $request, Response $response, $args){

        $subscription = new subscriptionEntity();
        $subscription->load($args['id']);

        $form = new formEntity();
        $form->setId('UpdateSubscription');
        $form->setMethod('post');
        $form->setActionUrl(Routes::getRoutePattern('subscription.update'));
        $form->setSubmitText('Save');

        $productEntity = new productEntity();
        $products = $productEntity->getAll();
        $options = [];
        foreach ($products as $product) {
            if (trim($product->product_name) != "") {
                $options[$product->id] = $product->product_name;
            }
        }

        $form->addField((new selectField('product_id', $options))->setLabel("Product*")->isRequired()->setValue($subscription->product_id)->addClass('col-xl-6'));
        $form->addField((new inputField('product_quantity'))->setLabel('Product Quantity*')->setInputType('number')->isRequired()->setValue($subscription->product_quantity)->addClass('col-xl-6'));
        $form->addField((new inputField('next_billing_date'))->setLabel("Next Billing Date*")->addClass('col col-xl-6')->setPlaceholder('yyyy-mm-dd')->isRequired()->setValue($subscription->next_billing_date));
        $form->addField((new toggleField('enabled'))->setLabel("Subscription Active?")->addClass('col col-xl-6')->setValue($subscription->enabled ? TRUE : FALSE));
        $form->addField((new inputField("subscription_id"))->setValue($args['id'])->setInputType('hidden'));

        return System::asJson($response, $form->getBuiltFormArray());
    }

    public function troubleshoot(Request $request, Response $response)    {

        $path = Routes::getRoutePattern('subscriptionEntity.display.put.override', [], false);
        $path2 = Routes::getRoutePattern('userEntity.display.get.override', [], false);
        $table = (new CardEntityFilteredDisplayTable(new subscriptionEntity(), [], false))
            ->addTitle('Troubleshoot Subscriptions')
            ->addClass('subscription-troubleshoot-table')
            ->src(Routes::getRoutePattern('subscription.data.troubleshoot'))
            ->addClass('subscription-table')
            ->addDropMenuItem('userEntity.display.get'.($path2?'.override':''), 'Go to User','','get',null,false,false,['id'=>'userId'])
            ->addDropMenuModal('Edit', 'Edit Subscription', [], 'subscriptionEntity.display.put'.($path?'.override':''))
            ->addDropMenuModal('Suspend', 'Suspend Subscription', [], 'subscriptionDisplay.suspend', (object)['col' => 'status', 'val' => 'Active'])
            ->addProperty('refreshButton', '<i class="fa-light fa-arrows-rotate"></i>')
        ;

        //render
        $this->render::setPageTitle('Troubleshoot Subscriptions');
        $this->output::addResponse($request, $this->render::build($table));
        return System::asJson($response);
    }
}