<?php

use Carbon\Carbon;
use idoit\Module\License\LicenseService;
use idoit\Module\License\LicenseServiceFactory;

/**
 * i-doit
 *
 * Dashboard widget class
 *
 * @package     i-doit
 * @subpackage  Modules
 * @author      Leonard Fischer <lfischer@i-doit.com>
 * @version     1.2
 * @copyright   synetics GmbH
 * @license     http://www.i-doit.com/license
 *
 * @todo licensing 2.0
 */
class isys_dashboard_widgets_eval extends isys_dashboard_widgets
{
    /**
     * Path and Filename of the configuration template.
     *
     * @var  string
     */
    protected $m_config_tpl_file = '';

    /**
     * Path and Filename of the template.
     *
     * @var  string
     */
    protected $m_tpl_file = '';

    /**
     * Returns a boolean value, if the current widget has an own configuration page.
     *
     * @return  boolean
     * @author  Leonard Fischer <lfischer@i-doit.com>
     */
    public function has_configuration()
    {
        return true;
    }

    /**
     * Init method.
     *
     * @param   array $p_config
     *
     * @return  isys_dashboard_widgets_quicklaunch
     * @author  Leonard Fischer <lfischer@i-doit.com>
     */
    public function init($p_config = [])
    {
        isys_core::expire(300);

        $this->m_tpl_file = __DIR__ . '/templates/eval.tpl';
        $this->m_config_tpl_file = __DIR__ . '/templates/config.tpl';

        return parent::init($p_config);
    }

    /**
     * Method for loading the widget configuration.
     *
     * @param   array   $p_row The current widget row from "isys_widgets".
     * @param   integer $p_id  The ID from "isys_widgets_config".
     *
     * @return  string
     * @author  Leonard Fischer <lfischer@i-doit.com>
     */
    public function load_configuration(array $p_row, $p_id)
    {
        $rules = [
            'layout'     => [
                'p_arData'        => [
                    'vertical'   => $this->language->get('LC__WIDGET__EVAL__LAYOUT_VERTITAL'),
                    'horizontal' => $this->language->get('LC__WIDGET__EVAL__LAYOUT_HORIZONTAL')
                ],
                'p_strClass'      => 'input-small',
                'p_bDbFieldNN'    => true,
                'p_strSelectedID' => $this->m_config['layout']
            ],
            'short_form' => [
                'p_arData'        => get_smarty_arr_YES_NO(),
                'p_strClass'      => 'input-small',
                'p_bDbFieldNN'    => true,
                'p_strSelectedID' => $this->m_config['short_form']
            ],
        ];

        return $this->m_tpl->activate_editmode()
            ->assign('title', $this->language->get('LC__WIDGET__EVAL__CONFIG'))
            ->smarty_tom_add_rules('tom.popup.dashboard', $rules)
            ->fetch($this->m_config_tpl_file);
    }

    /**
     * @param string $p_unique_id
     *
     * @return string
     * @throws SmartyException
     */
    public function render($p_unique_id)
    {
        if (!class_exists('isys_module_licence')) {
            return;
        }

        // Get licence module.
        $l_licence = new isys_module_licence();

        global $g_license_token;

        $licenseService = LicenseServiceFactory::createDefaultLicenseService(isys_application::instance()->container->get('database_system'), $g_license_token);

        $earliestExpiringLicense = $licenseService->getEarliestExpiringLicense();

        $requestedAt = null;
        $expires = null;
        $expiresAt = null;
        $expiresWithinSixMonths = false;
        $remaining = null;

        $dateFormat = isys_application::instance()->container->get('locales')->get_date_format();
        $session = isys_application::instance()->container->get('session');
        $now = Carbon::now();

        if ($earliestExpiringLicense instanceof \idoit\Module\License\Entity\License) {
            $requestedAt = $earliestExpiringLicense->getValidityFrom()->format($dateFormat);
            $expiresAt = $earliestExpiringLicense->getValidityTo()->format($dateFormat);
        } elseif (is_array($earliestExpiringLicense) && isset($earliestExpiringLicense[LicenseService::C__LICENCE__REG_DATE])) {
            if (
                $earliestExpiringLicense[LicenseService::LEGACY_LICENSE_TYPE] == LicenseService::C__LICENCE_TYPE__BUYERS_LICENCE ||
                $earliestExpiringLicense[LicenseService::LEGACY_LICENSE_TYPE] == LicenseService::C__LICENCE_TYPE__BUYERS_LICENCE_HOSTING
            ) {
                $registrationDate = Carbon::createFromTimestamp($earliestExpiringLicense[LicenseService::C__LICENCE__REG_DATE]);

                $requestedAt = $registrationDate->format($dateFormat);

                $expires = Carbon::instance($registrationDate)->modify("+99 years");

                $expiresAt = $expires->format($dateFormat);

                $remaining = $expires->diff($now);
            } elseif (isset($earliestExpiringLicense[LicenseService::C__LICENCE__RUNTIME])) {
                $days = (int) round(abs((($earliestExpiringLicense[LicenseService::C__LICENCE__RUNTIME] / 60 / 60 / 24))));

                $registrationDate = Carbon::createFromTimestamp($earliestExpiringLicense[LicenseService::C__LICENCE__REG_DATE]);

                $requestedAt = $registrationDate->format($dateFormat);

                $expires = Carbon::instance($registrationDate)->modify("+{$days} days");

                $expiresAt = $expires->format($dateFormat);

                $remaining = $expires->diff($now);
            }
        }

        if ($expires !== null) {
            $expiresWithinSixMonths = Carbon::instance($expires)
                ->between($now, $now->copy()
                    ->addMonths(6));
        }
        $remainingTimePercentage = 0;

        if ($expiresWithinSixMonths) {
            $remainingTimePercentage = 100 - (100 / $now->diffInDays($now->copy()->addMonths(6)) * $now->diffInDays(Carbon::parse($expiresAt)));
        }

        $stringTimeLimit = $this->language->get('LC__WIDGET__EVAL__TIME_LIMIT', [
            $requestedAt,
            $expiresAt,
            $remaining->y,
            $remaining->m,
            $remaining->d
        ]);

        if (!$licenseService->isTenantLicensed($session->get_mandator_id())) {
            $this->m_tpl->assign('error', $this->language->get('LC__LICENCE__NO_LICENCE'));

            $stringTimeLimit = $this->language->get('LC__WIDGET__EVAL__TIME_LIMIT_EXCEEDED', [
                $requestedAt,
                $expiresAt,
                $remaining->y,
                $remaining->m,
                $remaining->d
            ]);
        }

        $tenant = $licenseService->getTenants(true, [$session->get_mandator_id()]);

        // Statistics.
        $l_mod_stat = new isys_module_statistics();
        $l_mod_stat->init_statistics();

        $objectsInUse = $l_mod_stat->get_counts()['objects'];
        $totalLicenseObjects = (int) $tenant[0]['isys_mandator__license_objects'];

        // Prepare object data.
        $remainingObjects = $totalLicenseObjects - $objectsInUse;

        $remainingObjectsPercent = 0;

        // Preventing division by zero.
        if ($totalLicenseObjects > 0) {
            $remainingObjectsPercent = round(($objectsInUse / $totalLicenseObjects) * 100, 2);
        }

        // Handle the object logic.
        if ($remainingObjectsPercent >= 100) {
            $remainingObjectsPercent = 100;

            $stringObjLimit = $this->language->get('LC__WIDGET__EVAL__OBJ_LIMIT_EXCEEDED', ($remainingObjects * -1));
        } elseif ($this->m_config['short_form']) {
            $stringObjLimit = $this->language->get('LC__WIDGET__EVAL__OBJ_LIMIT_SHORT', [$remainingObjects]);
        } else {
            $stringObjLimit = $this->language->get('LC__WIDGET__EVAL__OBJ_LIMIT', [$totalLicenseObjects, $objectsInUse, $remainingObjects]);
        }

        $this->m_tpl
            ->assign('layout', $this->m_config['layout'])
            ->assign('uid', $p_unique_id)
            ->assign('stringObjectLimit', $stringObjLimit)
            ->assign('stringTimeLimit', $stringTimeLimit)
            ->assign('expiresWithinSixMonths', $expiresWithinSixMonths)
            ->assign('remainingObjectPercentage', $remainingObjectsPercent)
            ->assign('remainingTimePercentage', $remainingTimePercentage);

        return $this->m_tpl->fetch($this->m_tpl_file);
    }
}
