import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useEffect, useRef, useState } from "react";
import { ChevronDown, Folder, GitBranch } from "lucide-react";
import { Select } from "../../components/ui/select";
import { Tooltip, TooltipContent, TooltipTrigger, } from "../../components/ui/tooltip";
import { ProjectPropertiesPanel } from "./ProjectPropertiesPanel";
const EMPTY_COUNTS = {
    total: 0,
    todo: 0,
    waiting: 0,
    inProgress: 0,
    review: 0,
    done: 0,
};
const DEFAULT_COST_LIMIT = 25;
const STATE_STOPS = [
    {
        key: "todo",
        label: "Todo",
        segmentClassName: "bg-neutral-grey-10",
        ringColor: "var(--color-neutral-grey-10)",
        swatchClassName: "bg-neutral-grey-10",
    },
    {
        key: "waiting",
        label: "Waiting",
        segmentClassName: "bg-feedback-orange",
        ringColor: "var(--color-feedback-orange-light)",
        swatchClassName: "bg-feedback-orange",
    },
    {
        key: "inProgress",
        label: "In progress",
        segmentClassName: "bg-feedback-blue",
        ringColor: "var(--color-component-default)",
        swatchClassName: "bg-feedback-blue",
    },
    {
        key: "review",
        label: "Review",
        segmentClassName: "bg-highlight-100",
        ringColor: "var(--color-component-layout)",
        swatchClassName: "bg-highlight-100",
    },
    {
        key: "done",
        label: "Done",
        segmentClassName: "bg-feedback-green",
        ringColor: "var(--color-feedback-green)",
        swatchClassName: "bg-feedback-green",
    },
];
export function TaskStateProgressBar(props) {
    const { counts, compact = false } = props;
    const total = counts.total;
    return (_jsx("div", { className: `${compact ? "h-1.5" : "h-2"} bg-neutral-grey-5 w-full overflow-hidden rounded-full`, children: total > 0 ? (_jsx("div", { className: "flex h-full w-full", children: STATE_STOPS.map((stop) => {
                const value = counts[stop.key];
                const widthPct = (value / total) * 100;
                return (_jsx("div", { className: stop.segmentClassName, style: { width: `${widthPct}%` }, title: `${stop.label}: ${value}` }, stop.key));
            }) })) : null }));
}
export function CostProgressRing(props) {
    const { used, limit, size = 44, strokeWidth = 4 } = props;
    const radius = (size - strokeWidth) / 2;
    const circumference = 2 * Math.PI * radius;
    const pct = limit > 0 ? Math.max(0, Math.min((used / limit) * 100, 100)) : 0;
    const dashOffset = circumference - (pct / 100) * circumference;
    const stroke = pct >= 100
        ? "var(--color-feedback-red)"
        : pct >= 80
            ? "var(--color-feedback-orange)"
            : "var(--color-feedback-green)";
    const center = size / 2;
    const formatAmount = (value) => value >= 1000
        ? `${(value / 1000).toFixed(value >= 10000 ? 0 : 1)}k`
        : value.toFixed(value >= 100 ? 0 : 0);
    return (_jsxs("div", { className: "relative", style: { width: size, height: size }, children: [_jsxs("svg", { width: size, height: size, viewBox: `0 0 ${size} ${size}`, className: "-rotate-90", "aria-hidden": true, children: [_jsx("circle", { cx: center, cy: center, r: radius, stroke: "var(--color-neutral-grey-10)", strokeWidth: strokeWidth, fill: "none" }), _jsx("circle", { cx: center, cy: center, r: radius, stroke: stroke, strokeWidth: strokeWidth, fill: "none", strokeLinecap: "round", strokeDasharray: circumference, strokeDashoffset: dashOffset, style: { transition: "stroke-dashoffset 200ms ease-out" } })] }), _jsxs("div", { className: "text-neutral-grey-100 pointer-events-none absolute inset-0 flex flex-col items-center justify-center text-[10px] leading-none font-semibold", children: [_jsxs("span", { children: ["$", formatAmount(used)] }), _jsxs("span", { className: "text-neutral-grey-50 text-[8px] font-normal", children: ["of $", formatAmount(limit)] })] })] }));
}
export function TaskStateProgressRing(props) {
    const { counts, size = 44, strokeWidth = 4 } = props;
    const radius = (size - strokeWidth) / 2;
    const circumference = 2 * Math.PI * radius;
    const center = size / 2;
    const total = counts.total;
    let cumulative = 0;
    const segments = total
        ? STATE_STOPS.map((stop) => {
            const value = counts[stop.key];
            if (value <= 0)
                return null;
            const fraction = value / total;
            const dashLength = fraction * circumference;
            const dashGap = circumference - dashLength;
            const dashOffset = -cumulative * circumference;
            cumulative += fraction;
            return (_jsx("circle", { cx: center, cy: center, r: radius, stroke: stop.ringColor, strokeWidth: strokeWidth, fill: "none", strokeDasharray: `${dashLength} ${dashGap}`, strokeDashoffset: dashOffset }, stop.key));
        })
        : [];
    return (_jsxs("div", { className: "relative", style: { width: size, height: size }, children: [_jsxs("svg", { width: size, height: size, viewBox: `0 0 ${size} ${size}`, className: "-rotate-90", "aria-hidden": true, children: [_jsx("circle", { cx: center, cy: center, r: radius, stroke: "var(--color-neutral-grey-10)", strokeWidth: strokeWidth, fill: "none" }), segments] }), _jsxs("div", { className: "text-neutral-grey-100 pointer-events-none absolute inset-0 flex flex-col items-center justify-center text-[11px] leading-none font-semibold", children: [_jsx("span", { children: total }), _jsx("span", { className: "text-neutral-grey-50 text-[8px] font-normal", children: total === 1 ? "task" : "tasks" })] })] }));
}
function SourceTemplateBadge(props) {
    const { templateId, templateName, canOpenTemplate, onOpenTemplate } = props;
    // Hide entirely when the project was not created from a template, or when
    // the source template was deleted (backend leaves the resolved name null).
    if (!templateId || !templateName) {
        return null;
    }
    const tooltipText = `Created from project template "${templateName}"`;
    const inner = (_jsxs("span", { className: "inline-flex max-w-56 items-center gap-1 truncate", children: [_jsx(GitBranch, { className: "h-3 w-3 shrink-0", "aria-hidden": true }), _jsx("span", { className: "truncate", children: templateName })] }));
    return (_jsxs("div", { className: "flex shrink-0 flex-col gap-0.5", children: [_jsx("span", { className: "text-neutral-grey-50 text-[10px] font-semibold tracking-wider", children: "Created from template" }), _jsxs(Tooltip, { delayDuration: 250, children: [_jsx(TooltipTrigger, { asChild: true, children: canOpenTemplate ? (_jsx("button", { type: "button", className: "rounded-badge badge-pad text-2xs bg-neutral-grey-5 text-neutral-grey-50 hover:bg-neutral-grey-10 hover:text-neutral-grey-100 flex h-7 shrink-0 items-center font-medium", onClick: () => onOpenTemplate(templateId), "data-testid": "taskboard-project-source-template", children: inner })) : (_jsx("span", { className: "rounded-badge badge-pad text-2xs bg-neutral-grey-5 text-neutral-grey-50 flex h-7 shrink-0 items-center font-medium", "data-testid": "taskboard-project-source-template", children: inner })) }), _jsx(TooltipContent, { side: "bottom", children: canOpenTemplate
                            ? `${tooltipText}. Click to open the template editor.`
                            : tooltipText })] })] }));
}
export function ProjectDashboard(props) {
    const { selectedProjectStatus, selectedProjectCostUsed = 0, selectedProjectCostLimit = null, selectedProjectSourceTemplateId, selectedProjectSourceTemplateName, canOpenSourceTemplate = false, onOpenSourceTemplate, canEditProjectStatus = false, savingProjectStatus = false, onStatusChange, selectedProjectTaskCounts, subprojects, taskCountsByProjectId, parentProjectId, parentProjectTitle, onSelectProject, projectId, canEditProperties = false, } = props;
    const hasSubprojects = subprojects.length > 0;
    const [showSubprojects, setShowSubprojects] = useState(hasSubprojects);
    const previousSubprojectCountRef = useRef(subprojects.length);
    useEffect(() => {
        const previousCount = previousSubprojectCountRef.current;
        const nextCount = subprojects.length;
        if (nextCount > previousCount) {
            setShowSubprojects(true);
        }
        previousSubprojectCountRef.current = nextCount;
    }, [subprojects.length]);
    const normalizedCostUsed = Number.isFinite(selectedProjectCostUsed)
        ? Math.max(0, selectedProjectCostUsed)
        : 0;
    const effectiveCostLimit = typeof selectedProjectCostLimit === "number" && selectedProjectCostLimit > 0
        ? selectedProjectCostLimit
        : DEFAULT_COST_LIMIT;
    const statusValue = selectedProjectStatus ?? "Active";
    const aggregatedCounts = hasSubprojects
        ? subprojects.reduce((acc, subproject) => {
            const counts = taskCountsByProjectId[subproject.project.projectId] || EMPTY_COUNTS;
            return {
                total: acc.total + counts.total,
                todo: acc.todo + counts.todo,
                waiting: acc.waiting + counts.waiting,
                inProgress: acc.inProgress + counts.inProgress,
                review: acc.review + counts.review,
                done: acc.done + counts.done,
            };
        }, {
            total: selectedProjectTaskCounts.total,
            todo: selectedProjectTaskCounts.todo,
            waiting: selectedProjectTaskCounts.waiting,
            inProgress: selectedProjectTaskCounts.inProgress,
            review: selectedProjectTaskCounts.review,
            done: selectedProjectTaskCounts.done,
        })
        : selectedProjectTaskCounts;
    const subprojectRows = hasSubprojects && showSubprojects
        ? subprojects.map((subproject) => ({
            projectId: subproject.project.projectId,
            title: subproject.project.title,
            counts: taskCountsByProjectId[subproject.project.projectId] || EMPTY_COUNTS,
        }))
        : [];
    return (_jsxs("div", { "data-testid": "taskboard-project-dashboard", children: [parentProjectId && parentProjectTitle && onSelectProject && (_jsx("div", { className: "mb-2", children: _jsxs("button", { type: "button", className: "text-neutral-grey-50 hover:text-neutral-grey-100 text-xs", onClick: () => onSelectProject(parentProjectId), "data-testid": "taskboard-parent-project-button", children: ["\u2190 Back to ", parentProjectTitle] }) })), _jsxs("div", { className: "flex items-center gap-3 px-3 py-2", "data-testid": "taskboard-project-info-row", children: [_jsxs("div", { className: "flex shrink-0 flex-col gap-0.5", children: [_jsx("span", { className: "text-neutral-grey-50 text-[10px] font-semibold tracking-wider", id: "taskboard-project-status-label", children: "Project Status" }), _jsx(Select, { "data-testid": "taskboard-project-status-select", "aria-labelledby": "taskboard-project-status-label", value: statusValue, onValueChange: (value) => onStatusChange?.(value), disabled: !canEditProjectStatus || savingProjectStatus || !onStatusChange, options: [
                                    { value: "Planning", label: "Planning" },
                                    { value: "Active", label: "Active" },
                                    { value: "Finished", label: "Finished" },
                                    { value: "Archived", label: "Archived" },
                                ], className: "h-7 w-28 text-xs" })] }), _jsx(SourceTemplateBadge, { templateId: selectedProjectSourceTemplateId ?? null, templateName: selectedProjectSourceTemplateName ?? null, canOpenTemplate: canOpenSourceTemplate && !!onOpenSourceTemplate, onOpenTemplate: (id) => onOpenSourceTemplate?.(id) }), _jsxs("div", { className: "flex flex-1 items-center justify-end gap-2", children: [_jsxs(Tooltip, { delayDuration: 250, children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("div", { "data-testid": "taskboard-project-cost-ring", children: _jsx(CostProgressRing, { used: normalizedCostUsed, limit: effectiveCostLimit }) }) }), _jsxs(TooltipContent, { side: "bottom", children: ["Cumulative cost: $", normalizedCostUsed.toFixed(2), " / $", effectiveCostLimit.toFixed(2)] })] }), _jsxs(Tooltip, { delayDuration: 250, children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("div", { "data-testid": "taskboard-project-progress-ring", children: _jsx(TaskStateProgressRing, { counts: aggregatedCounts }) }) }), _jsx(TooltipContent, { side: "bottom", className: "max-w-xs text-left", children: aggregatedCounts.total > 0 ? (_jsx("div", { className: "space-y-1", children: STATE_STOPS.map((stop) => (_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: `inline-block h-2 w-2 rounded-full ${stop.swatchClassName}` }), stop.label] }), _jsx("span", { children: aggregatedCounts[stop.key] })] }, stop.key))) })) : ("No tasks yet") })] })] })] }), hasSubprojects && (_jsxs("div", { className: "mt-3", children: [_jsxs("button", { type: "button", className: "text-neutral-grey-50 hover:text-neutral-grey-100 mb-1.5 flex items-center gap-1 text-[11px] font-semibold tracking-wider", onClick: () => setShowSubprojects((prev) => !prev), "aria-label": showSubprojects ? "Hide subprojects" : "Show subprojects", "data-testid": "taskboard-subproject-toggle-label", children: [_jsx(ChevronDown, { className: `h-3 w-3 transition-transform ${showSubprojects ? "rotate-0" : "-rotate-90"}` }), "Subprojects (", subprojects.length, ")"] }), showSubprojects && (_jsx("div", { className: "space-y-2", "data-testid": "taskboard-project-progress-rows", children: subprojectRows.map((row) => (_jsxs("div", { className: "space-y-1", "data-testid": `taskboard-project-progress-row-${row.projectId}`, children: [_jsxs("div", { className: "flex items-center justify-between gap-4 pl-4 text-xs", children: [onSelectProject ? (_jsxs("button", { type: "button", className: "text-neutral-grey-100 hover:text-neutral-grey-100 flex min-w-0 items-center gap-1.5 truncate text-left font-medium", onClick: () => onSelectProject(row.projectId), "data-testid": `taskboard-subproject-link-${row.projectId}`, children: [_jsx(Folder, { className: "text-neutral-grey-50 h-3.5 w-3.5 shrink-0", "aria-hidden": true }), _jsx("span", { className: "truncate", children: row.title })] })) : (_jsxs("div", { className: "text-neutral-grey-100 flex min-w-0 items-center gap-1.5 truncate font-medium", children: [_jsx(Folder, { className: "text-neutral-grey-50 h-3.5 w-3.5 shrink-0", "aria-hidden": true }), _jsx("span", { className: "truncate", children: row.title })] })), _jsxs("div", { className: "text-neutral-grey-50 shrink-0 text-[11px]", children: [row.counts.total, " tasks"] })] }), _jsx("div", { className: "pr-6 pl-4", children: _jsx(TaskStateProgressBar, { counts: row.counts, compact: true }) })] }, row.projectId))) }))] })), _jsx(ProjectPropertiesPanel, { projectId: projectId, canEdit: canEditProperties, className: "mt-4" })] }));
}
//# sourceMappingURL=ProjectDashboard.js.map