<?php
/*
 * @ PHP 5.6
 * @ Decoder version : 1.0.0.1
 * @ Release on : 24.03.2018
 * @ Website    : http://EasyToYou.eu
 */

// $dbkeys = Illuminate\Database\Capsule\Manager::table('tbladdonmodules')->where('module', 'addononestreamlines')->get();
// $dbr = json_encode($dbkeys);
// $dbr = json_decode($dbr, true);
// foreach ($dbr as $row => $setting) {
//     $localkey = $dbr[0]['value'];
//     $licensekey = $dbr[3]['value'];
// }
// $results = onestreamlines_check_license($licensekey, $localkey);
// if ($results['status'] == 'Active') {
//     if ($results['localkey']) {
//         $localkeydata = $results['localkey'];
//         $data = Illuminate\Database\Capsule\Manager::table('tbladdonmodules')->where('module', 'addononestreamlines')->where('setting', 'localkey')->update(array('value' => (string) $localkeydata));
//     }
// } else {
//     if ($results['status'] == 'Invalid') {
//         echo 'Please report this to our customer support: onestreamlines Module License key is Invalid' . '<br></br>';
//     } else {
//         if ($results['status'] == 'Expired') {
//             echo 'Please report this to our customer support: onestreamlines Module License key is Expired' . '<br></br>';
//         } else {
//             if ($results['status'] == 'Suspended') {
//                 echo 'Please report this to our customer support: onestreamlines Module License key is Suspended' . '<br></br>';
//             }
//         }
//     }
// }

use WHMCS\Module\Addon\OnestreamReseller\Config;

if (!defined('WHMCS')) {
    exit('This file cannot be accessed directly');
}

/**
 * Define module related meta data.
 *
 * Values returned here are used to determine module related abilities and
 * settings.
 *
 * @see https://developers.whmcs.com/provisioning-modules/meta-data-params/
 *
 * @return array
 */
function onestreamlines_MetaData()
{
    return array(
        'DisplayName' => '1-Stream Lines',
        'APIVersion' => '1.0',
        'RequiresServer' => false,
        'DefaultNonSSLPort' => '7999',
        'DefaultSSLPort' => '1112',
        'ServiceSingleSignOnLabel' => 'Login to Panel as User',
        'AdminSingleSignOnLabel' => 'Login to Panel as Admin'
    );
}

/**
 * Define product configuration options.
 *
 * The values you return here define the configuration options that are
 * presented to a user when configuring a product for use with the module. These
 * values are then made available in all module function calls with the key name
 * configoptionX - with X being the index number of the field from 1 to 24.
 *
 * You can specify up to 24 parameters, with field types:
 * * text
 * * password
 * * yesno
 * * dropdown
 * * radio
 * * textarea
 *
 * Examples of each and their possible configuration parameters are provided in
 * this sample function.
 *
 * @see https://developers.whmcs.com/provisioning-modules/config-options/
 *
 * @return array
 */
function onestreamlines_ConfigOptions()
{
    return array(
        'Panel' => array('Type' => 'dropdown', 'Size' => '150', 'Loader' => 'onestreamlines_LoadPanels', 'SimpleMode' => true),
        'Parent User Token (Optional)' => array('Type' => 'text', 'Size' => '200', 'Default' => '', 'Description' => '', 'SimpleMode' => true),
        'Reseller Domain (Optional)' => array('Type' => 'text', 'Size' => '200', 'Default' => '', 'Description' => '', 'SimpleMode' => true),
        'Monthly ID' => array('Type' => 'dropdown', 'Size' => '150', 'Loader' => 'onestreamlines_LoadPackages', 'SimpleMode' => true),
        'Quarterly ID' => array('Type' => 'dropdown', 'Size' => '150', 'Loader' => 'onestreamlines_LoadPackages', 'SimpleMode' => true),
        'Semi-Annually ID' => array('Type' => 'dropdown', 'Size' => '150', 'Loader' => 'onestreamlines_LoadPackages', 'SimpleMode' => true),
        'Annually ID' => array('Type' => 'dropdown', 'Size' => '150', 'Loader' => 'onestreamlines_LoadPackages', 'SimpleMode' => true),
        'PPV ID' => array('Type' => 'dropdown', 'Size' => '150', 'Loader' => 'onestreamlines_LoadPackages', 'SimpleMode' => true),
    );
}

/**
 * Provision a new instance of a product/service.
 *
 * Attempt to provision a new instance of a given product/service. This is
 * called any time provisioning is requested inside of WHMCS. Depending upon the
 * configuration, this can be any of:
 * * When a new order is placed
 * * When an invoice for a new order is paid
 * * Upon manual request by an admin user
 *
 * @param array $params common module parameters
 *
 * @see https://developers.whmcs.com/provisioning-modules/module-parameters/
 *
 * @return string 'success' or an error message
 */
function onestreamlines_CreateAccount(array $params)
{
    try {

        logActivity(__FUNCTION__ . ' variables: ' . print_r($params, true));

        $serviceid = $params['serviceid'];
        $panel = $params['configoption1'];
        $authToken = $params['configoption2'];
        $resellerDomain = $params['configoption3'];
        $config_monthly = $params['configoption4'];
        $config_quarterly = $params['configoption5'];
        $config_semi = $params['configoption6'];
        $config_annually = $params['configoption7'];
        $config_ppv = $params['configoption8'];

        $billingcycle = $params['model']->billingcycle;

        $custom_username = $params['customfields']['Username'] ?? null;
        $custom_mac = $params['customfields']['MAC'] ?? null;

        $client = Config::getApiClient($panel, $authToken);

        $panels = Config::getConfiguredPanels();
        $panelDetails = $panels[$panel];

        $package = null;

        if ($billingcycle == 'Monthly') {
            $package = $config_monthly;
        } else {
            if ($billingcycle == 'Quarterly') {
                $package = $config_quarterly;
            } else {
                if ($billingcycle == 'Semi-Annually') {
                    $package = $config_semi;
                } else {
                    if ($billingcycle == 'Annually') {
                        $package = $config_annually;
                    } else {
                        if ($billingcycle == 'One Time') {
                            $package = $config_ppv;
                        }
                    }
                }
            }
        }

        $results = $client->createLine(
            $package,
            $custom_username,
            null,
            $custom_mac,
            $serviceid
        );

        if ($results['code'] != 200) {
            return 'API Connection failed with code ' . $results['code'];
        }

        $data = json_decode($results['data'], true);

        if (!empty($data['error'])) {
            return $data['error'];
        }

        $serviceusername = $data['username'];
        $servicepassword = $data['password'];

        $command = 'UpdateClientProduct';

        $postData = array(
            'serviceid' => (string) $serviceid,
            'serviceusername' => (string) $serviceusername,
            'servicepassword' => (string) $servicepassword,
            'domain' => (string) ($resellerDomain ?: $panelDetails['panel_url'])
        );

        $adminUsername = Config::getAdminUserName();

        $results = localAPI($command, $postData, $adminUsername);

    } catch (Exception $e) {
        logModuleCall('onestreamlines', 'onestreamlines_CreateAccount', $params, $e->getMessage(), $e->getTraceAsString());
        return $e->getMessage();
    }
    return 'success';
}

function onestreamlines_SuspendAccount(array $params)
{
    try {
        logActivity(__FUNCTION__ . ' variables: ' . print_r($params, true));

        $serviceid = $params['serviceid'];
        $panel = $params['configoption1'];
        $authToken = $params['configoption2'];
        $serviceusername = $params['username'];

        $client = Config::getApiClient($panel, $authToken);

        $result = $client->suspendLine($serviceusername, $serviceid . '_' . 'suspend_account');
    } catch (Exception $e) {
        logModuleCall('onestreamlines', 'onestreamlines_SuspendAccount', $params, $e->getMessage(), $e->getTraceAsString());
        return $e->getMessage();
    }
    return 'success';
}

/**
 * Un-suspend instance of a product/service.
 *
 * Called when an un-suspension is requested. This is invoked
 * automatically upon payment of an overdue invoice for a product, or
 * can be called manually by admin user.
 *
 * @param array $params common module parameters
 *
 * @see https://developers.whmcs.com/provisioning-modules/module-parameters/
 *
 * @return string 'success' or an error message
 */
function onestreamlines_UnsuspendAccount(array $params)
{
    try {
        logActivity(__FUNCTION__ . ' variables: ' . print_r($params, true));

        $serviceid = $params['serviceid'];
        $panel = $params['configoption1'];
        $authToken = $params['configoption2'];
        $serviceusername = $params['username'];

        $client = Config::getApiClient($panel, $authToken);

        $result = $client->unsuspendLine($serviceusername, $serviceid . '_' . 'unsuspend_account');
    } catch (Exception $e) {
        logModuleCall('onestreamlines', 'onestreamlines_UnsuspendAccount', $params, $e->getMessage(), $e->getTraceAsString());
        return $e->getMessage();
    }
    return 'success';
}

/**
 * Terminate instance of a product/service.
 *
 * Called when a termination is requested. This can be invoked automatically for
 * overdue products if enabled, or requested manually by an admin user.
 *
 * @param array $params common module parameters
 *
 * @see https://developers.whmcs.com/provisioning-modules/module-parameters/
 *
 * @return string 'success' or an error message
 */
function onestreamlines_TerminateAccount(array $params)
{
    try {
        logActivity(__FUNCTION__ . ' variables: ' . print_r($params, true));

        $serviceid = $params['serviceid'];
        $panel = $params['configoption1'];
        $authToken = $params['configoption2'];
        $serviceusername = $params['username'];

        $client = Config::getApiClient($panel, $authToken);

        $result = $client->terminateLine($serviceusername, $serviceid . '_' . 'terminate_account');
    } catch (Exception $e) {
        logModuleCall('onestreamlines', 'onestreamlines_TerminateAccount', $params, $e->getMessage(), $e->getTraceAsString());
        return $e->getMessage();
    }
    return 'success';
}

/**
 * Change the password for an instance of a product/service.
 *
 * Called when a password change is requested. This can occur either due to a
 * client requesting it via the client area or an admin requesting it from the
 * admin side.
 *
 * This option is only available to client end users when the product is in an
 * active status.
 *
 * @param array $params common module parameters
 *
 * @see https://developers.whmcs.com/provisioning-modules/module-parameters/
 *
 * @return string 'success' or an error message
 */
function onestreamlines_ChangePackage(array $params)
{
    try {
        logActivity(__FUNCTION__ . ' variables: ' . print_r($params, true));
    } catch (Exception $e) {
        logModuleCall('onestreamlines', 'onestreamlines_ChangePackage', $params, $e->getMessage(), $e->getTraceAsString());
        return $e->getMessage();
    }
    return 'success';
}

/**
 * Renew an instance of a product/service.
 *
 * Attempt to renew an existing instance of a given product/service. This is
 * called any time a product/service invoice has been paid. 
 *
 * @param array $params common module parameters
 *
 * @see https://developers.whmcs.com/provisioning-modules/module-parameters/
 *
 * @return string "success" or an error message
 */
function onestreamlines_Renew(array $params)
{
    try {
        logActivity(__FUNCTION__ . ' variables: ' . print_r($params, true));

        $serviceid = $params['serviceid'];
        $panel = $params['configoption1'];
        $authToken = $params['configoption2'];
        $serviceusername = $params['username'];

        $client = Config::getApiClient($panel, $authToken);

        $result = $client->renewLine($serviceusername, $serviceid . '_' . 'renew' . '_' . ($params['invoiceid'] ?? 0));

        if ($result['code'] != 200) {
            throw new \Exception('API Connection failed with code ' . $result['code']);
        }

        $data = json_decode($result['data'], true);

        if (!empty($data['error'])) {
            throw new \Exception($data['error']);
        }
    } catch (Exception $e) {
        logModuleCall('onestreamlines', __FUNCTION__, $params, $e->getMessage(), $e->getTraceAsString());
        
        return $e->getMessage();
    }

    return 'success';
}

/**
 * Test connection with the given server parameters.
 *
 * Allows an admin user to verify that an API connection can be
 * successfully made with the given configuration parameters for a
 * server.
 *
 * When defined in a module, a Test Connection button will appear
 * alongside the Server Type dropdown when adding or editing an
 * existing server.
 *
 * @param array $params common module parameters
 *
 * @see https://developers.whmcs.com/provisioning-modules/module-parameters/
 *
 * @return array
 */
function onestreamlines_TestConnection(array $params)
{
    try {
        $success = true;
        $errorMsg = '';
    } catch (Exception $e) {
        logModuleCall('onestreamlines', 'onestreamlines_TestConnection', $params, $e->getMessage(), $e->getTraceAsString());
        $success = false;
        $errorMsg = $e->getMessage();
    }
    return array('success' => $success, 'error' => $errorMsg);
}
/**
 * Additional actions an admin user can invoke.
 *
 * Define additional actions that an admin user can perform for an
 * instance of a product/service.
 *
 * @see onestreamlines_buttonOneFunction()
 *
 * @return array
 */
function onestreamlines_ClientAreaCustomButtonArray()
{
    return array('Login Details' => 'actionOneFunction');
}
/**
 * Custom function for performing an additional action.
 *
 * You can define an unlimited number of custom functions in this way.
 *
 * Similar to all other module call functions, they should either return
 * 'success' or an error message to be displayed.
 *
 * @param array $params common module parameters
 *
 * @see https://developers.whmcs.com/provisioning-modules/module-parameters/
 * @see onestreamlines_AdminCustomButtonArray()
 *
 * @return string 'success' or an error message
 */
function onestreamlines_buttonOneFunction(array $params)
{
    try {
    } catch (Exception $e) {
        logModuleCall('onestreamlines', 'onestreamlines_buttonOneFunction', $params, $e->getMessage(), $e->getTraceAsString());
        return $e->getMessage();
    }
    return 'success';
}
/**
 * Custom function for performing an additional action.
 *
 * You can define an unlimited number of custom functions in this way.
 *
 * Similar to all other module call functions, they should either return
 * 'success' or an error message to be displayed.
 *
 * @param array $params common module parameters
 *
 * @see https://developers.whmcs.com/provisioning-modules/module-parameters/
 * @see onestreamlines_ClientAreaCustomButtonArray()
 *
 * @return string 'success' or an error message
 */
function onestreamlines_actionOneFunction(array $params)
{
    try {
    } catch (Exception $e) {
        logModuleCall('onestreamlines', 'onestreamlines_actionOneFunction', $params, $e->getMessage(), $e->getTraceAsString());
        return $e->getMessage();
    }
    return 'success';
}
/**
 * Admin services tab additional fields.
 *
 * Define additional rows and fields to be displayed in the admin area service
 * information and management page within the clients profile.
 *
 * Supports an unlimited number of additional field labels and content of any
 * type to output.
 *
 * @param array $params common module parameters
 *
 * @see https://developers.whmcs.com/provisioning-modules/module-parameters/
 * @see onestreamlines_AdminServicesTabFieldsSave()
 *
 * @return array
 */
function onestreamlines_AdminServicesTabFieldsSave(array $params)
{
    // $originalFieldValue = isset($_REQUEST['onestreamlines_original_uniquefieldname']) ? $_REQUEST['onestreamlines_original_uniquefieldname'] : '';
    // $newFieldValue = isset($_REQUEST['onestreamlines_uniquefieldname']) ? $_REQUEST['onestreamlines_uniquefieldname'] : '';
    // if ($originalFieldValue != $newFieldValue) {
    //     try {
    //     } catch (Exception $e) {
    //         logModuleCall('onestreamlines', 'onestreamlines_AdminServicesTabFieldsSave', $params, $e->getMessage(), $e->getTraceAsString());
    //     }
    // }
}
/**
 * Perform single sign-on for a given instance of a product/service.
 *
 * Called when single sign-on is requested for an instance of a product/service.
 *
 * When successful, returns a URL to which the user should be redirected.
 *
 * @param array $params common module parameters
 *
 * @see https://developers.whmcs.com/provisioning-modules/module-parameters/
 *
 * @return array
 */
function onestreamlines_ServiceSingleSignOn(array $params)
{
    // try {
    //     $response = array();
    //     return array('success' => true, 'redirectTo' => $response['redirectUrl']);
    // } catch (Exception $e) {
    //     logModuleCall('onestreamlines', 'onestreamlines_ServiceSingleSignOn', $params, $e->getMessage(), $e->getTraceAsString());
    //     return array('success' => false, 'errorMsg' => $e->getMessage());
    // }
}
/**
 * Perform single sign-on for a server.
 *
 * Called when single sign-on is requested for a server assigned to the module.
 *
 * This differs from ServiceSingleSignOn in that it relates to a server
 * instance within the admin area, as opposed to a single client instance of a
 * product/service.
 *
 * When successful, returns a URL to which the user should be redirected to.
 *
 * @param array $params common module parameters
 *
 * @see https://developers.whmcs.com/provisioning-modules/module-parameters/
 *
 * @return array
 */
function onestreamlines_AdminSingleSignOn(array $params)
{
    // try {
    //     $response = array();
    //     return array('success' => true, 'redirectTo' => $response['redirectUrl']);
    // } catch (Exception $e) {
    //     logModuleCall('onestreamlines', 'onestreamlines_AdminSingleSignOn', $params, $e->getMessage(), $e->getTraceAsString());
    //     return array('success' => false, 'errorMsg' => $e->getMessage());
    // }
}

function onestreamlines_ClientArea(array $params)
{
    $requestedAction = isset($_REQUEST['customAction']) ? $_REQUEST['customAction'] : '';
    if ($requestedAction == 'manage') {
        $serviceAction = 'get_usage';
        $templateFile = 'templates/manage.tpl';
    } else {
        $serviceAction = 'get_stats';
        $templateFile = 'templates/overview.tpl';
    }
    $parsed = parse_url($params['domain']);
    $domain = $parsed['scheme'] . '://' . $parsed['host'] . ':' . $parsed['port'];
    $portal = (empty($parsed['path']) || $parsed['path'] == '/') ? $domain . '/c' : $params['domain'];
    $mac = $params['customfields']['MAC'] ?? null;

    try {
        return array('tabOverviewReplacementTemplate' => $templateFile,
            'templateVariables' => array('domain' => $domain,
            'portal' => $portal, 'mac' => $mac));
    } catch (Exception $e) {
        logModuleCall('onestreamlines', 'onestreamlines_ClientArea', $params, $e->getMessage(), $e->getTraceAsString());
        return array('tabOverviewReplacementTemplate' => 'error.tpl', 'templateVariables' => array('usefulErrorHelper' => $e->getMessage()));
    }
}

function onestreamlines_LoadPackages($params)
{
    // logActivity(__FUNCTION__ . ' variables: ' . print_r($params, true));
    // logActivity(__FUNCTION__ . ' args: ' . print_r(func_get_args(), true));

    // return [0 => 'None', 555 => '[Package 555] 10 credits, official', 666 => '[Package 666] 10 credits, official'];

    $serviceId = $_POST['id'] ?? ($_GET['id'] ?? 0);
    
    $data = Config::loadProductConfig($serviceId, 'onestreamlines');

    // default to 1st panel
    $panel = 1;
    $authToken = null;

    if (!empty($data->configoption1)) {
        $panel = $data->configoption1;
    }

    if (!empty($data->configoption2)) {
        $authToken = $data->configoption2;
    }

    $client = Config::getApiClient($panel, $authToken);

    $response = $client->getPackages();

    $packages = json_decode($response['data']);

    $return = [];

    $return[0] = 'None';

    foreach ($packages as $p) {
        $return[$p->id] = '[Panel ' . $panel . ']: #'  . $p->id . ', ' . $p->name;
    }

    return $return;
}

function onestreamlines_LoadPanels()
{
    $configured = Config::getConfiguredPanels();

    $panels = [];

    foreach ($configured as $id => $c) {
        $panels[$id] = '[Panel ' . $id . '] ' . $c['panel_url'];
    }

    return $panels;
}