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

use apexl\Config\Singleton;
use apexl\Io\includes\Hook;
use apexl\Io\includes\Routes;
use apexl\Io\includes\System;
use apexl\Io\modules\display\components\BasicLink;
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\Modal;
use apexl\Io\modules\display\components\SimpleButton;
use apexl\Io\modules\product\entities\productEntity;
use apexl\Io\modules\subscription\entities\subscriptionChangeEntity;
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\user\services\currentUser;
use apexl\Io\modules\userDisplay\components\dashboardTiles;
use apexl\Io\services\Logger;
use app\module\billing\entities\billingSimSettingsEntity;

class viewTiles {

    public static function getSubscriptionStatusObject($subscriptionEntity)
    {

        $obj = (object)[
            'content' => self::getSubscriptionStatusText($subscriptionEntity),
            'class' => 'warning',
        ];

        if (($subscriptionEntity->enabled == '1' && $subscriptionEntity->suspended == '0')
            || $subscriptionEntity->enabled == '1' && $subscriptionEntity->suspended == '1') {
            $obj->class = 'success';
        }

        $objMod = Hook::processHook('modify_subscription_status_lozenge', $obj, $subscriptionEntity);
        if (isset($objMod->btnContent) && isset($objMod->btnClass)) $obj = $objMod;

        return $obj;

        /*if ($clickable) {
            $button = (new Modal())
                ->setContentSrc('subscriptionDisplay.suspend', ['id' => $subscriptionEntity->id])
                ->setTitle('Subscription Status');
            $button->setButtonContent($btnData->content)->setButtonClass($btnData->class . ' btn');
        } else {
            $button = (new SimpleButton());
            $button->addText($btnData->content)->addClass($btnData->class);
        }*/
    }

    /*public static function getSuspendButton($subscriptionEntity)
    {
        $statusObj = getSubscriptionStatusObject($subscriptionEntity);

        $button = (new Modal())
            ->setContentSrc('subscriptionDisplay.suspend', ['id' => $subscriptionEntity->id])
            ->setTitle('Subscription Status');
        $button->setButtonContent($statusObj->content)->setButtonClass($statusObj->class . ' btn');
    }*/

    public static function getSubscriptionStatusText($subscriptionEntity)
    {
        $text = "Unknown";
        if ($subscriptionEntity->enabled == '1' && $subscriptionEntity->suspended == '0' && $subscriptionEntity->cancellation_date >= date('Y-m-d')) {
            $text = System::getVariable('io_subscription_pending_cancellation_not_suspended_text') ?? 'Active, Pending Cancellation';
        } elseif ($subscriptionEntity->enabled == '1' && $subscriptionEntity->suspended == '1' && $subscriptionEntity->cancellation_date >= date('Y-m-d')) {
            $text = System::getVariable('io_subscription_pending_cancellation_suspended_text') ?? 'Active, Pending Cancellation';
        } elseif ($subscriptionEntity->enabled == '1' && $subscriptionEntity->suspended == '0') {
            $text = System::getVariable('io_subscription_active_not_suspended_text') ?? 'Active';
        } elseif ($subscriptionEntity->enabled == '0' && $subscriptionEntity->suspended == '1') {
            $text = System::getVariable('io_subscription_inactive_suspended_text') ?? 'Inactive';
        } elseif ($subscriptionEntity->enabled == '1' && $subscriptionEntity->suspended == '1') {
            $text = System::getVariable('io_subscription_active_suspended_text') ?? 'Active';
        } elseif ($subscriptionEntity->enabled == '0' && $subscriptionEntity->suspended == '0') {
            $text = System::getVariable('io_subscription_inactive_not_suspended_text') ?? 'Inactive';
        }

        $modifiedText = Hook::processHook('modify_subscription_status_text', $text, $subscriptionEntity);
        if ($modifiedText) $text = $modifiedText;

        return $text;
    }

    public static function subscriptionViewTile($subscription){
        if($subscription) {
            $currentUser = currentUser::getCurrentUser();

            $user = new userEntity();
            $user->load($subscription->user_id);
            $product = new productEntity();
            $product->load($subscription->product_id);

            $userInfo = new DisplayTable();
            $userInfo->addData('Email', $user->email);

            $subscriptionInfo = new DisplayTable();
            $subscriptionInfo->addData('Product', $product->product_name);
            $subscriptionInfo->addData('Quantity', $subscription->product_quantity);
            if (trim($subscription->price_override) != "") {
                $monthlyFee = trim($subscription->price_override);
                $monthlyFee = (float)$monthlyFee;
                $subscriptionInfo->addData('£'.number_format($monthlyFee, 2).' total  Exc. VAT');
            } else {
                $subscriptionInfo->addData('Monthly Fee', '£'.number_format($product->price, 2) . ' (£'.number_format($subscription->product_quantity*$product->price, 2).' total)  Exc. VAT');
            }

            $subscriptionInfo->addData('Nominal Code', $product->invoice_nominal_code);
            $subscriptionInfo->addData('Enabled?', ($subscription->enabled == 1 ? 'Yes' : 'No'));

            $startDate = \DateTime::createFromFormat('Y-m-d', $subscription->date_starts);
            $subscriptionInfo->addData('Started', $startDate->format('d M Y'));

            $lastBillingDate = \DateTime::createFromFormat('Y-m-d', $subscription->last_billing_date);
            if ($lastBillingDate instanceof \DateTime){
                $subscriptionInfo->addData('Last Billed on', $lastBillingDate->format('d M Y'));
            } else {
                $subscriptionInfo->addData('Last Billed on', 'N/A');
            }

            $nextBillingDate = \DateTime::createFromFormat('Y-m-d', $subscription->next_billing_date);
            $subscriptionInfo->addData('Next Billed on', $nextBillingDate->format('d M Y'));

            list($userInfo, $subscriptionInfo) = $entityData = Hook::processHook('modify_subscription_display_fields', $subscription, $userInfo, $subscriptionInfo);

            $components = [];
            $components[] = genericComponents::ContentTitle("User");
            $components[] = $userInfo;
            $components[] = genericComponents::ContentTitle("Subscription");
            $components[] = $subscriptionInfo;

            return genericComponents::dashboardBlockWrapper($components);
        } else {
            return genericComponents::dashboardBlockWrapper([]);
        }
    }

    public static function subscriptionDetailsTable(subscriptionEntity $subscriptionEntity, $title='Current Subscription Details:')
    {

        $subscriptions = $subscriptionEntity->getWithProducts([$subscriptionEntity->id]);
        $subscriptionInfo = new DisplayTable();
        $subscriptionInfo->addTitle($title);
        $statusObject = viewTiles::getSubscriptionStatusObject($subscriptionEntity);
        $subscriptionService = new subscriptionService();
        $suspensionStatus = $subscriptionService->suspendedStatus($subscriptionEntity);
        if (isset($subscriptions[0])) {
            $subscriptionDetails = $subscriptions[0];

            $statusContent = '<h5><span class="fw-bold badge rounded-pill bg-'. $statusObject->class .'">'.$statusObject->content.'</span></h5>';
            if ($suspensionStatus->label) {
                $statusContent.= "<p><small>{$suspensionStatus->label}</small></p>";
            }

            $subscriptionInfo->addData('Status', $statusContent);
            $subscriptionInfo->addData('Product Name', $subscriptionDetails->product_name);
            $subscriptionInfo->addData('Price per month', '<strong>£'.number_format($subscriptionDetails->price,2) . '</strong> ('.number_format($subscriptionDetails->price*1.2,2).' inc. VAT)');
            $subscriptionInfo->addData('Last Billing Date', $subscriptionDetails->last_billing_date);
            $subscriptionInfo->addData('Next Billing Date', $subscriptionDetails->next_billing_date);
            $subscriptionInfo->addData('Start Date', $subscriptionDetails->start_date);
        }
        $subscriptionInfo = Hook::processHook('modify_subscription_details_table', $subscriptionEntity, $subscriptionInfo);

        return $subscriptionInfo;
    }



    public static function userSubscriptionsTile($userEntity=null){

        $currentUser = currentUser::getCurrentUser();

        $subscriptionsList = (new ColWrapper())
            ->addClass('bg-white col-12');
        $subscriptionTable = (new CardEntityFilteredDisplayTable())
            ->addTitle('Subscriptions')
            ->src(Routes::getRoutePattern('subscription.data.basic'). (isset($userEntity->email) ? '?userEmail='.$userEntity->email : ''))
            ->displayPagination(FALSE)
            ->addProperty('refreshButton', '<i class="fa-light fa-arrows-rotate"></i>')
            ->displayShortTotals(FALSE)
            ->setRefreshTag('user-subscriptions-table')
            ->hideIdColumn();
        //$subscriptionTable->hideIdColumn();
        if($currentUser->isAllowed('ManageUsers') || $currentUser->isAllowed('UpdateSubscriptions')) {
            $path = Routes::getRoutePattern('subscriptionEntity.display.put.override', [], false);
            $subscriptionTable->addDropMenuModal('Edit', 'Edit Subscription', [], 'subscriptionEntity.display.put'.($path?'.override':''));
            $subscriptionTable->addDropMenuModal('Suspend', 'Suspend Subscription', [], 'subscriptionDisplay.suspend', (object)['col' => 'status', 'val' => 'Active']);
        } else {
            $subscriptionTable->addDropMenuModal('Cancel', 'Cancel Subscription', [], 'subscriptionDisplay.suspend', (object)['col' => 'status', 'valLike' => 'Active']);
            $subscriptionTable->addDropMenuModal('Change', 'Change Subscription', [], 'subscriptionDisplay.change', (object)['col' => 'status', 'valLike' => 'Active']);
        }

        $helpComponents = [
            (new ContentTitle())->addClass('text-black text-start help-modal-content-title')->addTitle('A list of recent payments, and their status'),
            (new DisplayTable())->addClass('text-black text-start help-modal-display-table')->addRows([
                ['Subscription ID', 'The internal ID of your subscription. We use this to help with support queries. It also helps you to match your SIM cards with their subscriptions.'],
                ['Created', 'The date your subscription was created'],
                ['Next Billing Date', 'The date we will take your next payment for this subscription'],
                ['Bundle', 'Your chosen monthly subscription product'],
                ['Type', 'The type of subscription. CC (Credit/Debit Card), DD (Direct Debit)'],
                ['Amount', 'The billing amount of the subscription (Inc VAT)'],
                ['Status', 'The status of your subscription. Active, Disabled, Suspended'],
                ['Actions', 'The actions menu. Click the three dots to open the actions menu to manage your subscription'],
            ])
        ];
        $subscriptionTable->addHeaderModal('Subscriptions Table', $helpComponents);

        $subscriptionTable = Hook::processHook('modify_user_subscriptions_table', $subscriptionTable);
        
        $subscriptionsList->addComponent($subscriptionTable);
        return $subscriptionsList;

    }

    public static function subscriptionInvoicesTile($subscriptionId, $cssClass="col-12")
    {
        return (new ColWrapper())
            ->addClass($cssClass)
            ->addComponent((new CardEntityFilteredDisplayTable())
                ->addTitle('Latest Invoices')
                ->setFilters('orderBy[]=invoice_date&orderBy[]=DESC')
                ->src(Routes::getRoutePattern('invoice.subscription.data.basic'). '?subscriptionId='.$subscriptionId)
                ->displayPagination(false)
                ->displayShortTotals(false)
                ->hideIdColumn()
                ->addDropMenuItem('provider.invoices.view', 'view', '', 'get', '_blank')
            );
    }

    public static function changeSubscriptionTile(subscriptionEntity $subscriptionEntity, $args)
    {
        $subscriptionChangeEntity = new subscriptionChangeEntity();
        $subscriptionChangeEntity->getMostRecentForSubscription($subscriptionEntity->id);
        $cutoff = new \DateTime('now');
        $cutoff->sub(new \DateInterval('P1M'));
        $cutoff->setTime(0, 0, 0);
        $disallowed = false;
        if (isset($subscriptionChangeEntity->timestamp)) {
            $timestamp = \DateTime::createFromFormat('Y-m-d H:i:s', $subscriptionChangeEntity->timestamp);
            if ($timestamp > $cutoff) {
                $disallowed = true;
            }
        }

        $hookResponse = (object)[];
        $hookResponse = Hook::processHook('change_subscription_is_disallowed', $hookResponse, $subscriptionEntity);

        if ($disallowed || isset($hookResponse->disallowed) && $hookResponse->disallowed) {
            $nextBillingDate = \DateTime::createFromFormat('Y-m-d', $subscriptionEntity->next_billing_date);
            $colWrapper = (new ColWrapper())
                ->addComponents([
                    (new ContentTitle())
                        ->addTitle('Change Subscription Disabled')
                        ->addContent($hookResponse->message ?? 'Your subscription was last changed on '.$timestamp->format('jS M Y').'.<br>Only one change per billing month is allowed.<br>The subscription can be changed from '. $nextBillingDate->format('jS M Y'))
                        ->addClass('my-3 fw-bold')
                ]);
        } else {
            $colWrapper = (new ColWrapper())
                ->addComponents([
                    (new ContentTitle())
                        ->addTitle('Change Subscription')
                        ->addContent('By changing your subscription you are agreeing to the following terms and conditions:<br>
    - The change will occur with immediate effect;<br>
    - Any overage accrued to date will still be charged for;<br>
    - Any "unused" allowances will be forfeited;<br>
    - The new subscription payment will be collected immediately and billed on the anniversary of the change;<br>
    - Only one change per billing month is allowed;<br>
    - The change cannot be reversed until the next billing month has passed.')
                        ->addClass('my-3 fw-bold'),
                    (new FormComponent())->setID('subscriptionChange')->src(Routes::getRoutePattern('subscriptionDisplay.form.subscriptions.change', $args))
                ]);
        }
        return $colWrapper;
    }

    public static function restartSubscriptionTile(subscriptionEntity $subscriptionEntity, $args)
    {
            $args['id'] = $args['subscriptionId'] ?? $args['id'];
            $colWrapper = (new ColWrapper())
                ->addComponents([
                    (new ContentTitle())
                        ->addTitle('Restart Subscription')
                        ->addContent('By restarting your subscription you are agreeing to the following terms and conditions:<br>
        - The change will occur with immediate effect;<br>
        - Any overage accrued to date will still be charged for;<br>
        - The new subscription payment will be collected immediately and billed on the anniversary of the change;')
                        ->addClass('my-3 fw-bold'),
                    (new FormComponent())->setID('subscriptionRestart')->src(Routes::getRoutePattern('subscriptionDisplay.form.subscriptions.restart', $args))
                ]);

        return $colWrapper;
    }


    public static function suspendSubscriptionTile(subscriptionEntity $subscriptionEntity)
    {
        $subscriptionService = new subscriptionService();
        $config = Singleton::getInstance();
        $suspendStatusObject = $subscriptionService->suspendedStatus($subscriptionEntity);

        $preLabelMessage = !$suspendStatusObject->canSuspend || $subscriptionEntity->product_quantity == 1 ? '' : '<span class="text-danger text-lg">IMPORTANT: This subscription contains multiple SIMs, all of which will be cancelled. If you only want to cancel one of them, please choose the "Cancel Subscription" option from the <a href="'.Routes::getRoutePattern('simcardEntity.display.all').'">SIMs > List All page</a>" instead.</span><br><br>';
        $colWrapper = (new ColWrapper())->addComponent((new ContentTitle())->addContent($preLabelMessage.$suspendStatusObject->label))->addClass('my-3 fw-bold');

        $currentUser = currentUser::getCurrentUser();
        if(!$currentUser->isAllowed('ManageUsers') && !$currentUser->isAllowed('UpdateSubscriptions')){
            $labels = ['Cancel', 'Cancellation', 'Cancelled'];
        } else {
            $labels = ['Suspend', 'Suspension', 'Suspended'];
        }

        $button = (new SimpleButton());

        if ($subscriptionEntity->cancellation_date > date('Y-m-d') && $suspendStatusObject->canSuspend) {
            $button->addClass('btn-danger me-4');
            $button->addText('Cancel Immediately');
            $button->addRoute($config->app->site->backend_domain . Routes::getRoutePattern('subscription.suspend', ['id' => $subscriptionEntity->id]));
            $button->addProperty('asynch', 'POST');
            $colWrapper->addComponent($button);

            $button = (new SimpleButton());
            $button->addClass('btn-success');
            $button->addText('Re-enable Now');
            $button->addRoute($config->app->site->backend_domain . Routes::getRoutePattern('subscription.reenable', ['id' => $subscriptionEntity->id]));
            $button->addProperty('asynch', 'POST');

        } elseif ($suspendStatusObject->canSuspend && isset($suspendStatusObject->suspensionDate)) {
            $button->addClass('btn-'.$suspendStatusObject->bsStyle);
            $button->addText('Schedule '.$labels[1].' for '.$suspendStatusObject->suspensionDate->format('jS M Y'));
            $button->addRoute($config->app->site->backend_domain . Routes::getRoutePattern('subscription.suspend', ['id' => $subscriptionEntity->id, 'cancellationDate' => $suspendStatusObject->suspensionDate->format('Y-m-d')]));
            $button->addProperty('asynch', 'POST');
        } elseif ($suspendStatusObject->canSuspend) {
            $button->addClass('btn-'.$suspendStatusObject->bsStyle);
            $button->addText($labels[0] . ' Now');
            $button->addRoute($config->app->site->backend_domain . Routes::getRoutePattern('subscription.suspend', ['id' => $subscriptionEntity->id]));
            $button->addProperty('asynch', 'POST');
        } else {
            $button->addClass('btn-success');
            $button->addText('Re-enable Now');
            $button->addRoute($config->app->site->backend_domain . Routes::getRoutePattern('subscription.reenable', ['id' => $subscriptionEntity->id]));
            $button->addProperty('asynch', 'POST');
        }

        $newButton = Hook::processHook('modify_subscription_cancellation_button', $subscriptionEntity);

        if ($newButton instanceof SimpleButton) $button = $newButton;

        $colWrapper->addComponent($button);

        return $colWrapper;
    }


}