/**
 * Flow Formatters
 *
 * Human-readable formatting for flow list output.
 * Supports both FlowConfig (config-only) and FlowStatus (with runtime state).
 */
import { Array as Arr, Option as O } from "effect";
import { ANSI } from "../constants/ansi.js";
import { formatRelativeTime } from "./status.js";
// ============================================================================
// State Icons
// ============================================================================
const STATE_ICONS = {
    idle: `${ANSI.GREEN}●${ANSI.RESET}`, // Green circle - synced and ready
    syncing: `${ANSI.CYAN}◐${ANSI.RESET}`, // Cyan half circle - in progress
    error: `${ANSI.RED}✗${ANSI.RESET}`, // Red X - error state
    paused: `${ANSI.YELLOW}⏸${ANSI.RESET}` // Yellow pause - paused
};
const STATE_LABELS = {
    idle: `${ANSI.GREEN}✓ Clean${ANSI.RESET}`,
    syncing: `${ANSI.CYAN}Syncing...${ANSI.RESET}`,
    error: `${ANSI.RED}Error${ANSI.RESET}`,
    paused: `${ANSI.YELLOW}[Paused]${ANSI.RESET}`
};
// ============================================================================
// Path Formatting
// ============================================================================
/**
 * Shorten home directory paths for readability.
 */
const shortenPath = (path) => {
    const home = process.env.HOME;
    if (home != null && path.startsWith(home)) {
        return `~${path.slice(home.length)}`;
    }
    return path;
};
/**
 * Truncate string to max length with ellipsis.
 */
const truncate = (str, maxLen) => str.length > maxLen ? `${str.slice(0, maxLen - 1)}…` : str;
/**
 * Pad string to fixed width.
 */
const padRight = (str, width) => str.padEnd(width);
// ============================================================================
// Flow Formatting
// ============================================================================
/**
 * Format a single flow as a multi-line entry.
 */
const formatFlowEntry = (flow) => {
    const icon = STATE_ICONS[flow.state];
    const stateLabel = STATE_LABELS[flow.state];
    const path = shortenPath(flow.path);
    const lastSync = formatRelativeTime(flow.lastSync);
    const pendingInfo = flow.pendingChanges > 0 ? `${flow.pendingChanges} pending` : undefined;
    const lines = [
        `${icon} ${flow.name}`,
        `  ${ANSI.DIM}${path}${ANSI.RESET}`,
        `  Last sync: ${lastSync}  ${stateLabel}${pendingInfo != null ? `  ${pendingInfo}` : ""}`
    ];
    // Add error line if present using Option pattern
    const errorLine = O.fromNullable(flow.lastError).pipe(O.map((err) => [`  ${ANSI.RED}Error: ${err}${ANSI.RESET}`]), O.getOrElse(() => []));
    return Arr.join(Arr.appendAll(lines, errorLine), "\n");
};
/**
 * Format flows as a detailed list.
 */
export const formatFlows = (flows) => Arr.match(flows, {
    onEmpty: () => "No flows configured.\n\nAdd a repository with: ghostflow add <path>",
    onNonEmpty: (nonEmpty) => Arr.join(Arr.map(nonEmpty, formatFlowEntry), "\n\n")
});
// ============================================================================
// Compact Formatting
// ============================================================================
/**
 * Format a single flow as a compact one-liner.
 */
const formatFlowCompact = (flow) => {
    const icon = STATE_ICONS[flow.state];
    const name = padRight(truncate(flow.name, 20), 20);
    const path = padRight(truncate(shortenPath(flow.path), 30), 30);
    const stateLabel = STATE_LABELS[flow.state];
    return `${icon} ${name} ${path} ${stateLabel}`;
};
/**
 * Format flows as compact table-like output.
 */
export const formatFlowsCompact = (flows) => Arr.match(flows, {
    onEmpty: () => "No flows configured.",
    onNonEmpty: (nonEmpty) => Arr.join(Arr.map(nonEmpty, formatFlowCompact), "\n")
});
// ============================================================================
// Paths Only
// ============================================================================
/**
 * Format flows as paths only (for shell scripts).
 */
export const formatFlowPaths = (flows) => Arr.match(flows, {
    onEmpty: () => "",
    onNonEmpty: (nonEmpty) => Arr.join(Arr.map(nonEmpty, (f) => f.path), "\n")
});
// ============================================================================
// Config-Only Formatting (No Runtime State)
// ============================================================================
/** Icon for enabled/disabled state */
const getConfigIcon = (enabled) => enabled ? `${ANSI.GREEN}●${ANSI.RESET}` : `${ANSI.YELLOW}○${ANSI.RESET}`;
/** Get display name for a FlowConfig */
const getFlowDisplayName = (flow) => O.getOrElse(O.fromNullable(flow.name), () => flow.path);
/**
 * Format a single FlowConfig as a multi-line entry.
 */
const formatFlowConfigEntry = (flow) => {
    const icon = getConfigIcon(flow.enabled);
    const name = getFlowDisplayName(flow);
    const path = shortenPath(flow.path);
    const enabledLabel = flow.enabled ? undefined : `${ANSI.DIM}(disabled)${ANSI.RESET}`;
    const lines = [
        `${icon} ${name}${enabledLabel != null ? ` ${enabledLabel}` : ""}`,
        `  ${ANSI.DIM}${path}${ANSI.RESET}`,
        `  Remote: ${flow.remote}${flow.branch != null ? `  Branch: ${flow.branch}` : ""}`,
        `  ${ANSI.DIM}ID: ${flow.id}${ANSI.RESET}`
    ];
    return Arr.join(lines, "\n");
};
/**
 * Format FlowConfigs as a detailed list (config view, no runtime state).
 */
export const formatFlowConfigs = (flows) => Arr.match(flows, {
    onEmpty: () => "No flows configured.\n\nAdd a repository with: ghostflow add <path>",
    onNonEmpty: (nonEmpty) => Arr.join(Arr.map(nonEmpty, formatFlowConfigEntry), "\n\n")
});
/**
 * Format a single FlowConfig as a compact one-liner.
 */
const formatFlowConfigCompact = (flow) => {
    const icon = getConfigIcon(flow.enabled);
    const name = padRight(truncate(getFlowDisplayName(flow), 20), 20);
    const path = padRight(truncate(shortenPath(flow.path), 30), 30);
    const status = flow.enabled ? `${ANSI.GREEN}✓${ANSI.RESET}` : `${ANSI.DIM}disabled${ANSI.RESET}`;
    return `${icon} ${name} ${path} ${status}`;
};
/**
 * Format FlowConfigs as compact table-like output (config view).
 */
export const formatFlowConfigsCompact = (flows) => Arr.match(flows, {
    onEmpty: () => "No flows configured.",
    onNonEmpty: (nonEmpty) => Arr.join(Arr.map(nonEmpty, formatFlowConfigCompact), "\n")
});
/**
 * Format FlowConfig paths only (for shell scripts).
 */
export const formatFlowConfigPaths = (flows) => Arr.match(flows, {
    onEmpty: () => "",
    onNonEmpty: (nonEmpty) => Arr.join(Arr.map(nonEmpty, (f) => f.path), "\n")
});
//# sourceMappingURL=flows.js.map