<?php
$project_gantt_data = isset($project_gantt_data) && is_array($project_gantt_data) ? $project_gantt_data : array();
$gantt_data = isset($project_gantt_data['milestones']) ? $project_gantt_data['milestones'] : array();
$gantt_data2 = isset($project_gantt_data['status']) ? $project_gantt_data['status'] : array();
$gantt_data3 = isset($project_gantt_data['members']) ? $project_gantt_data['members'] : array();
?>
<div class="space-y-4">
    <section class="space-y-4">
        <div class="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
            <div>
                <h3 class="text-xl font-semibold text-foreground"><?= lang('gantt') ?></h3>
                <p class="mt-1 text-sm text-muted-foreground"><?= $project_details->project_name ?> . <?= display_date($project_details->start_date) ?> - <?= display_date($project_details->end_date) ?></p>
            </div>
            <div class="flex flex-col gap-3 md:flex-row md:items-center">
                <details class="relative gantt-select">
                    <summary class="flex min-w-[180px] list-none cursor-pointer items-center justify-between rounded-xl border border-border bg-card px-4 py-3 text-sm font-medium text-foreground shadow-sm">
                        <span data-gantt-filter-label><?= lang('all') ?></span>
                        <i data-lucide="chevron-down" class="h-4 w-4 text-muted-foreground"></i>
                    </summary>
                    <div class="absolute right-0 z-30 mt-3 w-full overflow-hidden rounded-2xl border border-border bg-card shadow-xl">
                        <button type="button" class="gantt-filter-option flex w-full items-center px-4 py-3 text-left text-sm font-medium text-foreground hover:bg-muted/60" data-filter="all"><?= lang('all') ?></button>
                    </div>
                </details>

                <details class="relative gantt-select">
                    <summary class="flex min-w-[200px] list-none cursor-pointer items-center justify-between rounded-xl border border-border bg-card px-4 py-3 text-sm font-medium text-foreground shadow-sm">
                        <span data-gantt-group-label><?= lang('milestones') ?></span>
                        <i data-lucide="chevron-down" class="h-4 w-4 text-muted-foreground"></i>
                    </summary>
                    <div class="absolute right-0 z-30 mt-3 w-full overflow-hidden rounded-2xl border border-border bg-card shadow-xl">
                        <button type="button" class="gantt-group-option flex w-full items-center px-4 py-3 text-left text-sm font-medium text-foreground hover:bg-muted/60 resize-gantt" data-mode="milestones"><?= lang('milestones') ?></button>
                        <?php if (!empty($gantt_data3)) : ?>
                            <button type="button" class="gantt-group-option flex w-full items-center px-4 py-3 text-left text-sm font-medium text-foreground hover:bg-muted/60 user-gantt" data-mode="members"><?= lang('project_members') ?></button>
                        <?php endif; ?>
                        <button type="button" class="gantt-group-option flex w-full items-center px-4 py-3 text-left text-sm font-medium text-foreground hover:bg-muted/60 status-gantt" data-mode="status"><?= lang('status') ?></button>
                    </div>
                </details>

                <details class="relative gantt-select">
                    <summary class="flex min-w-[220px] list-none cursor-pointer items-center justify-between rounded-xl border border-primary bg-card px-4 py-3 text-sm font-medium text-foreground shadow-sm ring-2 ring-primary/15">
                        <span data-gantt-scale-label><?= lang('months_view') ?></span>
                        <i data-lucide="chevron-down" class="h-4 w-4 text-muted-foreground"></i>
                    </summary>
                    <div class="absolute right-0 z-30 mt-3 w-full overflow-hidden rounded-2xl border border-border bg-card shadow-xl">
                        <button type="button" class="gantt-scale-option flex w-full items-center px-4 py-3 text-left text-sm font-medium text-foreground hover:bg-muted/60" data-scale="days"><?= lang('days_view') ?></button>
                        <button type="button" class="gantt-scale-option flex w-full items-center px-4 py-3 text-left text-sm font-medium text-foreground hover:bg-muted/60" data-scale="weeks"><?= lang('weeks_view') ?></button>
                        <button type="button" class="gantt-scale-option flex w-full items-center bg-muted/50 px-4 py-3 text-left text-sm font-semibold text-foreground" data-scale="months"><?= lang('months_view') ?></button>
                        <button type="button" class="gantt-scale-option flex w-full items-center px-4 py-3 text-left text-sm font-medium text-foreground hover:bg-muted/60" data-scale="years"><?= lang('years_view') ?></button>
                    </div>
                </details>
            </div>
        </div>

        <div class="overflow-hidden rounded-2xl border border-border bg-card shadow-sm">
            <div id="gantt-shell" class="overflow-x-auto bg-card">
                <div class="gantt min-w-[1200px] p-6"></div>
            </div>
        </div>
    </section>
</div>

<div id="gantData">
    <script type="text/javascript">
        var currentScale = "months";

        function parseDate(value) {
            if (!value) {
                return null;
            }
            var parts = String(value).split('-');
            if (parts.length < 3) {
                return null;
            }
            return new Date(Number(parts[0]), Number(parts[1]) - 1, Number(parts[2]));
        }

        function updateGanttLabel(selector, text) {
            var label = document.querySelector(selector);
            if (label) {
                label.textContent = text;
            }
        }

        function startOfWeek(date) {
            var d = new Date(date.getFullYear(), date.getMonth(), date.getDate());
            var day = d.getDay();
            var diff = d.getDate() - day + (day === 0 ? -6 : 1);
            d.setDate(diff);
            d.setHours(0, 0, 0, 0);
            return d;
        }

        function endOfWeek(date) {
            var d = startOfWeek(date);
            d.setDate(d.getDate() + 6);
            return d;
        }

        function startOfMonth(date) {
            return new Date(date.getFullYear(), date.getMonth(), 1);
        }

        function endOfMonth(date) {
            return new Date(date.getFullYear(), date.getMonth() + 1, 0);
        }

        function startOfYear(date) {
            return new Date(date.getFullYear(), 0, 1);
        }

        function endOfYear(date) {
            return new Date(date.getFullYear(), 11, 31);
        }

        function addUnit(date, scale) {
            var d = new Date(date.getTime());
            if (scale === 'days') {
                d.setDate(d.getDate() + 1);
            } else if (scale === 'weeks') {
                d.setDate(d.getDate() + 7);
            } else if (scale === 'years') {
                d.setFullYear(d.getFullYear() + 1);
            } else {
                d.setMonth(d.getMonth() + 1);
            }
            return d;
        }

        function formatUnitLabel(date, scale) {
            if (scale === 'days') {
                return new Intl.DateTimeFormat(undefined, { month: 'short', day: 'numeric' }).format(date);
            }
            if (scale === 'weeks') {
                return 'W' + getWeekNumber(date);
            }
            if (scale === 'years') {
                return String(date.getFullYear());
            }
            return new Intl.DateTimeFormat(undefined, { month: 'long' }).format(date);
        }

        function formatGroupLabel(date, scale) {
            if (scale === 'days' || scale === 'weeks' || scale === 'months') {
                return String(date.getFullYear());
            }
            return '';
        }

        function getWeekNumber(date) {
            var d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
            var dayNum = d.getUTCDay() || 7;
            d.setUTCDate(d.getUTCDate() + 4 - dayNum);
            var yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
            return Math.ceil((((d - yearStart) / 86400000) + 1) / 7);
        }

        function getScaleStart(date, scale) {
            if (scale === 'days') {
                return new Date(date.getFullYear(), date.getMonth(), date.getDate());
            }
            if (scale === 'weeks') {
                return startOfWeek(date);
            }
            if (scale === 'years') {
                return startOfYear(date);
            }
            return startOfMonth(date);
        }

        function getScaleEnd(date, scale) {
            if (scale === 'days') {
                return new Date(date.getFullYear(), date.getMonth(), date.getDate());
            }
            if (scale === 'weeks') {
                return endOfWeek(date);
            }
            if (scale === 'years') {
                return endOfYear(date);
            }
            return endOfMonth(date);
        }

        function getCellWidth(scale) {
            if (scale === 'days') {
                return 72;
            }
            if (scale === 'weeks') {
                return 112;
            }
            if (scale === 'years') {
                return 180;
            }
            return 132;
        }

        function collectBounds(data) {
            var min = null;
            var max = null;
            data.forEach(function(group) {
                (group.values || []).forEach(function(value) {
                    var from = parseDate(value.from);
                    var to = parseDate(value.to);
                    if (from && (!min || from < min)) min = from;
                    if (to && (!max || to > max)) max = to;
                });
            });
            return { min: min, max: max };
        }

        function buildUnits(minDate, maxDate, scale) {
            var units = [];
            if (!minDate || !maxDate) {
                return units;
            }
            var cursor = getScaleStart(minDate, scale);
            var limit = getScaleEnd(maxDate, scale);
            while (cursor <= limit) {
                units.push(new Date(cursor.getTime()));
                cursor = addUnit(cursor, scale);
            }
            return units;
        }

        function computePlacement(from, to, units, scale, cellWidth) {
            var taskStart = from || units[0];
            var taskEnd = to || taskStart;
            var firstIndex = 0;
            var lastIndex = units.length - 1;
            units.forEach(function(unit, index) {
                var unitStart = getScaleStart(unit, scale);
                var unitEnd = getScaleEnd(unit, scale);
                if (taskStart >= unitStart && taskStart <= unitEnd) {
                    firstIndex = index;
                }
                if (taskEnd >= unitStart && taskEnd <= unitEnd) {
                    lastIndex = index;
                }
            });
            if (lastIndex < firstIndex) {
                lastIndex = firstIndex;
            }
            return {
                left: firstIndex * cellWidth + 8,
                width: Math.max(cellWidth - 16, ((lastIndex - firstIndex) + 1) * cellWidth - 16)
            };
        }

        function renderGanttChart(ganttData) {
            var root = document.querySelector('.gantt');
            if (!root) {
                return;
            }
            var data = Array.isArray(ganttData) ? ganttData : [];
            var bounds = collectBounds(data);
            if (!bounds.min || !bounds.max) {
                root.innerHTML = '<div class="p-6 text-sm text-muted-foreground">No timeline data available.</div>';
                return;
            }

            var units = buildUnits(bounds.min, bounds.max, currentScale);
            var cellWidth = getCellWidth(currentScale);
            var timelineWidth = Math.max(units.length * cellWidth, 720);
            var timelineMinWidth = 280;

            var headerTop = '';
            var lastGroup = null;
            var groupStartIndex = 0;
            units.forEach(function(unit, index) {
                var groupLabel = formatGroupLabel(unit, currentScale);
                if (currentScale !== 'years' && groupLabel !== lastGroup) {
                    if (lastGroup !== null) {
                        headerTop += '<div class="gantt-group-label" style="left:' + (groupStartIndex * cellWidth) + 'px;width:' + ((index - groupStartIndex) * cellWidth) + 'px">' + lastGroup + '</div>';
                    }
                    lastGroup = groupLabel;
                    groupStartIndex = index;
                }
            });
            if (currentScale !== 'years' && lastGroup !== null) {
                headerTop += '<div class="gantt-group-label" style="left:' + (groupStartIndex * cellWidth) + 'px;width:' + ((units.length - groupStartIndex) * cellWidth) + 'px">' + lastGroup + '</div>';
            }
            if (currentScale === 'years') {
                headerTop = '<div class="gantt-group-label" style="left:0;width:' + timelineWidth + 'px">' + formatUnitLabel(units[0], currentScale) + (units.length > 1 ? ' - ' + formatUnitLabel(units[units.length - 1], currentScale) : '') + '</div>';
            }

            var headerBottom = units.map(function(unit) {
                return '<div class="gantt-unit" style="width:' + cellWidth + 'px">' + formatUnitLabel(unit, currentScale) + '</div>';
            }).join('');

            var body = data.map(function(group, index) {
                var values = group.values || [];
                var line = values.map(function(value) {
                    var from = parseDate(value.from);
                    var to = parseDate(value.to);
                    var placement = computePlacement(from, to, units, currentScale, cellWidth);
                    var label = value.label || group.name || '';
                    return '<div class="gantt-bar ' + (value.customClass || '') + '" style="left:' + placement.left + 'px;width:' + placement.width + 'px">' + label + '</div>';
                }).join('');
                return '' +
                    '<div class="gantt-row">' +
                        '<div class="gantt-row-label">' + (group.name || '&nbsp;') + '</div>' +
                        '<div class="gantt-row-track" style="width:' + timelineWidth + 'px;background-size:' + cellWidth + 'px 100%">' +
                            line +
                        '</div>' +
                    '</div>';
            }).join('');

            root.innerHTML = '' +
                '<div class="gantt-board">' +
                    '<div class="gantt-head">' +
                        '<div class="gantt-head-label"></div>' +
                        '<div class="gantt-head-track" style="width:' + timelineWidth + 'px;min-width:' + timelineMinWidth + 'px">' +
                            '<div class="gantt-groups">' + headerTop + '</div>' +
                            '<div class="gantt-units">' + headerBottom + '</div>' +
                        '</div>' +
                    '</div>' +
                    '<div class="gantt-body">' + body + '</div>' +
                '</div>';
        }

        function setActiveGanttMode(mode, labelText) {
            updateGanttLabel('[data-gantt-group-label]', labelText);
            document.querySelectorAll('.gantt-select[open]').forEach(function(dropdown) {
                dropdown.removeAttribute('open');
            });
        }

        function setActiveGanttScale(scale, labelText) {
            currentScale = scale;
            updateGanttLabel('[data-gantt-scale-label]', labelText);
            document.querySelectorAll('.gantt-scale-option').forEach(function(option) {
                option.classList.remove('bg-muted/50', 'font-semibold');
                option.classList.add('font-medium', 'hover:bg-muted/60');
            });
            document.querySelectorAll('.gantt-scale-option[data-scale="' + scale + '"]').forEach(function(option) {
                option.classList.add('bg-muted/50', 'font-semibold');
                option.classList.remove('hover:bg-muted/60');
            });
            document.querySelectorAll('.gantt-select[open]').forEach(function(dropdown) {
                dropdown.removeAttribute('open');
            });
        }

        var ganttModes = {
            milestones: <?= json_encode($gantt_data) ?>,
            status: <?= json_encode($gantt_data2) ?>,
            members: <?= json_encode($gantt_data3) ?>
        };
        var ganttData = ganttModes.milestones;
        renderGanttChart(ganttData);
        setActiveGanttMode('milestones', '<?= lang('milestones') ?>');
        setActiveGanttScale('months', '<?= lang('months_view') ?>');

        $(document).on("click", '.resize-gantt', function(e) {
            e.preventDefault();
            ganttData = ganttModes.milestones;
            renderGanttChart(ganttData);
            setActiveGanttMode('milestones', $(this).text().trim());
        });
        $(document).on("click", '.status-gantt', function(e) {
            e.preventDefault();
            ganttData = ganttModes.status;
            renderGanttChart(ganttData);
            setActiveGanttMode('status', $(this).text().trim());
        });
        <?php if (!empty($gantt_data3)) { ?>
        $(document).on("click", '.user-gantt', function(e) {
            e.preventDefault();
            ganttData = ganttModes.members;
            renderGanttChart(ganttData);
            setActiveGanttMode('members', $(this).text().trim());
        });
        <?php } ?>
        $(document).on("click", '.gantt-scale-option', function(e) {
            e.preventDefault();
            setActiveGanttScale($(this).data('scale'), $(this).text().trim());
            renderGanttChart(ganttData);
        });
        $(document).on("click", '.gantt-filter-option', function(e) {
            e.preventDefault();
            updateGanttLabel('[data-gantt-filter-label]', $(this).text().trim());
            document.querySelectorAll('.gantt-select[open]').forEach(function(dropdown) {
                dropdown.removeAttribute('open');
            });
            renderGanttChart(ganttData);
        });
    </script>
</div>

<style>
    .gantt-select summary::-webkit-details-marker {
        display: none;
    }

    #gantt-shell .gantt {
        background: transparent;
    }

    #gantt-shell .gantt-board {
        min-width: 1200px;
        font-family: inherit;
    }

    #gantt-shell .gantt-head,
    #gantt-shell .gantt-row {
        display: grid;
        grid-template-columns: 280px minmax(720px, 1fr);
    }

    #gantt-shell .gantt-head {
        border-bottom: 1px solid rgba(148, 163, 184, 0.22);
    }

    #gantt-shell .gantt-head-label {
        border-right: 1px solid rgba(148, 163, 184, 0.22);
        background: rgba(255, 255, 255, 0.92);
    }

    #gantt-shell .gantt-head-track {
        position: relative;
        overflow: hidden;
        background: rgba(255, 255, 255, 0.92);
    }

    #gantt-shell .gantt-groups {
        position: relative;
        height: 52px;
        border-bottom: 1px solid rgba(148, 163, 184, 0.22);
    }

    #gantt-shell .gantt-group-label {
        position: absolute;
        top: 14px;
        text-align: center;
        font-size: 14px;
        font-weight: 700;
        color: rgb(51 65 85);
    }

    #gantt-shell .gantt-units {
        display: flex;
    }

    #gantt-shell .gantt-unit {
        flex: 0 0 auto;
        padding: 12px 10px;
        text-align: center;
        font-size: 12px;
        font-weight: 700;
        color: rgb(71 85 105);
        border-right: 1px solid rgba(148, 163, 184, 0.14);
    }

    #gantt-shell .gantt-row-label {
        padding: 14px 16px;
        border-right: 1px solid rgba(148, 163, 184, 0.22);
        border-bottom: 1px solid rgba(148, 163, 184, 0.14);
        font-size: 14px;
        font-weight: 600;
        color: rgb(51 65 85);
        background: rgba(255, 255, 255, 0.92);
    }

    #gantt-shell .gantt-row:nth-child(even) .gantt-row-label,
    #gantt-shell .gantt-row:nth-child(even) .gantt-row-track {
        background-color: rgba(148, 163, 184, 0.10);
    }

    #gantt-shell .gantt-row:nth-child(odd) .gantt-row-label,
    #gantt-shell .gantt-row:nth-child(odd) .gantt-row-track {
        background-color: rgba(255, 255, 255, 0.92);
    }

    #gantt-shell .gantt-row-track {
        position: relative;
        min-height: 52px;
        border-bottom: 1px solid rgba(148, 163, 184, 0.14);
        background-image: linear-gradient(to right, rgba(148, 163, 184, 0.18) 1px, transparent 1px);
        background-repeat: repeat-x;
    }

    #gantt-shell .gantt-bar {
        position: absolute;
        top: 12px;
        height: 28px;
        border-radius: 6px;
        display: flex;
        align-items: center;
        padding: 0 10px;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        font-size: 12px;
        font-weight: 600;
        color: #fff;
        box-shadow: 0 8px 18px rgba(15, 23, 42, 0.12);
    }

    #gantt-shell .gantt-headerline,
    #gantt-shell .ganttGrey,
    #gantt-shell .gantt_not_started,
    #gantt-shell .gantt-timeline {
        background: #4b5563;
    }

    #gantt-shell .ganttin_progress {
        background: #22c55e;
    }

    #gantt-shell .gantt_deferred {
        background: #ef4444;
    }

    .dark #gantt-shell .gantt-head-label,
    .dark #gantt-shell .gantt-head-track,
    .dark #gantt-shell .gantt-row:nth-child(odd) .gantt-row-label,
    .dark #gantt-shell .gantt-row:nth-child(odd) .gantt-row-track {
        background-color: rgba(30, 41, 59, 0.88);
    }

    .dark #gantt-shell .gantt-row:nth-child(even) .gantt-row-label,
    .dark #gantt-shell .gantt-row:nth-child(even) .gantt-row-track {
        background-color: rgba(51, 65, 85, 0.55);
    }

    .dark #gantt-shell .gantt-group-label,
    .dark #gantt-shell .gantt-row-label {
        color: rgb(226 232 240);
    }

    .dark #gantt-shell .gantt-unit {
        color: rgb(148 163 184);
    }
</style>
