<?php
if (!function_exists('textAttrMap')) {
    function textAttrMap(string $html): array
    {
        $attrs = [];
        if (preg_match_all('/([a-zA-Z_:][-a-zA-Z0-9_:.]*)\s*=\s*("([^"]*)"|\'([^\']*)\'|([^\s"\'>]+))/i', $html, $matches, PREG_SET_ORDER)) {
            foreach ($matches as $match) {
                $value = '';
                if (isset($match[3]) && $match[3] !== '') {
                    $value = $match[3];
                } elseif (isset($match[4]) && $match[4] !== '') {
                    $value = $match[4];
                } elseif (isset($match[5])) {
                    $value = $match[5];
                }

                $attrs[strtolower($match[1])] = html_entity_decode($value, ENT_QUOTES, 'UTF-8');
            }
        }

        return $attrs;
    }
}

if (!function_exists('textCleanLabel')) {
    function textCleanLabel(string $value): string
    {
        $value = preg_replace('/<\?php.*?\?>|<\?.*?\?>/is', '', $value);
        $value = html_entity_decode(strip_tags($value), ENT_QUOTES, 'UTF-8');
        $value = preg_replace('/\s+/', ' ', trim((string)$value));

        return $value;
    }
}

if (!function_exists('textHumanName')) {
    function textHumanName(string $name): string
    {
        $name = preg_replace('/[_\-]+/', ' ', $name);
        $name = preg_replace('/(?<!^)([A-Z])/', ' $1', (string)$name);
        $name = preg_replace('/\s+/', ' ', trim((string)$name));

        return $name !== '' ? ucwords($name) : 'Default text';
    }
}

if (!function_exists('textIsDateField')) {
    function textIsDateField(array $attrs, string $label = ''): bool
    {
        $type = strtolower(trim((string)($attrs['type'] ?? 'text')));
        if (in_array($type, ['date', 'datetime', 'datetime-local', 'month', 'week', 'time'], true)) {
            return true;
        }

        foreach ($attrs as $key => $value) {
            $keyLower = strtolower((string)$key);
            $valueLower = strtolower(trim((string)$value));

            if ($keyLower === 'data-mdb-toggle' && $valueLower === 'datepicker') {
                return true;
            }

            if (strpos($keyLower, 'datepicker') !== false || strpos($keyLower, 'date-picker') !== false) {
                return true;
            }

            if (strpos($valueLower, 'datepicker') !== false || strpos($valueLower, 'date-picker') !== false) {
                return true;
            }
        }

        $markers = [
            (string)($attrs['name'] ?? ''),
            (string)($attrs['id'] ?? ''),
            (string)($attrs['placeholder'] ?? ''),
            (string)($attrs['title'] ?? ''),
            (string)($attrs['aria-label'] ?? ''),
            $label,
        ];

        foreach ($markers as $marker) {
            $marker = trim($marker);
            if ($marker === '') {
                continue;
            }

            if (preg_match('/(^|[\s_\-\/])date($|[\s_\-\/])/i', $marker)) {
                return true;
            }

            $normalised = strtolower((string)preg_replace('/[^a-z0-9]/i', '', $marker));
            if ($normalised === 'date' || $normalised === 'mdate' || strpos($normalised, 'dateof') === 0) {
                return true;
            }

            if (preg_match('/(manufacture|due|review|inspection|expiry|expire|calibration|service|created|completed|report|test|assessment|nextdue)date$/i', $normalised)) {
                return true;
            }
        }

        return false;
    }
}

if (!function_exists('textTenantItemDirectory')) {
    function textTenantItemDirectory(): string
    {
        $coreRoot = dirname(__DIR__, 2);
        $tenant = defined('TENANT_URL') ? trim((string)TENANT_URL, "/\\") : trim((string)($_REQUEST['tenant'] ?? ''), "/\\");
        $candidates = [
            dirname($coreRoot) . '/forms/items',
            $coreRoot . '/forms/items',
        ];

        if ($tenant !== '') {
            $candidates[] = dirname($coreRoot) . '/' . $tenant . '/forms/items';
            $candidates[] = dirname(dirname($coreRoot)) . '/' . $tenant . '/forms/items';
            $candidates[] = $coreRoot . '/' . $tenant . '/forms/items';
        }

        if (!empty($_SERVER['DOCUMENT_ROOT'])) {
            $candidates[] = rtrim((string)$_SERVER['DOCUMENT_ROOT'], "/\\") . '/forms/items';
            if ($tenant !== '') {
                $candidates[] = rtrim((string)$_SERVER['DOCUMENT_ROOT'], "/\\") . '/' . $tenant . '/forms/items';
            }
        }

        foreach (array_unique($candidates) as $candidate) {
            $candidate = str_replace(['\\', '//'], ['/', '/'], $candidate);
            if (is_dir($candidate)) {
                return $candidate;
            }
        }

        return '';
    }
}

if (!function_exists('textReportTitles')) {
    function textReportTitles(): array
    {
        $titles = [];
        $selectedMasterForms = [];

        if (!empty($GLOBALS['con'])) {
            $selectedRes = mysqli_query($GLOBALS['con'], "SELECT `formnumber` FROM `master_formtypes` WHERE `toggle` = 1");
            if ($selectedRes) {
                while ($row = mysqli_fetch_assoc($selectedRes)) {
                    $formNumber = preg_replace('/\D+/', '', (string)($row['formnumber'] ?? ''));
                    if ($formNumber !== '') {
                        $selectedMasterForms[$formNumber] = true;
                    }
                }
            }
        }

        if (!empty($selectedMasterForms) && !empty($GLOBALS['master']) && !empty($GLOBALS['path'])) {
            $path = str_replace('`', '``', (string)$GLOBALS['path']);
            if ($path !== '') {
                $sql = "SELECT `formnumber`, `description` FROM `" . $path . "`.`dd_formtypes`";
                $res = mysqli_query($GLOBALS['master'], $sql);
                if ($res) {
                    while ($row = mysqli_fetch_assoc($res)) {
                        $formNumber = preg_replace('/\D+/', '', (string)($row['formnumber'] ?? ''));
                        if ($formNumber !== '' && isset($selectedMasterForms[$formNumber])) {
                            $titles[$formNumber] = trim((string)($row['description'] ?? ''));
                        }
                    }
                }
            }
        }

        if (!empty($GLOBALS['con'])) {
            $res = mysqli_query($GLOBALS['con'], "SELECT `formnumber`, `description` FROM `dd_formtypes`");
            if ($res) {
                while ($row = mysqli_fetch_assoc($res)) {
                    $formNumber = preg_replace('/\D+/', '', (string)($row['formnumber'] ?? ''));
                    if ($formNumber !== '') {
                        $titles[$formNumber] = trim((string)($row['description'] ?? ''));
                    }
                }
            }
        }

        return $titles;
    }
}

if (!function_exists('textAllowedFormNumbers')) {
    function textAllowedFormNumbers(array $titles): array
    {
        $allowed = [];

        foreach ($titles as $formNumber => $title) {
            $cleanFormNumber = preg_replace('/\D+/', '', (string)$formNumber);
            if ($cleanFormNumber !== '') {
                $allowed[$cleanFormNumber] = true;
            }
        }

        return $allowed;
    }
}

if (!function_exists('textDefaultRows')) {
    function textDefaultRows(): array
    {
        $rows = [];
        if (empty($GLOBALS['con'])) {
            return $rows;
        }

        $res = mysqli_query($GLOBALS['con'], "SELECT `formNumber`, `data` FROM `default_text`");
        if (!$res) {
            return $rows;
        }

        while ($row = mysqli_fetch_assoc($res)) {
            $formNumber = (string)($row['formNumber'] ?? '');
            $cleanFormNumber = preg_replace('/\D+/', '', $formNumber);
            $data = json_decode((string)($row['data'] ?? '{}'), true);
            if ($cleanFormNumber !== '') {
                $rows[$cleanFormNumber] = is_array($data) ? $data : [];
            }
        }

        return $rows;
    }
}

if (!function_exists('textExtractFields')) {
    function textExtractFields(string $file): array
    {
        $contents = file_get_contents($file);
        if (!is_string($contents)) {
            return [];
        }

        $labels = [];
        if (preg_match_all('/<label\b([^>]*)>(.*?)<\/label>/is', $contents, $matches, PREG_SET_ORDER)) {
            foreach ($matches as $match) {
                $attrs = textAttrMap($match[1]);
                $for = trim((string)($attrs['for'] ?? ''));
                if ($for !== '') {
                    $labels[$for] = textCleanLabel($match[2]);
                }
            }
        }

        $fields = [];
        $seen = [];
        $addField = static function (array $attrs, string $kind) use (&$fields, &$seen, $labels): void {
            $type = strtolower(trim((string)($attrs['type'] ?? 'text')));
            if ($kind === 'input' && $type !== '' && $type !== 'text') {
                return;
            }

            $name = trim((string)($attrs['name'] ?? ''));
            if ($name === '') {
                return;
            }

            if (!preg_match('/^[A-Za-z0-9_\-]+$/', $name)) {
                return;
            }

            if (isset($seen[$name])) {
                return;
            }

            $id = trim((string)($attrs['id'] ?? ''));
            $label = '';
            if ($id !== '' && isset($labels[$id])) {
                $label = $labels[$id];
            } elseif (isset($labels[$name])) {
                $label = $labels[$name];
            } elseif (!empty($attrs['placeholder'])) {
                $label = textCleanLabel((string)$attrs['placeholder']);
            }

            if ($label === '') {
                $label = textHumanName($name);
            }

            if (textIsDateField($attrs, $label)) {
                return;
            }

            $seen[$name] = true;
            $fields[] = [
                'name' => $name,
                'label' => $label,
                'kind' => $kind,
            ];
        };

        if (preg_match_all('/<input\b[^>]*>/is', $contents, $matches)) {
            foreach ($matches[0] as $inputHtml) {
                $addField(textAttrMap($inputHtml), 'input');
            }
        }

        if (preg_match_all('/<textarea\b([^>]*)>/is', $contents, $matches, PREG_SET_ORDER)) {
            foreach ($matches as $match) {
                $addField(textAttrMap($match[1]), 'textarea');
            }
        }

        if (preg_match_all('/autofill\s*\((.*?)\)/is', $contents, $matches, PREG_SET_ORDER)) {
            foreach ($matches as $match) {
                if (!preg_match_all('/([\'"])(.*?)\1/', $match[1], $args)) {
                    continue;
                }

                $name = trim((string)($args[2][0] ?? ''));
                if ($name === '') {
                    continue;
                }

                $addField([
                    'name' => $name,
                    'id' => $name,
                    'type' => 'text',
                ], 'textarea');
            }
        }

        usort($fields, static function (array $a, array $b): int {
            return strcasecmp($a['label'], $b['label']);
        });

        return $fields;
    }
}

if (!function_exists('textDiscoveredForms')) {
    function textDiscoveredForms(string $itemDir, array $titles, array $defaults, array $allowedForms): array
    {
        if ($itemDir === '') {
            return [];
        }

        $forms = [];
        $files = glob(rtrim($itemDir, "/\\") . '/*.php');
        if (!is_array($files)) {
            return [];
        }

        foreach ($files as $file) {
            $base = basename($file, '.php');
            if (!preg_match('/^\d+$/', $base)) {
                continue;
            }

            if (!isset($allowedForms[$base])) {
                continue;
            }

            $fields = textExtractFields($file);
            $forms[] = [
                'formNumber' => $base,
                'title' => $titles[$base] ?? ('Report ' . $base),
                'fields' => $fields,
                'defaults' => $defaults[$base] ?? [],
                'hasDefaults' => array_key_exists($base, $defaults),
                'file' => $file,
            ];
        }

        usort($forms, static function (array $a, array $b): int {
            return strnatcasecmp((string)$a['formNumber'], (string)$b['formNumber']);
        });

        return $forms;
    }
}

$itemDir = textTenantItemDirectory();
$reportTitles = textReportTitles();
$allowedForms = textAllowedFormNumbers($reportTitles);
$defaultRows = textDefaultRows();
$forms = textDiscoveredForms($itemDir, $reportTitles, $defaultRows, $allowedForms);
$fieldTotal = 0;
foreach ($forms as $form) {
    $fieldTotal += count($form['fields']);
}
?>

<div class="default-text-page">
    <div class="note note-secondary mb-3">
        Default text is detected from selected reports and custom reports. Text inputs, textareas, and autofill textareas are listed here.
    </div>

    <?php if ($itemDir === '') { ?>
        <div class="alert alert-warning">
            The tenant report input folder could not be found, so default text fields could not be detected.
        </div>
    <?php } ?>

    <div class="row g-3">
        <div class="col-12 col-lg-4 col-xl-3">
            <div class="default-text-list-panel border rounded">
                <div class="p-3 border-bottom">
                    <div class="d-flex justify-content-between align-items-start gap-2">
                        <div>
                            <h5 class="mb-1">Report Inputs</h5>
                            <div class="small text-muted"><?= count($forms) ?> forms, <?= $fieldTotal ?> editable defaults</div>
                        </div>
                    </div>
                    <div class="input-group input-group-sm mt-3">
                        <input type="search" id="defaultTextSearch" class="form-control" placeholder="Search reports">
                        <button type="button" id="defaultTextClear" class="btn btn-light" title="Clear search">
                            <i class="fad fa-times"></i>
                        </button>
                    </div>
                </div>

                <div id="defaultTextList" class="list-group list-group-flush default-text-list">
                    <?php foreach ($forms as $index => $form) { ?>
                        <?php
                        $formNumber = (string)$form['formNumber'];
                        $fieldCount = count($form['fields']);
                        ?>
                        <button type="button"
                                class="list-group-item list-group-item-action default-text-list-item <?= $index === 0 ? 'active' : '' ?>"
                                data-form-target="defaultTextForm<?= htmlspecialchars($formNumber, ENT_QUOTES, 'UTF-8') ?>"
                                data-search="<?= htmlspecialchars(strtolower($formNumber . ' ' . $form['title']), ENT_QUOTES, 'UTF-8') ?>">
                            <span class="d-flex justify-content-between align-items-start gap-2">
                                <span class="min-w-0">
                                    <span class="d-block fw-bold text-truncate"><?= htmlspecialchars((string)$form['title'], ENT_QUOTES, 'UTF-8') ?></span>
                                    <span class="small"><?= htmlspecialchars($formNumber, ENT_QUOTES, 'UTF-8') ?> &middot; <?= $fieldCount ?> field<?= $fieldCount === 1 ? '' : 's' ?></span>
                                </span>
                                <span class="badge default-text-status-list <?= $form['hasDefaults'] ? 'bg-info' : 'bg-warning text-dark' ?>">
                                    <?= $form['hasDefaults'] ? 'Edit' : 'New' ?>
                                </span>
                            </span>
                        </button>
                    <?php } ?>
                </div>
            </div>
        </div>

        <div class="col-12 col-lg-8 col-xl-9">
            <?php if (empty($forms)) { ?>
                <div class="alert alert-info">
                    No selected or custom report input scripts were found in the tenant report folder.
                </div>
            <?php } ?>

            <?php foreach ($forms as $index => $form) { ?>
                <?php
                $formNumber = (string)$form['formNumber'];
                $fields = $form['fields'];
                $defaults = $form['defaults'];
                ?>
                <section id="defaultTextForm<?= htmlspecialchars($formNumber, ENT_QUOTES, 'UTF-8') ?>"
                         class="default-text-editor <?= $index === 0 ? '' : 'd-none' ?>"
                         data-form-number="<?= htmlspecialchars($formNumber, ENT_QUOTES, 'UTF-8') ?>">
                    <div class="border rounded">
                        <div class="p-3 border-bottom bg-light">
                            <div class="d-flex flex-wrap justify-content-between align-items-start gap-3">
                                <div>
                                    <h4 class="mb-1"><?= htmlspecialchars((string)$form['title'], ENT_QUOTES, 'UTF-8') ?></h4>
                                    <div class="text-muted small">
                                        Form <?= htmlspecialchars($formNumber, ENT_QUOTES, 'UTF-8') ?> &middot; <?= count($fields) ?> detected text field<?= count($fields) === 1 ? '' : 's' ?>
                                    </div>
                                </div>
                                <span class="badge default-text-status-editor <?= $form['hasDefaults'] ? 'bg-info' : 'bg-warning text-dark' ?> align-self-start">
                                    <?= $form['hasDefaults'] ? 'Existing default text' : 'Not yet saved' ?>
                                </span>
                            </div>
                        </div>

                        <form class="default-text-form p-3" data-form-number="<?= htmlspecialchars($formNumber, ENT_QUOTES, 'UTF-8') ?>">
                            <input type="hidden" name="formNumber" value="F<?= htmlspecialchars($formNumber, ENT_QUOTES, 'UTF-8') ?>">
                            <input type="hidden" name="default_text_fields" value="<?= htmlspecialchars(json_encode(array_column($fields, 'name')), ENT_QUOTES, 'UTF-8') ?>">

                            <?php if (empty($fields)) { ?>
                                <div class="alert alert-light border mb-0">
                                    No text inputs or textareas were found in this report input script.
                                </div>
                            <?php } else { ?>
                                <div class="row g-3">
                                    <?php foreach ($fields as $field) { ?>
                                        <?php
                                        $name = (string)$field['name'];
                                        $value = (string)($defaults[$name] ?? '');
                                        ?>
                                        <div class="col-12 col-xl-6">
                                            <label class="form-label" for="dt_<?= htmlspecialchars($formNumber . '_' . $name, ENT_QUOTES, 'UTF-8') ?>">
                                                <?= htmlspecialchars((string)$field['label'], ENT_QUOTES, 'UTF-8') ?>
                                            </label>
                                            <div class="small text-muted mb-1"><?= htmlspecialchars($name, ENT_QUOTES, 'UTF-8') ?></div>
                                            <?php if ($field['kind'] === 'textarea') { ?>
                                                <textarea class="form-control"
                                                          id="dt_<?= htmlspecialchars($formNumber . '_' . $name, ENT_QUOTES, 'UTF-8') ?>"
                                                          name="<?= htmlspecialchars($name, ENT_QUOTES, 'UTF-8') ?>"
                                                          rows="4"><?= htmlspecialchars($value, ENT_QUOTES, 'UTF-8') ?></textarea>
                                            <?php } else { ?>
                                                <input type="text"
                                                       class="form-control"
                                                       id="dt_<?= htmlspecialchars($formNumber . '_' . $name, ENT_QUOTES, 'UTF-8') ?>"
                                                       name="<?= htmlspecialchars($name, ENT_QUOTES, 'UTF-8') ?>"
                                                       value="<?= htmlspecialchars($value, ENT_QUOTES, 'UTF-8') ?>">
                                            <?php } ?>
                                        </div>
                                    <?php } ?>
                                </div>

                                <div class="d-flex justify-content-end mt-3">
                                    <button type="submit" class="btn btn-info default-text-save">
                                        <i class="fad fa-save me-1"></i> Save Defaults
                                    </button>
                                </div>
                            <?php } ?>
                        </form>
                    </div>
                </section>
            <?php } ?>
        </div>
    </div>
</div>

<style>
    .default-text-list-panel {
        background: #ffffff;
        overflow: hidden;
    }

    .default-text-list {
        max-height: 68vh;
        overflow: auto;
    }

    .default-text-list-item {
        text-align: left;
    }

    .default-text-list-item.active {
        background: #2f485e;
        border-color: #2f485e;
        color: #ffffff;
    }

    .default-text-list-item.active .text-muted,
    .default-text-list-item.active .small {
        color: rgba(255, 255, 255, .82) !important;
    }

    .default-text-editor textarea {
        min-height: 112px;
    }

    @media (max-width: 991.98px) {
        .default-text-list {
            max-height: 260px;
        }
    }
</style>

<script>
document.getElementById('navBox').innerHTML = '<li class="breadcrumb-item">Tools <i class="fad fa-angle-double-right mx-2 mt-1" aria-hidden="true"></i></li><li class="breadcrumb-item active">Default Text</li>';

(function () {
    const list = document.getElementById('defaultTextList');
    const search = document.getElementById('defaultTextSearch');
    const clear = document.getElementById('defaultTextClear');

    function showEditor(targetId) {
        document.querySelectorAll('.default-text-editor').forEach((editor) => {
            editor.classList.toggle('d-none', editor.id !== targetId);
        });

        document.querySelectorAll('.default-text-list-item').forEach((item) => {
            item.classList.toggle('active', item.getAttribute('data-form-target') === targetId);
        });
    }

    if (list) {
        list.addEventListener('click', (event) => {
            const button = event.target.closest('.default-text-list-item');
            if (!button) return;
            showEditor(button.getAttribute('data-form-target'));
        });
    }

    function filterForms() {
        const term = search ? search.value.trim().toLowerCase() : '';
        let firstVisible = null;

        document.querySelectorAll('.default-text-list-item').forEach((item) => {
            const match = term === '' || (item.getAttribute('data-search') || '').indexOf(term) !== -1;
            item.style.display = match ? '' : 'none';
            if (match && !firstVisible) firstVisible = item;
        });

        const active = document.querySelector('.default-text-list-item.active');
        if ((!active || active.style.display === 'none') && firstVisible) {
            showEditor(firstVisible.getAttribute('data-form-target'));
        }
    }

    if (search) search.addEventListener('input', filterForms);
    if (clear) {
        clear.addEventListener('click', () => {
            if (!search) return;
            search.value = '';
            filterForms();
            search.focus();
        });
    }

    document.querySelectorAll('.default-text-form').forEach((form) => {
        form.addEventListener('submit', (event) => {
            event.preventDefault();
            const button = form.querySelector('.default-text-save');
            const formData = new FormData(form);
            formData.append('tenant', typeof TENANT_URL !== 'undefined' ? TENANT_URL : '');

            if (button) {
                button.disabled = true;
                button.innerHTML = '<i class="fad fa-spinner-third fa-spin me-1"></i> Saving';
            }

            fetch(ROOT_URL + '/includes/master/text_functions.php', {
                method: 'POST',
                body: formData
            })
                .then((response) => response.text())
                .then((text) => {
                    if (text.trim() === 'success') {
                        const editor = form.closest('.default-text-editor');
                        const targetId = editor ? editor.id : '';
                        const listButton = targetId ? document.querySelector('.default-text-list-item[data-form-target="' + targetId + '"]') : null;
                        const listBadge = listButton ? listButton.querySelector('.default-text-status-list') : null;
                        const editorBadge = editor ? editor.querySelector('.default-text-status-editor') : null;

                        [listBadge, editorBadge].forEach((badge) => {
                            if (!badge) return;
                            badge.classList.remove('bg-warning', 'text-dark');
                            badge.classList.add('bg-info');
                        });

                        if (listBadge) listBadge.textContent = 'Edit';
                        if (editorBadge) editorBadge.textContent = 'Existing default text';
                        showResponse('success', 'Default text saved successfully');
                    } else {
                        showResponse('danger', 'There was a problem saving the default text<br><br>' + text);
                    }
                })
                .catch(() => showResponse('danger', 'There was a problem saving the default text'))
                .finally(() => {
                    if (button) {
                        button.disabled = false;
                        button.innerHTML = '<i class="fad fa-save me-1"></i> Save Defaults';
                    }
                });
        });
    });
})();
</script>
