'use client';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useMemo, useCallback, useRef, useState } from 'react';
import { ChevronLeft, ChevronRight } from 'lucide-react';
import { cn } from '../../../lib/utils.js';
import { Button } from '../../ui/button.js';
import { GanttBar } from './gantt-bar.js';
const DAY_MS = 86400000;
const WEEKS_VISIBLE = 6;
const DAYS_VISIBLE = WEEKS_VISIBLE * 7;
const STATE_GROUP_COLORS = {
    Backlog: '#a3a3a3',
    Unstarted: '#60a5fa',
    Started: '#fbbf24',
    Completed: '#34d399',
    Cancelled: '#ef4444',
};
function getMonday(d) {
    const day = d.getDay();
    const diff = d.getDate() - day + (day === 0 ? -6 : 1);
    return new Date(d.getFullYear(), d.getMonth(), diff);
}
function formatDate(d) {
    return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
}
function addDays(d, n) {
    return new Date(d.getTime() + n * DAY_MS);
}
export function TimelineView({ workItems, states, relations, projectPrefix, onItemClick, className, }) {
    const containerRef = useRef(null);
    const [weekOffset, setWeekOffset] = useState(0);
    const stateMap = useMemo(() => new Map(states.map((s) => [s.id, s])), [states]);
    const viewStart = useMemo(() => {
        const today = getMonday(new Date());
        return addDays(today, weekOffset * 7);
    }, [weekOffset]);
    const viewEnd = useMemo(() => addDays(viewStart, DAYS_VISIBLE), [viewStart]);
    const weeks = useMemo(() => {
        const result = [];
        for (let i = 0; i < WEEKS_VISIBLE; i++) {
            const weekStart = addDays(viewStart, i * 7);
            result.push({ start: weekStart, label: formatDate(weekStart) });
        }
        return result;
    }, [viewStart]);
    const itemsWithDates = useMemo(() => workItems.filter((wi) => wi.startDate &&
        wi.dueDate &&
        new Date(wi.dueDate) >= viewStart &&
        new Date(wi.startDate) <= viewEnd), [workItems, viewStart, viewEnd]);
    const blockingRelations = useMemo(() => relations.filter((r) => r.relationType === 'Blocking'), [relations]);
    const getBarPosition = useCallback((item) => {
        if (!item.startDate || !item.dueDate)
            return null;
        const start = new Date(item.startDate);
        const end = new Date(item.dueDate);
        const viewStartMs = viewStart.getTime();
        const totalMs = DAYS_VISIBLE * DAY_MS;
        const startOffset = Math.max(0, ((start.getTime() - viewStartMs) / totalMs) * 100);
        const endOffset = Math.min(100, ((end.getTime() - viewStartMs) / totalMs) * 100);
        const width = endOffset - startOffset;
        return { startOffset, widthPercent: width };
    }, [viewStart]);
    const itemIdSet = useMemo(() => new Set(itemsWithDates.map((wi) => wi.id)), [itemsWithDates]);
    const visibleBlockingLines = useMemo(() => blockingRelations.filter((r) => itemIdSet.has(r.sourceWorkItemId) && itemIdSet.has(r.targetWorkItemId)), [blockingRelations, itemIdSet]);
    const handlePrev = useCallback(() => setWeekOffset((o) => o - 2), []);
    const handleNext = useCallback(() => setWeekOffset((o) => o + 2), []);
    const handleToday = useCallback(() => setWeekOffset(0), []);
    if (workItems.length === 0) {
        return (_jsx("div", { "data-testid": "timeline-view-empty", className: "text-muted-foreground flex flex-col items-center justify-center py-12 text-center", children: _jsx("p", { className: "text-xs", children: "No work items to display on the timeline." }) }));
    }
    return (_jsxs("div", { "data-testid": "timeline-view", className: cn('space-y-2', className), children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-1", children: [_jsx(Button, { variant: "ghost", size: "sm", className: "h-6 px-2 text-[10px]", onClick: handlePrev, children: _jsx(ChevronLeft, { className: "h-3 w-3" }) }), _jsx(Button, { variant: "outline", size: "sm", className: "h-6 px-2 text-[10px]", onClick: handleToday, children: "Today" }), _jsx(Button, { variant: "ghost", size: "sm", className: "h-6 px-2 text-[10px]", onClick: handleNext, children: _jsx(ChevronRight, { className: "h-3 w-3" }) })] }), _jsxs("span", { className: "text-muted-foreground text-[10px]", children: [formatDate(viewStart), " \u2013 ", formatDate(addDays(viewEnd, -1))] })] }), _jsx("div", { ref: containerRef, className: "overflow-x-auto rounded-lg border", children: _jsxs("div", { className: "min-w-[800px]", children: [_jsxs("div", { className: "bg-muted/50 flex border-b", children: [_jsx("div", { className: "w-[180px] shrink-0 border-r px-2 py-1", children: _jsx("span", { className: "text-[10px] font-medium", children: "Work Item" }) }), _jsx("div", { className: "flex flex-1", children: weeks.map((week) => (_jsx("div", { className: "flex-1 border-r px-2 py-1 text-center last:border-r-0", children: _jsx("span", { className: "text-muted-foreground text-[10px]", children: week.label }) }, week.label))) })] }), itemsWithDates.map((item) => {
                            const pos = getBarPosition(item);
                            const state = stateMap.get(item.stateId);
                            const color = STATE_GROUP_COLORS[state?.stateGroup ?? 'Backlog'] ?? '#a3a3a3';
                            const identifier = `${projectPrefix}-${item.sequenceId}`;
                            return (_jsxs("div", { className: "flex border-b last:border-b-0", children: [_jsx("div", { className: "w-[180px] shrink-0 border-r px-2 py-1", children: _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("span", { className: "text-muted-foreground text-[10px]", children: identifier }), _jsx("span", { className: "max-w-[120px] truncate text-[10px]", children: item.title })] }) }), _jsxs("div", { className: "relative flex-1", style: { height: 32 }, children: [weeks.map((week, weekIdx) => (_jsx("div", { className: "border-r-border/30 absolute top-0 h-full border-r", style: { left: `${((weekIdx + 1) / WEEKS_VISIBLE) * 100}%` } }, week.label))), pos ? (_jsx(GanttBar, { title: item.title, identifier: identifier, startOffset: pos.startOffset, widthPercent: pos.widthPercent, color: color, onClick: () => onItemClick?.(item) })) : null] })] }, item.id));
                        }), visibleBlockingLines.length > 0 && (_jsx("div", { className: "bg-muted/30 border-t px-3 py-1.5", children: _jsxs("span", { className: "text-muted-foreground text-[10px]", children: [visibleBlockingLines.length, " blocking", ' ', visibleBlockingLines.length === 1 ? 'dependency' : 'dependencies', " visible"] }) }))] }) })] }));
}
