/**
 * Enhanced Spinners and Progress Components
 *
 * Provides various spinner styles and progress indicators for CLI.
 * Based on hurry-mode's UI component patterns.
 */
import React, { useState, useEffect } from "react";
import { Box, Text } from "ink";
/**
 * Spinner frame definitions
 */
const SPINNER_FRAMES = {
    dots: ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"],
    line: ["-", "\\", "|", "/"],
    circle: ["◐", "◓", "◑", "◒"],
    arrow: ["←", "↖", "↑", "↗", "→", "↘", "↓", "↙"],
    bounce: ["⠁", "⠂", "⠄", "⠂"],
    pulse: ["█", "▓", "▒", "░", "▒", "▓"],
    braille: ["⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"],
    clock: ["🕐", "🕑", "🕒", "🕓", "🕔", "🕕", "🕖", "🕗", "🕘", "🕙", "🕚", "🕛"],
    earth: ["🌍", "🌎", "🌏"],
    moon: ["🌑", "🌒", "🌓", "🌔", "🌕", "🌖", "🌗", "🌘"],
};
/**
 * Enhanced Spinner Component
 */
export function EnhancedSpinner({ style = "dots", text = "Loading...", color = "cyan", speed = 80, isActive = true, }) {
    const [frame, setFrame] = useState(0);
    const frames = SPINNER_FRAMES[style];
    useEffect(() => {
        if (!isActive)
            return;
        const interval = setInterval(() => {
            setFrame((prev) => (prev + 1) % frames.length);
        }, speed);
        return () => clearInterval(interval);
    }, [isActive, frames.length, speed]);
    if (!isActive)
        return null;
    return (React.createElement(Box, null,
        React.createElement(Text, { color: color },
            frames[frame],
            " "),
        React.createElement(Text, null, text)));
}
/**
 * Progress Bar Component
 */
export function ProgressBar({ progress, width = 30, showPercentage = true, filledChar = "█", emptyChar = "░", color = "green", label, }) {
    const clampedProgress = Math.max(0, Math.min(100, progress));
    const filledWidth = Math.round((clampedProgress / 100) * width);
    const emptyWidth = width - filledWidth;
    const filled = filledChar.repeat(filledWidth);
    const empty = emptyChar.repeat(emptyWidth);
    return (React.createElement(Box, { flexDirection: "column" },
        label && React.createElement(Text, { dimColor: true }, label),
        React.createElement(Box, null,
            React.createElement(Text, { color: color }, filled),
            React.createElement(Text, { dimColor: true }, empty),
            showPercentage && (React.createElement(Text, null,
                " ",
                clampedProgress.toFixed(0),
                "%")))));
}
/**
 * Step Progress Component
 */
export function StepProgress({ steps, currentStep, completedColor = "green", currentColor = "cyan", pendingColor = "gray", }) {
    return (React.createElement(Box, { flexDirection: "column" }, steps.map((step, index) => {
        let icon;
        let textColor;
        if (index < currentStep) {
            icon = "✓";
            textColor = completedColor;
        }
        else if (index === currentStep) {
            icon = "●";
            textColor = currentColor;
        }
        else {
            icon = "○";
            textColor = pendingColor;
        }
        return (React.createElement(Box, { key: index },
            React.createElement(Text, { color: textColor },
                icon,
                " "),
            React.createElement(Text, { color: textColor }, step)));
    })));
}
/**
 * Status Indicator Component
 */
export function StatusIndicator({ status, text, showIcon = true, }) {
    const config = {
        success: { icon: "✓", color: "green" },
        error: { icon: "✗", color: "red" },
        warning: { icon: "⚠", color: "yellow" },
        info: { icon: "ℹ", color: "blue" },
        pending: { icon: "○", color: "gray" },
        running: { icon: "◐", color: "cyan" },
    };
    const { icon, color } = config[status];
    return (React.createElement(Box, null,
        showIcon && React.createElement(Text, { color: color },
            icon,
            " "),
        React.createElement(Text, { color: color }, text)));
}
/**
 * Countdown Timer Component
 */
export function CountdownTimer({ seconds: initialSeconds, onComplete, format = "seconds", prefix = "Time remaining: ", }) {
    const [seconds, setSeconds] = useState(initialSeconds);
    useEffect(() => {
        if (seconds <= 0) {
            onComplete?.();
            return;
        }
        const interval = setInterval(() => {
            setSeconds((prev) => prev - 1);
        }, 1000);
        return () => clearInterval(interval);
    }, [seconds, onComplete]);
    const formatTime = (secs) => {
        if (format === "seconds") {
            return `${secs}s`;
        }
        else if (format === "minutes") {
            const mins = Math.floor(secs / 60);
            const remainingSecs = secs % 60;
            return `${mins}:${remainingSecs.toString().padStart(2, "0")}`;
        }
        else {
            const hours = Math.floor(secs / 3600);
            const mins = Math.floor((secs % 3600) / 60);
            const remainingSecs = secs % 60;
            return `${hours}:${mins.toString().padStart(2, "0")}:${remainingSecs.toString().padStart(2, "0")}`;
        }
    };
    return (React.createElement(Box, null,
        React.createElement(Text, { dimColor: true }, prefix),
        React.createElement(Text, { color: seconds <= 10 ? "red" : "cyan" }, formatTime(seconds))));
}
/**
 * Task List Component
 */
export function TaskList({ tasks }) {
    const [runningFrame, setRunningFrame] = useState(0);
    const spinnerFrames = SPINNER_FRAMES.dots;
    useEffect(() => {
        const hasRunning = tasks.some((t) => t.status === "running");
        if (!hasRunning)
            return;
        const interval = setInterval(() => {
            setRunningFrame((prev) => (prev + 1) % spinnerFrames.length);
        }, 80);
        return () => clearInterval(interval);
    }, [tasks, spinnerFrames.length]);
    const getIcon = (status) => {
        switch (status) {
            case "completed":
                return "✓";
            case "failed":
                return "✗";
            case "running":
                return spinnerFrames[runningFrame];
            case "skipped":
                return "⊘";
            default:
                return "○";
        }
    };
    const getColor = (status) => {
        switch (status) {
            case "completed":
                return "green";
            case "failed":
                return "red";
            case "running":
                return "cyan";
            case "skipped":
                return "yellow";
            default:
                return "gray";
        }
    };
    return (React.createElement(Box, { flexDirection: "column" }, tasks.map((task, index) => (React.createElement(Box, { key: index },
        React.createElement(Text, { color: getColor(task.status) },
            getIcon(task.status),
            " "),
        React.createElement(Text, { color: getColor(task.status) }, task.name),
        task.duration !== undefined && task.status === "completed" && (React.createElement(Text, { dimColor: true },
            " (",
            task.duration,
            "ms)")))))));
}
/**
 * Info Panel Component (Tooltip-like)
 */
export function InfoPanel({ title, content, type = "info", width = 50, }) {
    const colors = {
        info: "blue",
        warning: "yellow",
        error: "red",
        success: "green",
        tip: "magenta",
    };
    const icons = {
        info: "ℹ",
        warning: "⚠",
        error: "✗",
        success: "✓",
        tip: "💡",
    };
    const borderColor = colors[type];
    const lines = Array.isArray(content) ? content : [content];
    const border = "─".repeat(width - 2);
    return (React.createElement(Box, { flexDirection: "column" },
        React.createElement(Text, { color: borderColor },
            "\u250C",
            border,
            "\u2510"),
        React.createElement(Box, null,
            React.createElement(Text, { color: borderColor }, "\u2502 "),
            React.createElement(Text, { color: borderColor, bold: true },
                icons[type],
                " ",
                title),
            React.createElement(Text, { color: borderColor },
                " ".repeat(Math.max(0, width - title.length - 5)),
                "\u2502")),
        React.createElement(Text, { color: borderColor },
            "\u251C",
            border,
            "\u2524"),
        lines.map((line, index) => (React.createElement(Box, { key: index },
            React.createElement(Text, { color: borderColor }, "\u2502 "),
            React.createElement(Text, null, line),
            React.createElement(Text, { color: borderColor },
                " ".repeat(Math.max(0, width - line.length - 4)),
                "\u2502")))),
        React.createElement(Text, { color: borderColor },
            "\u2514",
            border,
            "\u2518")));
}
/**
 * Simple Data Table Component
 */
export function DataTable({ headers, rows, maxWidth = 80 }) {
    // Calculate column widths
    const colWidths = headers.map((header, i) => {
        const maxInColumn = Math.max(header.length, ...rows.map((row) => (row[i] || "").length));
        return Math.min(maxInColumn, Math.floor(maxWidth / headers.length));
    });
    const formatCell = (content, width) => {
        if (content.length > width) {
            return content.slice(0, width - 1) + "…";
        }
        return content.padEnd(width);
    };
    const headerRow = headers
        .map((h, i) => formatCell(h, colWidths[i]))
        .join(" │ ");
    const separator = colWidths.map((w) => "─".repeat(w)).join("─┼─");
    return (React.createElement(Box, { flexDirection: "column" },
        React.createElement(Text, { bold: true }, headerRow),
        React.createElement(Text, { dimColor: true }, separator),
        rows.map((row, rowIndex) => (React.createElement(Text, { key: rowIndex }, row.map((cell, i) => formatCell(cell || "", colWidths[i])).join(" │ "))))));
}
/**
 * Badge Component
 */
export function Badge({ text, color = "white", backgroundColor = "blue", }) {
    return (React.createElement(Text, { color: color, backgroundColor: backgroundColor },
        " ",
        text,
        " "));
}
/**
 * Divider Component
 */
export function Divider({ width = 60, char = "─", title, color = "gray", }) {
    if (title) {
        const sideWidth = Math.floor((width - title.length - 2) / 2);
        const leftSide = char.repeat(sideWidth);
        const rightSide = char.repeat(width - sideWidth - title.length - 2);
        return (React.createElement(Text, { color: color },
            leftSide,
            " ",
            title,
            " ",
            rightSide));
    }
    return React.createElement(Text, { color: color }, char.repeat(width));
}
//# sourceMappingURL=EnhancedSpinners.js.map