<?php
if (!isset($GLOBALS['con']) || !($GLOBALS['con'] instanceof mysqli)) {
    if (file_exists('../../../' . ($_REQUEST['tenant'] ?? '') . '/config.php')) {
        require_once('../../../' . ($_REQUEST['tenant'] ?? '') . '/config.php');
    }
    if (file_exists('/config.php')) {
        require_once('/config.php');
    }
}

if (!function_exists('jumpPlantColourMap')) {
    function jumpPlantColourMap(): array
    {
        return [
            'rose'   => ['bg' => '#fce4ec', 'text' => '#6a1b3a', 'label' => 'Rose'],
            'red'    => ['bg' => '#fdecea', 'text' => '#7f1d1d', 'label' => 'Red'],
            'orange' => ['bg' => '#fff3e0', 'text' => '#8a3b12', 'label' => 'Orange'],
            'amber'  => ['bg' => '#fff8e1', 'text' => '#7a5600', 'label' => 'Amber'],
            'yellow' => ['bg' => '#fffde7', 'text' => '#6b5b00', 'label' => 'Yellow'],
            'lime'   => ['bg' => '#f1f8e9', 'text' => '#466a12', 'label' => 'Lime'],
            'green'  => ['bg' => '#e8f5e9', 'text' => '#1b5e20', 'label' => 'Green'],
            'mint'   => ['bg' => '#e6f7f1', 'text' => '#0f5c4d', 'label' => 'Mint'],
            'cyan'   => ['bg' => '#e0f7fa', 'text' => '#155e75', 'label' => 'Cyan'],
            'blue'   => ['bg' => '#e3f2fd', 'text' => '#0d47a1', 'label' => 'Blue'],
            'indigo' => ['bg' => '#e8eaf6', 'text' => '#283593', 'label' => 'Indigo'],
            'purple' => ['bg' => '#f3e5f5', 'text' => '#6a1b9a', 'label' => 'Purple']
        ];
    }
}

function jumpPlantColourBadge(?string $rowColour): string
{
    $rowColour = trim((string)$rowColour);
    $map = jumpPlantColourMap();

    if ($rowColour === '' || !isset($map[$rowColour])) {
        return '<span class="badge rounded-pill bg-light text-dark border">None</span>';
    }

    $cfg = $map[$rowColour];

    return '<span class="badge rounded-pill border" style="background:' . htmlspecialchars($cfg['bg']) . '; color:' . htmlspecialchars($cfg['text']) . ';">'
        . '<i class="fad fa-palette me-1"></i>'
        . htmlspecialchars($cfg['label'])
        . '</span>';
}

if (!function_exists('jumpPlantRenderRow')) {
    function jumpPlantRenderRow(array $d): void
    {
        $id = (int)($d['id'] ?? 0);
        $code = (string)($d['code'] ?? '');
        $desc = (string)($d['description'] ?? '');
        $freq = (int)($d['frequency'] ?? 0);
        $units = (string)($d['units'] ?? '');
        $doc = (string)($d['doc_file'] ?? '');
        $rowColour = trim((string)($d['row_colour'] ?? ''));
        $deliveryExclusion = (int)($d['delivery_exclusion'] ?? 0) === 1;

        $map = jumpPlantColourMap();
        $cfg = $map[$rowColour] ?? null;
?><style>
.plant-tool-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: end;
    margin-bottom: 10px;
}

.plant-toolbar-group {
    background: #f6f8fb;
    border: 1px solid #dfe5ec;
    border-radius: 6px;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    min-height: 66px;
    min-width: 0;
    padding: 8px;
}

.plant-search-group {
    flex: 0 1 520px;
}

.plant-rows-group {
    flex: 0 1 145px;
}

.plant-csv-group {
    flex: 0 1 330px;
    margin-left: auto;
}

.plant-toolbar-label {
    color: #6b7785;
    display: block;
    font-size: 0.76rem;
    font-weight: 700;
    margin-bottom: 6px;
    text-transform: uppercase;
}

.plant-control-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 38px;
    gap: 6px;
    align-items: center;
}

.plant-csv-actions {
    display: grid;
    gap: 6px;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    width: 100%;
}

.plant-control-row .form-control,
.plant-rows-group .form-select,
.plant-csv-actions .btn,
.plant-icon-btn {
    min-height: 32px;
}

.plant-csv-actions .btn {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.plant-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 36px;
    padding: 0.35rem 0.55rem;
}

.plant-row-hidden,
.plant-row-page-hidden {
    display: none !important;
}

.plant-sort-col {
    cursor: pointer;
    padding-right: 1.4rem !important;
    position: relative;
    user-select: none;
    white-space: nowrap;
}

.plant-sort-col::after {
    color: rgba(255, 255, 255, .45);
    content: "\f0dc";
    font-family: "Font Awesome 6 Duotone", "Font Awesome 5 Duotone", "Font Awesome 6 Pro", "Font Awesome 5 Pro", "Font Awesome 6 Free";
    font-size: .75rem;
    font-weight: 900;
    position: absolute;
    right: .45rem;
    top: 50%;
    transform: translateY(-50%);
}

.plant-sort-col.plant-sort-active::after {
    color: #ffffff;
}

.plant-sort-col.plant-sort-asc::after {
    content: "\f0de";
}

.plant-sort-col.plant-sort-desc::after {
    content: "\f0dd";
}

.plant-pagination-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-top: 14px;
    color: #6b7785;
    font-size: 0.9rem;
}

.plant-pagination-controls,
.plant-page-buttons {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    justify-content: flex-end;
}

.plant-page-buttons {
    gap: 6px;
}

.plant-page-btn {
    min-width: 34px;
}

.plant-page-btn.active {
    background: #2d445d;
    border-color: #2d445d;
    color: #fff;
}

@media (max-width: 575.98px) {
    .plant-tool-grid {
        gap: 6px;
        margin-bottom: 8px;
    }

    .plant-toolbar-group {
        flex: 1 1 100%;
        min-height: 62px;
        padding: 6px;
    }

    .plant-csv-group {
        margin-left: 0;
    }

    .plant-toolbar-label {
        font-size: 0.68rem;
        margin-bottom: 3px;
    }

    .plant-control-row {
        grid-template-columns: minmax(0, 1fr) 32px;
        gap: 4px;
    }

    .plant-csv-actions .btn {
        font-size: 0.72rem;
        min-height: 30px;
        padding: 0.25rem 0.35rem;
    }
}
</style>
<tr id="R<?= htmlspecialchars($code) ?>" class="plant-row" data-plant-id="<?= $id ?>"
    data-plant-code="<?= htmlspecialchars($code) ?>" data-row-colour="<?= htmlspecialchars($rowColour) ?>">
    <td class="plant-code-cell"><span><?= htmlspecialchars($code) ?></span></td>
    <td class="plant-description-cell"><span><?= htmlspecialchars($desc) ?></span></td>
    <td class="plant-frequency-cell"><span><?= $freq ?></span></td>
    <td class="plant-units-cell"><span><?= htmlspecialchars($units) ?></span></td>

    <td class="text-center">
        <button type="button" class="btn btn-link btn-sm p-0 text-decoration-none"
            onclick="openPlantColourModal(<?= $id ?>,'<?= htmlspecialchars($rowColour, ENT_QUOTES) ?>')"
            data-mdb-tooltip-init data-mdb-placement="top" data-mdb-trigger="hover" title="Set row colour">
            <?php if ($cfg): ?>
            <span class="badge rounded-pill"
                style="background:<?= htmlspecialchars($cfg['bg']) ?>; color:<?= htmlspecialchars($cfg['text']) ?>; border:1px solid rgba(0,0,0,0.08);">
                <i class="fad fa-palette me-1"></i><?= htmlspecialchars($cfg['label']) ?>
            </span>
            <?php else: ?>
            <span class="badge rounded-pill bg-light text-dark border">
                <i class="fad fa-palette me-1"></i>None
            </span>
            <?php endif; ?>
        </button>
    </td>

    <td class="text-center">
        <div class="form-check form-switch d-inline-flex align-items-center justify-content-center mb-0">
            <input class="form-check-input plant-delivery-exclusion" type="checkbox" role="switch"
                id="plantDeliveryExclusion_<?= $id ?>" data-plant-id="<?= $id ?>"
                <?= $deliveryExclusion ? 'checked' : '' ?> data-mdb-tooltip-init data-mdb-placement="top"
                data-mdb-trigger="hover" title="Exclude this plant code from delivery report lists">
            <label class="form-check-label ms-2 small" for="plantDeliveryExclusion_<?= $id ?>">
                <?= $deliveryExclusion ? 'Excluded' : 'Include' ?>
            </label>
        </div>
    </td>

    <td>
        <div class="d-flex align-items-center gap-2 flex-wrap">
            <?php if (!empty($doc)): ?>
            <a class="btn btn-sm btn-secondary" href="/<?= TENANT_URL ?>/resources/plantFiles/<?= rawurlencode($doc) ?>"
                download data-mdb-tooltip-init data-mdb-placement="top" data-mdb-trigger="hover"
                title="Download attached document">
                <i class="fad fa-file"></i>
            </a>

            <button type="button" class="btn btn-sm btn-danger" onclick="deletePlantDoc_UI(<?= $id ?>)"
                data-mdb-tooltip-init data-mdb-placement="top" data-mdb-trigger="hover" title="Remove document">
                <i class="fad fa-trash"></i>
            </button>

            <span class="text-muted small ms-2" data-mdb-tooltip-init data-mdb-placement="top" data-mdb-trigger="hover"
                title="<?= htmlspecialchars($doc) ?>">
                <?= htmlspecialchars($doc) ?>
            </span>
            <?php else: ?>
            <div class="d-flex align-items-center gap-2">
                <input class="form-control form-control-sm" style="max-width:220px" type="file"
                    id="plantDocInput_<?= $id ?>" accept=".pdf,.doc,.docx,.xls,.xlsx,.csv,.png,.jpg,.jpeg,.webp" />

                <button type="button" class="btn btn-sm btn-success" onclick="uploadPlantDoc_UI(<?= $id ?>)"
                    data-mdb-tooltip-init data-mdb-placement="top" data-mdb-trigger="hover" title="Upload document">
                    <i class="fad fa-upload"></i>
                </button>
            </div>
            <?php endif; ?>
        </div>
    </td>

    <td class="text-end">
        <button class="btn btn-secondary me-3" onclick="editPlant_UI(<?= $id ?>)" type="button" data-mdb-tooltip-init
            data-mdb-placement="top" data-mdb-trigger="hover" title="Edit plant">
            <i class="fad fa-pencil" aria-hidden="true"></i>
        </button>

        <button class="btn btn-danger" type="button" onclick="removePlant('plant',<?= $id ?>)" data-mdb-tooltip-init
            data-mdb-placement="top" data-mdb-trigger="hover" title="Remove plant entry">
            <i class="fad fa-trash" aria-hidden="true"></i>
        </button>
    </td>
</tr>
<?php
    }
}

if (isset($_REQUEST['mode']) && $_REQUEST['mode'] === 'row') {
    $id = (int)($_REQUEST['id'] ?? 0);

    if ($id <= 0) {
        http_response_code(400);
        exit('<!-- invalid id -->');
    }

    $stmt = $GLOBALS['con']->prepare("SELECT * FROM `dd_plant` WHERE `id` = ? LIMIT 1") or die(mysqli_error($GLOBALS['con']));
    $stmt->bind_param('i', $id);
    $stmt->execute();
    $rs = $stmt->get_result();
    $row = $rs ? $rs->fetch_assoc() : null;
    $stmt->close();

    if (!$row) {
        http_response_code(404);
        exit('<!-- not found -->');
    }

    jumpPlantRenderRow($row);
    exit();
}

$stmt = $GLOBALS['con']->prepare("SELECT * FROM `dd_plant` ORDER BY `code` ASC") or die(mysqli_error($GLOBALS['con']));
$stmt->execute();
$rslt = $stmt->get_result();
$stmt->close();

$groupFilter = trim((string)($_REQUEST['group_id'] ?? ''));
?>

<div class="col-md-12 pt-4" id="plantListRoot"
    data-row-endpoint="<?= htmlspecialchars(ROOT_URL . '/includes/jump/jump_plant.php') ?>"
    data-csv-endpoint="<?= htmlspecialchars(ROOT_URL . '/includes/jump/jump_plant_csv.php') ?>">
    <div class="plant-tool-grid">
        <div class="plant-toolbar-group plant-search-group">
            <label class="plant-toolbar-label" for="plantSearch">
                <i class="fad fa-search me-1" aria-hidden="true"></i>Search Plant
            </label>
            <div class="plant-control-row">
                <input type="search" id="plantSearch" class="form-control form-control-sm"
                    placeholder="Search code, description or values" autocomplete="off">
                <button type="button" id="plantSearchClear" class="btn btn-sm btn-light plant-icon-btn"
                    data-mdb-tooltip-init data-mdb-placement="top" data-mdb-trigger="hover" title="Clear search">
                    <i class="fad fa-times"></i>
                </button>
            </div>
        </div>

        <div class="plant-toolbar-group plant-rows-group">
            <label class="plant-toolbar-label" for="plantRows">
                <i class="fad fa-list-ol me-1" aria-hidden="true"></i>Show Rows
            </label>
            <select id="plantRows" class="form-select form-select-sm" data-mdb-tooltip-init data-mdb-placement="top"
                data-mdb-trigger="hover" title="Rows per page">
                <option value="10">10 rows</option>
                <option value="25" selected>25 rows</option>
                <option value="50">50 rows</option>
                <option value="100">100 rows</option>
                <option value="150">150 rows</option>
                <option value="200">200 rows</option>
                <option value="500">500 rows</option>
                <option value="-1">All rows</option>
            </select>
        </div>

        <div class="plant-toolbar-group plant-csv-group">
            <span class="plant-toolbar-label">
                <i class="fad fa-file-csv me-1" aria-hidden="true"></i>CSV
            </span>
            <div class="plant-csv-actions">
                <a class="btn btn-sm btn-light"
                    href="<?= htmlspecialchars(ROOT_URL . '/includes/jump/jump_plant_csv.php?action=template&tenant=' . urlencode(TENANT_URL)) ?>"
                    data-mdb-tooltip-init data-mdb-placement="top" data-mdb-trigger="hover"
                    title="Download blank plant import template">
                    <i class="fad fa-file-download me-1"></i>Template
                </a>
                <a class="btn btn-sm btn-light"
                    href="<?= htmlspecialchars(ROOT_URL . '/includes/jump/jump_plant_csv.php?action=export&tenant=' . urlencode(TENANT_URL)) ?>"
                    data-mdb-tooltip-init data-mdb-placement="top" data-mdb-trigger="hover" title="Export plant list">
                    <i class="fad fa-file-export me-1"></i>Export
                </a>
                <button type="button" id="plantImportCsv" class="btn btn-sm btn-primary" data-mdb-tooltip-init
                    data-mdb-placement="top" data-mdb-trigger="hover" title="Import or update plant rows from CSV">
                    <i class="fad fa-file-import me-1"></i>Import
                </button>
                <input type="file" id="plantImportFile" class="d-none" accept=".csv,text/csv">
            </div>
        </div>
    </div>

    <table id="plantTable" class="table table-striped table-hover table-sm responsive" style="width:100%">
        <thead class="table-dark">
            <tr>
                <th width="10%" class="plant-sort-col" data-plant-sort="code">Code</th>
                <th class="plant-sort-col" data-plant-sort="description">Description</th>
                <th class="plant-sort-col" data-plant-sort="frequency">Frequency</th>
                <th class="plant-sort-col" data-plant-sort="units">Units</th>
                <th class="plant-sort-col" data-plant-sort="row_colour">Row Colour</th>
                <th class="plant-sort-col" data-plant-sort="delivery_exclusion">Delivery Exclusion</th>
                <th class="plant-sort-col" data-plant-sort="document">Document</th>
                <th class="no-sort"></th>
            </tr>
        </thead>
        <tbody>
            <?php
            if ($rslt) {
                while ($d = $rslt->fetch_assoc()) {
                    jumpPlantRenderRow($d);
                }
            }
            ?>
        </tbody>
    </table>

    <div class="plant-pagination-bar">
        <div id="plantSummary" class="plant-summary"></div>
        <div class="plant-pagination-controls">
            <button type="button" id="plantPrev" class="btn btn-sm btn-light">
                <i class="fad fa-chevron-left me-1"></i>Prev
            </button>
            <div id="plantPages" class="plant-page-buttons"></div>
            <button type="button" id="plantNext" class="btn btn-sm btn-light">
                Next<i class="fad fa-chevron-right ms-1"></i>
            </button>
        </div>
    </div>
</div>



<script>
(function() {
    const root = document.getElementById('plantListRoot');
    const rowEndpoint = root ? root.getAttribute('data-row-endpoint') : '';
    const csvEndpoint = root ? root.getAttribute('data-csv-endpoint') : '';
    const tenant = (typeof TENANT_URL !== 'undefined') ? TENANT_URL : '';
    const searchInput = document.getElementById('plantSearch');
    const searchClear = document.getElementById('plantSearchClear');
    const rowsSelect = document.getElementById('plantRows');
    const importButton = document.getElementById('plantImportCsv');
    const importFile = document.getElementById('plantImportFile');
    const table = document.getElementById('plantTable');
    const tbody = table ? table.querySelector('tbody') : null;
    const controls = {
        summary: document.getElementById('plantSummary'),
        prev: document.getElementById('plantPrev'),
        next: document.getElementById('plantNext'),
        pages: document.getElementById('plantPages')
    };
    const state = {
        search: '',
        rowsPerPage: 25,
        page: 1,
        sortField: 'code',
        sortDir: 'asc',
        filteredRows: [],
        visibleRows: []
    };
    let allRows = [];

    const lastAction = window.jumpPlantLastAction || {
        type: null,
        id: null
    };
    window.jumpPlantLastAction = lastAction;

    function initTooltips(scope) {
        if (typeof mdb === 'undefined' || !scope) return;
        const els = scope.querySelectorAll('[data-mdb-tooltip-init]');
        els.forEach((el) => {
            try {
                if (mdb.Tooltip.getInstance && mdb.Tooltip.getInstance(el)) return;
            } catch (e) {}
            try {
                new mdb.Tooltip(el);
            } catch (e) {}
        });
    }

    function findRowById(id) {
        return document.querySelector('tr[data-plant-id="' + String(id) + '"]');
    }

    function removePlantRow(id) {
        const row = findRowById(id);
        if (row) {
            row.remove();
            renderPlantTable(true);
        }
    }

    function buildRowUrl(id) {
        return rowEndpoint +
            '?mode=row&id=' + encodeURIComponent(String(id)) +
            '&tenant=' + encodeURIComponent(String(tenant)) +
            '&_=' + Date.now();
    }

    async function fetchRowResponse(id) {
        if (!rowEndpoint) return null;
        try {
            return await fetch(buildRowUrl(id), {
                method: 'GET',
                credentials: 'same-origin'
            });
        } catch (e) {
            return null;
        }
    }

    async function fetchPlantRowHtml(id) {
        const res = await fetchRowResponse(id);
        if (!res || !res.ok) return '';
        try {
            return (await res.text()).trim();
        } catch (e) {
            return '';
        }
    }

    async function refreshPlantRow(id) {
        const row = findRowById(id);
        if (!row) return;

        const html = await fetchPlantRowHtml(id);
        if (!html) return;

        const tmp = document.createElement('tbody');
        tmp.innerHTML = html;
        const newRow = tmp.querySelector('tr');
        if (!newRow) return;

        row.replaceWith(newRow);
        initTooltips(newRow);
        renderPlantTable(true);
    }

    function pollRefresh(id, predicate, attempts = 10, delayMs = 450) {
        let n = 0;

        const tick = async () => {
            n++;
            const res = await fetchRowResponse(id);

            if (res && res.ok) {
                const html = (await res.text()).trim();
                if (html && (!predicate || predicate(html))) {
                    const row = findRowById(id);
                    if (row) {
                        const tmp = document.createElement('tbody');
                        tmp.innerHTML = html;
                        const newRow = tmp.querySelector('tr');
                        if (newRow) {
                            row.replaceWith(newRow);
                            initTooltips(newRow);
                            renderPlantTable(true);
                        }
                    }
                    return;
                }
            }

            if (n < attempts) setTimeout(tick, delayMs);
        };

        setTimeout(tick, delayMs);
    }

    function pollRemove(id, attempts = 12, delayMs = 450) {
        let n = 0;

        const tick = async () => {
            n++;
            const res = await fetchRowResponse(id);

            if (res && res.status === 404) {
                const row = findRowById(id);

                if (row) {
                    row.style.transition = 'opacity 0.35s ease';
                    row.style.opacity = '0';
                    row.style.pointerEvents = 'none';

                    setTimeout(() => {
                        removePlantRow(id);
                    }, 350);
                } else {
                    removePlantRow(id);
                }

                return;
            }

            if (n < attempts) {
                setTimeout(tick, delayMs);
            }
        };

        setTimeout(tick, delayMs);
    }

    async function setPlantDeliveryExclusion(input) {
        const id = input.getAttribute('data-plant-id') || '';
        if (!id) return;

        const selected = input.checked ? '1' : '0';
        input.disabled = true;

        try {
            const res = await fetch(ROOT_URL + '/includes/jump/jump_functions.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                },
                body: new URLSearchParams({
                    FUNCTION: 'setPlantDeliveryExclusion',
                    id,
                    delivery_exclusion: selected,
                    tenant: String(TENANT_URL)
                })
            });

            const ret = String(await res.text()).trim();
            if (ret !== 's') {
                input.checked = selected !== '1';
                if (typeof showResponse === 'function') showResponse('danger', ret ||
                    'UNABLE TO UPDATE DELIVERY EXCLUSION');
                return;
            }

            const label = input.closest('.form-check')?.querySelector('label');
            if (label) label.textContent = input.checked ? 'Excluded' : 'Include';
            if (typeof showResponse === 'function') showResponse('success', 'DELIVERY EXCLUSION UPDATED');
        } catch (e) {
            input.checked = selected !== '1';
            if (typeof showResponse === 'function') showResponse('danger',
                'UNABLE TO UPDATE DELIVERY EXCLUSION');
        } finally {
            input.disabled = false;
        }
    }

    document.addEventListener('change', function(event) {
        const input = event.target.closest('.plant-delivery-exclusion');
        if (!input) return;
        setPlantDeliveryExclusion(input);
    });

    async function importPlantCsv(file) {
        if (!file || !csvEndpoint) return;

        const form = new FormData();
        form.append('csv', file);
        form.append('tenant', String(tenant));

        if (importButton) importButton.disabled = true;

        try {
            const res = await fetch(csvEndpoint + '?action=import&tenant=' + encodeURIComponent(String(
                tenant)) + '&_=' + Date.now(), {
                    method: 'POST',
                    credentials: 'same-origin',
                    body: form
                });

            const text = await res.text();
            let data = null;
            try {
                data = JSON.parse(text);
            } catch (e) {}

            if (!res.ok || !data) {
                if (typeof showResponse === 'function') showResponse('danger', data && data.message ? data
                    .message : 'CSV IMPORT FAILED');
                return;
            }

            if (Array.isArray(data.warnings) && data.warnings.length) {
                console.warn('Plant CSV import warnings:', data.warnings);
            }

            const changedRows = Number(data.inserted || 0) + Number(data.updated || 0);
            const type = data.success ? (changedRows > 0 ? 'success' : 'warning') : 'danger';
            if (typeof showResponse === 'function') {
                showResponse(type, String(data.message || 'CSV IMPORT COMPLETE').toUpperCase());
            }

            if (changedRows > 0) {
                setTimeout(() => {
                    window.location.reload();
                }, 900);
            }
        } catch (e) {
            if (typeof showResponse === 'function') showResponse('danger', 'CSV IMPORT FAILED');
        } finally {
            if (importButton) importButton.disabled = false;
            if (importFile) importFile.value = '';
        }
    }

    if (importButton && importFile) {
        importButton.addEventListener('click', () => {
            importFile.value = '';
            importFile.click();
        });

        importFile.addEventListener('change', () => {
            const file = importFile.files && importFile.files.length ? importFile.files[0] : null;
            importPlantCsv(file);
        });
    }

    function refreshPlantRows() {
        allRows = tbody ? Array.from(tbody.querySelectorAll('tr.plant-row')) : [];
    }

    function normalise(value) {
        return String(value || '').toLowerCase().replace(/\s+/g, ' ').trim();
    }

    function plantRowText(row) {
        return normalise(row.textContent || '');
    }

    function plantCellText(row, selector) {
        const el = row.querySelector(selector);
        return normalise(el ? el.textContent : '');
    }

    function plantSortValue(row, field) {
        if (field === 'description') return plantCellText(row, '.plant-description-cell');
        if (field === 'frequency') return Number(plantCellText(row, '.plant-frequency-cell')) || 0;
        if (field === 'units') return Number(plantCellText(row, '.plant-units-cell')) || 0;
        if (field === 'row_colour') return normalise(row.getAttribute('data-row-colour') || '');
        if (field === 'delivery_exclusion') {
            const input = row.querySelector('.plant-delivery-exclusion');
            return input && input.checked ? 1 : 0;
        }
        if (field === 'document') {
            const docCell = row.querySelector('td:nth-child(7)');
            return normalise(docCell ? docCell.textContent : '');
        }

        return normalise(row.getAttribute('data-plant-code') || plantCellText(row, '.plant-code-cell'));
    }

    function plantRowMatches(row) {
        return state.search === '' || plantRowText(row).includes(state.search);
    }

    function sortPlantRows(rows) {
        const dir = state.sortDir === 'desc' ? -1 : 1;
        const field = state.sortField || 'code';

        rows.sort((a, b) => {
            const av = plantSortValue(a, field);
            const bv = plantSortValue(b, field);

            if (typeof av === 'number' || typeof bv === 'number') {
                const cmp = (Number(av) || 0) - (Number(bv) || 0);
                if (cmp !== 0) return cmp * dir;
            } else {
                const cmp = String(av).localeCompare(String(bv), undefined, {
                    numeric: true,
                    sensitivity: 'base'
                });
                if (cmp !== 0) return cmp * dir;
            }

            return Number(a.getAttribute('data-plant-id') || 0) - Number(b.getAttribute('data-plant-id') ||
                0);
        });

        return rows;
    }

    function plantPageCount() {
        if (state.rowsPerPage === 'all') return 1;
        return Math.max(1, Math.ceil(state.filteredRows.length / state.rowsPerPage));
    }

    function plantPageRows() {
        if (state.rowsPerPage === 'all') return state.filteredRows;
        const start = (state.page - 1) * state.rowsPerPage;
        return state.filteredRows.slice(start, start + state.rowsPerPage);
    }

    function updatePlantSortHeaders() {
        if (!table) return;
        table.querySelectorAll('[data-plant-sort]').forEach((header) => {
            const active = header.getAttribute('data-plant-sort') === state.sortField;
            header.classList.toggle('plant-sort-active', active);
            header.classList.toggle('plant-sort-asc', active && state.sortDir === 'asc');
            header.classList.toggle('plant-sort-desc', active && state.sortDir === 'desc');
        });
    }

    function updatePlantSummary() {
        if (!controls.summary) return;

        const total = allRows.length;
        const filtered = state.filteredRows.length;

        if (filtered === 0) {
            controls.summary.textContent = total === 0 ? 'No plant found' : 'No matching plant';
            return;
        }

        const first = state.rowsPerPage === 'all' ? 1 : ((state.page - 1) * state.rowsPerPage) + 1;
        const last = state.rowsPerPage === 'all' ? filtered : Math.min(filtered, first + state.rowsPerPage - 1);
        controls.summary.textContent = 'Showing ' + first + ' to ' + last + ' of ' + filtered + ' plant entries' + (
            filtered !== total ? ' (' + total + ' total)' : '');
    }

    function visiblePlantPageNumbers(totalPages, currentPage) {
        const pages = [];
        const add = (value) => {
            if (!pages.includes(value)) pages.push(value);
        };

        add(1);
        for (let page = currentPage - 2; page <= currentPage + 2; page++) {
            if (page > 1 && page < totalPages) add(page);
        }
        if (totalPages > 1) add(totalPages);

        pages.sort((a, b) => a - b);
        return pages;
    }

    function updatePlantPagination() {
        const totalPages = plantPageCount();

        if (controls.prev) controls.prev.disabled = state.page <= 1;
        if (controls.next) controls.next.disabled = state.page >= totalPages;
        if (!controls.pages) return;

        controls.pages.innerHTML = '';
        if (totalPages <= 1) return;

        let previous = 0;
        visiblePlantPageNumbers(totalPages, state.page).forEach((page) => {
            if (previous && page - previous > 1) {
                const gap = document.createElement('span');
                gap.className = 'px-1 text-muted';
                gap.textContent = '...';
                controls.pages.appendChild(gap);
            }

            const btn = document.createElement('button');
            btn.type = 'button';
            btn.className = 'btn btn-sm btn-light plant-page-btn' + (page === state.page ? ' active' : '');
            btn.textContent = String(page);
            btn.addEventListener('click', () => {
                state.page = page;
                renderPlantTable(true);
            });
            controls.pages.appendChild(btn);
            previous = page;
        });
    }

    function renderPlantTable(keepPage) {
        refreshPlantRows();
        state.filteredRows = sortPlantRows(allRows.filter(plantRowMatches));

        const totalPages = plantPageCount();
        if (!keepPage) state.page = 1;
        state.page = Math.min(Math.max(1, state.page), totalPages);
        state.visibleRows = plantPageRows();

        const visibleSet = new Set(state.visibleRows);
        allRows.forEach((row) => {
            const matches = plantRowMatches(row);
            row.classList.toggle('plant-row-hidden', !matches);
            row.classList.toggle('plant-row-page-hidden', !visibleSet.has(row));
        });

        if (tbody) {
            state.filteredRows.forEach((row) => tbody.appendChild(row));
        }

        updatePlantSummary();
        updatePlantPagination();
        updatePlantSortHeaders();
    }

    if (searchInput) {
        searchInput.addEventListener('input', () => {
            state.search = normalise(searchInput.value);
            renderPlantTable(false);
        });
    }

    if (searchClear && searchInput) {
        searchClear.addEventListener('click', () => {
            searchInput.value = '';
            state.search = '';
            renderPlantTable(false);
            searchInput.focus();
        });
    }

    if (rowsSelect) {
        rowsSelect.addEventListener('change', () => {
            state.rowsPerPage = rowsSelect.value === '-1' ? 'all' : parseInt(rowsSelect.value, 10);
            if (!state.rowsPerPage || Number.isNaN(state.rowsPerPage)) state.rowsPerPage = 25;
            renderPlantTable(false);
        });
    }

    if (controls.prev) {
        controls.prev.addEventListener('click', () => {
            if (state.page > 1) {
                state.page--;
                renderPlantTable(true);
            }
        });
    }

    if (controls.next) {
        controls.next.addEventListener('click', () => {
            if (state.page < plantPageCount()) {
                state.page++;
                renderPlantTable(true);
            }
        });
    }

    if (table) {
        table.querySelectorAll('[data-plant-sort]').forEach((header) => {
            header.addEventListener('click', () => {
                const field = header.getAttribute('data-plant-sort') || 'code';
                if (state.sortField === field) {
                    state.sortDir = state.sortDir === 'asc' ? 'desc' : 'asc';
                } else {
                    state.sortField = field;
                    state.sortDir = 'asc';
                }
                renderPlantTable(false);
            });
        });
    }

    refreshPlantRows();
    renderPlantTable(false);

    window.refreshPlantRow = refreshPlantRow;
    window.removePlantRow = removePlantRow;

    window.uploadPlantDoc_UI = function(id) {
        lastAction.type = 'uploadDoc';
        lastAction.id = id;

        const fn = window.uploadPlantDoc;
        if (typeof fn !== 'function') return;

        try {
            const ret = fn(id);
            if (ret && typeof ret.then === 'function') {
                ret.then(() => refreshPlantRow(id)).catch(() => {});
            } else {
                pollRefresh(id, null, 8, 350);
            }
        } catch (e) {}
    };

    window.deletePlantDoc_UI = function(id) {
        lastAction.type = 'deleteDoc';
        lastAction.id = id;

        const fn = window.deletePlantDoc;
        if (typeof fn === 'function') {
            try {
                fn(id);
            } catch (e) {}
        }
    };

    window.editPlant_UI = function(id) {
        lastAction.type = 'edit';
        lastAction.id = id;

        const fn = window.edit;
        if (typeof fn === 'function') fn(String(id));
    };

    document.addEventListener('hidden.mdb.modal', function() {
        const id = lastAction.id;
        if (!id) return;

        if (lastAction.type === 'deleteDoc') {
            pollRefresh(id, (html) => html.includes('plantDocInput_' + String(id)), 12, 450);
            return;
        }

        if (lastAction.type === 'edit') {
            pollRefresh(id, null, 8, 450);
            return;
        }

        if (lastAction.type === 'uploadDoc') {
            pollRefresh(id, null, 6, 350);
            return;
        }

        if (lastAction.type === 'remove') {
            pollRemove(id, 12, 450);
        }
    });

    initTooltips(document);
})();

function removePlant(table, id) {
    const htmlEscape = (value) => String(value ?? '').replace(/[&<>"']/g, (ch) => ({
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#039;'
    }[ch]));

    const replacementOptionsHtml = (options) => {
        return (Array.isArray(options) ? options : []).map((option) => {
            const code = String(option.code || '').trim();
            if (!code) return '';

            const description = String(option.description || '').trim();
            const frequency = String(option.frequency || '').trim();
            const label = code + (description ? ' - ' + description : '') + (frequency ? ' (' + frequency + ' months)' : '');
            return '<option value="' + htmlEscape(code) + '">' + htmlEscape(label) + '</option>';
        }).join('');
    };

    const affectedItemsTable = (items, oldCode, plantOptions) => {
        const optionsHtml = replacementOptionsHtml(plantOptions);
        const rows = (Array.isArray(items) ? items : []).map((item) =>
            '<tr>' +
            '<td>' + htmlEscape(item.itemnumber) + '</td>' +
            '<td>' + htmlEscape(item.clientname) + '</td>' +
            '<td>' + htmlEscape(oldCode) + '</td>' +
            '<td>' + htmlEscape(item.description) + '</td>' +
            '<td>' + htmlEscape(item.plantnumber) + '</td>' +
            '<td>' + htmlEscape(item.serialnumber) + '</td>' +
            '<td style="min-width:260px;">' +
            '<select class="form-select form-select-sm plant-reassign-select" data-itemnumber="' + htmlEscape(item.itemnumber) + '">' +
            '<option value="">Select replacement</option>' +
            optionsHtml +
            '</select>' +
            '</td>' +
            '</tr>'
        ).join('');

        return '<div class="table-responsive" style="max-height:320px; overflow:auto;">' +
            '<table class="table table-sm table-striped mb-0">' +
            '<thead><tr><th>Item</th><th>Client</th><th>Existing Code</th><th>Description</th><th>Plant No.</th><th>Serial No.</th><th>New Code</th></tr></thead>' +
            '<tbody>' + rows + '</tbody>' +
            '</table>' +
            '</div>';
    };

    const bindReassignRemoval = (plantId, items) => {
        const modal = document.getElementById('confirmBox');
        if (!modal) return;

        const selects = Array.from(modal.querySelectorAll('.plant-reassign-select'));
        const btn = modal.querySelector('#plantReassignRemoveBtn');
        if (!btn) return;

        const syncButton = () => {
            btn.disabled = selects.length < 1 || selects.some((select) => String(select.value || '').trim() === '');
        };

        selects.forEach((select) => select.addEventListener('change', syncButton));
        syncButton();

        btn.addEventListener('click', () => {
            const assignments = selects.map((select) => ({
                itemnumber: Number(select.getAttribute('data-itemnumber') || 0),
                code: String(select.value || '').trim()
            }));

            btn.disabled = true;
            btn.innerHTML = '<i class="fad fa-spinner-third fa-spin me-1"></i>Updating';

            fetch(ROOT_URL + '/includes/jump/jump_plant_check.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                },
                body: new URLSearchParams({
                    action: 'reassignItemsAndRemovePlant',
                    id: String(plantId),
                    assignments: JSON.stringify(assignments),
                    tenant: String(TENANT_URL)
                })
            })
                .then((r) => r.json().catch(() => null).then((data) => ({ ok: r.ok, data })))
                .then(({ ok, data }) => {
                    if (!ok || !data || data.status !== 'success') {
                        const msg = data && data.message ? data.message : 'Unable to update affected items.';
                        if (typeof showResponse === 'function') showResponse('danger', msg);
                        btn.innerHTML = '<i class="fad fa-trash me-1"></i>Update Items & Remove Plant';
                        syncButton();
                        return;
                    }

                    window.jumpPlantLastAction.type = 'remove';
                    window.jumpPlantLastAction.id = plantId;
                    if (typeof showResponse === 'function') showResponse('success', data.message || 'PLANT ENTRY REMOVED');
                    if (typeof killModal === 'function') killModal('confirmBox');
                    if (typeof window.removePlantRow === 'function') window.removePlantRow(plantId);
                })
                .catch(() => {
                    if (typeof showResponse === 'function') showResponse('danger', 'Unable to update affected items.');
                    btn.innerHTML = '<i class="fad fa-trash me-1"></i>Update Items & Remove Plant';
                    syncButton();
                });
        });
    };

    const url = ROOT_URL + '/includes/jump/jump_plant_check.php';
    const body = new URLSearchParams({
        action: 'plantUsage',
        id: String(id),
        tenant: String(TENANT_URL)
    });

    fetch(url, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            body
        })
        .then((r) => r.json())
        .then((j) => {
            if (!j || j.status !== 'success') {
                if (typeof showResponse === 'function') showResponse('danger', 'UNABLE TO CHECK PLANT USAGE');
                return;
            }

            const code = j.code ? String(j.code) : '';
            const count = Number(j.count || 0);

            if (count > 0) {
                const dest =
                    '<div class="note note-danger text-center">' +
                    '<strong>' + count + '</strong> active item(s) are currently set to plant code <strong>' +
                    htmlEscape(code) + '</strong>.' +
                    '<br><small>Select a replacement plant code for every item before removing this entry.</small>' +
                    '</div>' +
                    affectedItemsTable(j.items || [], code, j.plant_options || []) +
                    '<div class="text-end mt-3">' +
                    '<button type="button" id="plantReassignRemoveBtn" class="btn btn-danger" disabled>' +
                    '<i class="fad fa-trash me-1"></i>Update Items & Remove Plant' +
                    '</button>' +
                    '</div>';

                loadModalContent(dest, 'confirmBox', 'modal-xxl', 1060, 'true', 'Plant In Use');
                setTimeout(() => bindReassignRemoval(id, j.items || []), 0);
                return;
            }

            const dest = '<p class="text-center">Sure you wish to remove this entry?</p>';

            loadModalContent(dest, 'confirmBox', 'modal-md', 1060, 'true', 'Confirm Removal', 'cancelConfirm',
        () => {
                window.jumpPlantLastAction.type = 'remove';
                window.jumpPlantLastAction.id = id;
                delItem(table, id);
            });
        })
        .catch(() => {
            if (typeof showResponse === 'function') showResponse('danger', 'UNABLE TO CHECK PLANT USAGE');
        });
}

document.addEventListener('DOMContentLoaded', () => {
    var nav = document.getElementById('navBox');
    var navBtn = document.querySelectorAll('.navBtn');
    var activeBtn = document.getElementById('plantBtn');

    if (nav) {
        nav.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">Jump List Management</li><li class="breadcrumb-item"><i class="fad fa-angle-double-right mx-2 mt-1" aria-hidden="true"></i></li><li class="breadcrumb-item active">Plant List</li>';
    }

    navBtn.forEach(btn => btn.classList.remove('active'));
    if (activeBtn) activeBtn.classList.add('active');
});



function plantColourOptionsHtml(selectedColour) {
    const colours = {
        rose: {
            bg: '#fce4ec',
            text: '#6a1b3a',
            label: 'Rose'
        },
        red: {
            bg: '#fdecea',
            text: '#7f1d1d',
            label: 'Red'
        },
        orange: {
            bg: '#fff3e0',
            text: '#8a3b12',
            label: 'Orange'
        },
        amber: {
            bg: '#fff8e1',
            text: '#7a5600',
            label: 'Amber'
        },
        yellow: {
            bg: '#fffde7',
            text: '#6b5b00',
            label: 'Yellow'
        },
        lime: {
            bg: '#f1f8e9',
            text: '#466a12',
            label: 'Lime'
        },
        green: {
            bg: '#e8f5e9',
            text: '#1b5e20',
            label: 'Green'
        },
        mint: {
            bg: '#e6f7f1',
            text: '#0f5c4d',
            label: 'Mint'
        },
        cyan: {
            bg: '#e0f7fa',
            text: '#155e75',
            label: 'Cyan'
        },
        blue: {
            bg: '#e3f2fd',
            text: '#0d47a1',
            label: 'Blue'
        },
        indigo: {
            bg: '#e8eaf6',
            text: '#283593',
            label: 'Indigo'
        },
        purple: {
            bg: '#f3e5f5',
            text: '#6a1b9a',
            label: 'Purple'
        }
    };

    let html = '<input type="hidden" id="quick_row_colour" value="' + (selectedColour || '') + '">';
    html += '<div class="row g-2">';

    Object.keys(colours).forEach((key) => {
        const cfg = colours[key];
        const active = key === selectedColour ? ' border border-dark border-3' : '';
        html += `
            <div class="col-6 col-md-4">
                <button type="button"
                        class="btn w-100 text-start quick-colour-btn${active}"
                        data-colour="${key}"
                        style="background:${cfg.bg}; color:${cfg.text};">
                    <i class="fad fa-square-full me-2"></i>${cfg.label}
                </button>
            </div>
        `;
    });

    html += `
        <div class="col-12 mt-2">
            <button type="button" class="btn btn-secondary btn-sm" id="clearQuickPlantColour"
                    data-mdb-tooltip-init data-mdb-placement="top" data-mdb-trigger="hover" title="Clear row colour">
                <i class="fad fa-eraser me-1"></i>Clear colour
            </button>
        </div>
    `;

    html += '</div>';
    return html;
}

function initQuickPlantColourEvents() {
    const hidden = document.getElementById('quick_row_colour');
    if (!hidden) {
        return;
    }

    document.querySelectorAll('.quick-colour-btn').forEach((btn) => {
        btn.addEventListener('click', function() {
            hidden.value = this.getAttribute('data-colour') || '';

            document.querySelectorAll('.quick-colour-btn').forEach((b) => {
                b.classList.remove('border', 'border-dark', 'border-3');
            });

            this.classList.add('border', 'border-dark', 'border-3');
        });
    });

    const clearBtn = document.getElementById('clearQuickPlantColour');
    if (clearBtn) {
        clearBtn.addEventListener('click', function() {
            hidden.value = '';
            document.querySelectorAll('.quick-colour-btn').forEach((b) => {
                b.classList.remove('border', 'border-dark', 'border-3');
            });
        });
    }

    if (typeof mdb !== 'undefined') {
        document.querySelectorAll('[data-mdb-tooltip-init]').forEach((el) => {
            try {
                new mdb.Tooltip(el);
            } catch (e) {}
        });
    }
}

function openPlantColourModal(id, currentColour) {
    const html = plantColourOptionsHtml(currentColour);

    loadModalContent(
        html,
        'popupBox',
        'modal-md',
        1060,
        'true',
        'Set Plant Row Colour',
        'cancelConfirm',
        () => savePlantRowColourQuick(id)
    );

    setTimeout(() => {
        initQuickPlantColourEvents();
    }, 100);
}

function savePlantRowColourQuick(id) {
    const colourEl = document.getElementById('quick_row_colour');
    const rowColour = colourEl ? colourEl.value : '';

    const xhr = new XMLHttpRequest();
    xhr.open('POST', ROOT_URL + '/includes/jump/jump_functions.php', true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
            const data = (xhr.responseText || '').trim();

            if (xhr.status === 200 && data === 's') {
                showResponse('success', 'ROW COLOUR UPDATED');
                refreshPlantColourCell(id, rowColour);
                killModal('popupBox');
            } else {
                showResponse('danger', 'UNABLE TO UPDATE ROW COLOUR');
            }
        }
    };

    xhr.send(
        'FUNCTION=setPlantRowColour' +
        '&id=' + encodeURIComponent(id) +
        '&row_colour=' + encodeURIComponent(rowColour) +
        '&tenant=' + encodeURIComponent(TENANT_URL)
    );
}

function refreshPlantColourCell(id, rowColour) {
    const row = document.querySelector('tr[data-plant-id="' + id + '"]');
    if (!row) {
        return;
    }

    const cell = row.querySelector('td:nth-child(6)');
    if (!cell) {
        return;
    }

    const badges = {
        rose: {
            bg: '#fce4ec',
            text: '#6a1b3a',
            label: 'Rose'
        },
        red: {
            bg: '#fdecea',
            text: '#7f1d1d',
            label: 'Red'
        },
        orange: {
            bg: '#fff3e0',
            text: '#8a3b12',
            label: 'Orange'
        },
        amber: {
            bg: '#fff8e1',
            text: '#7a5600',
            label: 'Amber'
        },
        yellow: {
            bg: '#fffde7',
            text: '#6b5b00',
            label: 'Yellow'
        },
        lime: {
            bg: '#f1f8e9',
            text: '#466a12',
            label: 'Lime'
        },
        green: {
            bg: '#e8f5e9',
            text: '#1b5e20',
            label: 'Green'
        },
        mint: {
            bg: '#e6f7f1',
            text: '#0f5c4d',
            label: 'Mint'
        },
        cyan: {
            bg: '#e0f7fa',
            text: '#155e75',
            label: 'Cyan'
        },
        blue: {
            bg: '#e3f2fd',
            text: '#0d47a1',
            label: 'Blue'
        },
        indigo: {
            bg: '#e8eaf6',
            text: '#283593',
            label: 'Indigo'
        },
        purple: {
            bg: '#f3e5f5',
            text: '#6a1b9a',
            label: 'Purple'
        }
    };

    let badgeHtml = '<span class="badge rounded-pill bg-light text-dark border">None</span>';

    if (rowColour && badges[rowColour]) {
        const cfg = badges[rowColour];
        badgeHtml = '<span class="badge rounded-pill border" style="background:' + cfg.bg + '; color:' + cfg.text +
            ';">' +
            '<i class="fad fa-palette me-1"></i>' + cfg.label + '</span>';
    }

    cell.innerHTML = `
        <button type="button"
                class="btn btn-link btn-sm p-0 text-decoration-none"
                onclick="openPlantColourModal(${id},'${rowColour}')"
                data-mdb-tooltip-init data-mdb-placement="top" data-mdb-trigger="hover" title="Set row colour">
            ${badgeHtml}
        </button>
    `;

    if (typeof mdb !== 'undefined') {
        cell.querySelectorAll('[data-mdb-tooltip-init]').forEach((el) => {
            try {
                new mdb.Tooltip(el);
            } catch (e) {}
        });
    }
}
</script>
