<?php
/**
 * CustomAstDB — legacy hook functions for the Extensions edit page tab.
 *
 * FreePBX 17's BMO does NOT have a `getCoreExtensionTabs` hook — tabs on the
 * Extensions edit page are added the legacy way: by defining functions named
 * `<modname>_users_configpageinit / _configpageload / _configprocess` here
 * in functions.inc.php. The framework auto-discovers them.
 *
 * Reference patterns (verified in core): findmefollow/functions.inc.php (find
 * "_users_configpageinit"), voicemail/functions.inc.php (find "_users_").
 */

/**
 * The framework dispatches `<rawname>_configpageinit($dispnum)` — NOT
 * `<rawname>_users_configpageinit`. We have to be the entry point with the
 * exact `customastdb_configpageinit` name; we then route internally to the
 * load + process funcs when the current page is extensions or users.
 * (Pattern verified against findmefollow_configpageinit and
 * voicemail_configpageinit on the test PBX.)
 */
function customastdb_configpageinit($pagename) {
    global $currentcomponent;

    if ($pagename !== 'extensions' && $pagename !== 'users') {
        return true;
    }

    $action        = $_REQUEST['action']        ?? null;
    $extdisplay    = $_REQUEST['extdisplay']    ?? null;
    $tech_hardware = $_REQUEST['tech_hardware'] ?? null;

    // On a new-extension form (`tech_hardware` set and no `extdisplay` yet) the
    // astdb state doesn't exist yet. We still want the process hook so the
    // initial state can be set on first save, but the load hook is skipped —
    // there's nothing to display until the extension actually exists.
    if ($extdisplay !== null && $extdisplay !== '') {
        $currentcomponent->addguifunc('customastdb_users_configpageload');
        $currentcomponent->addprocessfunc('customastdb_users_configprocess', 9);
    } elseif ($action === 'add' || $tech_hardware !== null) {
        $currentcomponent->addprocessfunc('customastdb_users_configprocess', 9);
    }
}

function customastdb_users_configpageload($pagename) {
    global $currentcomponent;

    $extdisplay = $_REQUEST['extdisplay'] ?? '';
    if ($extdisplay === '') return;

    $state = \FreePBX::Customastdb()->getStateForExtension($extdisplay);

    $category = 'customastdb';
    $currentcomponent->addTabTranslation($category, _('AstDB State'));

    $section = _('Do Not Disturb');
    $guidefaults = [
        'elemname' => '', 'prompttext' => '', 'helptext' => '', 'currentvalue' => '',
        'valarray' => [], 'jsonclick' => '', 'jsvalidation' => '', 'failvalidationmsg' => '',
        'canbeempty' => true, 'maxchars' => 0, 'disable' => false, 'inputgroup' => false,
        'class' => '', 'cblabel' => 'Enable', 'disabled_value' => 'DEFAULT',
        'check_enables' => 'true', 'cbdisable' => false, 'cbclass' => '',
    ];

    $dndEl = [
        'elemname'   => 'customastdb_dnd',
        'prompttext' => _('Do Not Disturb'),
        'helptext'   => _('When ON, Asterisk sends inbound calls to the busy/voicemail path instead of ringing the extension.'),
        'currentvalue' => ($state['dnd'] ? '1' : '0'),
        'valarray'   => [
            ['value' => '1', 'text' => _('On')],
            ['value' => '0', 'text' => _('Off')],
        ],
        'pairedvalues' => false,
    ];
    $currentcomponent->addguielem($section, new gui_radio([...$guidefaults, ...$dndEl]), 5, null, $category);

    $section = _('Call Forward');

    // Build a tiny one-time decorator script. We append it to the LAST CF
    // field's helptext (rendered raw, after the input), which is the simplest
    // way to make a script execute on the extensions edit page — gui_html
    // elements don't reliably render in this form layout, and the form has
    // no addjsraw / addscript-on-load hook to register against.
    $clearScript = <<<'HTML'
<script>
(function () {
    function decorate() {
        ['customastdb_cf', 'customastdb_cfb', 'customastdb_cfu'].forEach(function (id) {
            var input = document.getElementById(id);
            if (!input) return;
            // Idempotent: skip if we've already wrapped this input.
            if (input.parentNode && input.parentNode.classList && input.parentNode.classList.contains('customastdb-input-wrap')) return;

            // Bootstrap input-group: input + button-addon side-by-side, no wrap.
            var wrap = document.createElement('div');
            wrap.className = 'input-group customastdb-input-wrap';

            var addon = document.createElement('span');
            addon.className = 'input-group-btn';

            var btn = document.createElement('button');
            btn.type = 'button';
            btn.className = 'btn btn-default customastdb-clear-btn';
            btn.setAttribute('data-for', id);
            btn.textContent = 'Clear';
            btn.title = 'Empty this field. Click Submit at the bottom of the form to persist the clear.';
            btn.onclick = function (e) {
                e.preventDefault();
                input.value = '';
                input.focus();
            };

            // Splice the wrapper into the DOM where the input was, then move
            // input into the wrapper followed by the button-addon.
            input.parentNode.insertBefore(wrap, input);
            wrap.appendChild(input);
            addon.appendChild(btn);
            wrap.appendChild(addon);
        });
    }
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', decorate);
    } else {
        decorate();
    }
})();
</script>
HTML;

    $rows = [
        ['CF',  'cf',  _('Call Forward (always)'),     _('Forward every inbound call to this destination. Empty = off.')],
        ['CFB', 'cfb', _('Call Forward on Busy'),      _('Forward only when the line is busy. Empty = off.')],
        ['CFU', 'cfu', _('Call Forward on No Answer'), _('Forward when the call goes unanswered or the device is unavailable. Empty = off.')],
    ];
    $lastIdx = count($rows) - 1;
    foreach ($rows as $i => $row) {
        [$type, $field, $prompt, $help] = $row;
        // Tack the decorator script onto the LAST CF field's helptext — at
        // that point all three inputs are in the DOM and the script can
        // safely find them by id.
        if ($i === $lastIdx) {
            $help .= $clearScript;
        }
        $el = [
            'elemname'   => 'customastdb_' . $field,
            'prompttext' => $prompt,
            'helptext'   => $help,
            'currentvalue' => $state[$field],
            'jsvalidation' => '',
            'failvalidationmsg' => '',
            'canbeempty' => true,
            'maxchars'   => 80,
        ];
        $currentcomponent->addguielem($section, new gui_textbox([...$guidefaults, ...$el]), 5, null, $category);
    }
}

function customastdb_users_configprocess() {
    $extdisplay = $_REQUEST['extdisplay'] ?? '';
    $extension  = $_REQUEST['extension']  ?? '';
    $target     = ($extdisplay !== '') ? $extdisplay : $extension;
    if ($target === '') return;

    $cd = \FreePBX::Customastdb();

    if (array_key_exists('customastdb_dnd', $_REQUEST)) {
        $cd->setDnd($target, $_REQUEST['customastdb_dnd'] === '1');
    }
    foreach (['cf' => 'CF', 'cfb' => 'CFB', 'cfu' => 'CFU'] as $field => $type) {
        if (array_key_exists('customastdb_' . $field, $_REQUEST)) {
            $cd->setCf($target, $type, trim((string)$_REQUEST['customastdb_' . $field]));
        }
    }
}
