import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
import { formatUsageSnapshot, formatUsdCost } from "../../core/utils/format.js";
import { formatToolActivityText } from "./agent_activity_format.js";
import { truncateFromEndByWidthPreserveAnsi, } from "./components/one_line_segments.js";
export class DiffReviewMessageComponent {
    theme;
    model;
    constructor(theme, model) {
        this.theme = theme;
        this.model = model;
    }
    setTheme(theme) {
        this.theme = theme;
    }
    update(model) {
        this.model = model;
    }
    invalidate() { }
    render(width) {
        if (width <= 0) {
            return [""];
        }
        const lines = buildDiffReviewLines(this.theme, this.model);
        const contentWidth = Math.max(0, width - 2);
        return [
            this.renderBlankLine(width),
            ...lines.map((line) => this.renderLine(line, width, contentWidth)),
            this.renderBlankLine(width),
        ];
    }
    renderBlankLine(width) {
        if (width < 2) {
            return "";
        }
        return this.theme.palette.userReviewSurface(" ".repeat(width));
    }
    renderLine(line, width, contentWidth) {
        const truncatedLine = truncateLineSegments(line, contentWidth);
        const usedWidth = truncatedLine.reduce((sum, segment) => sum + visibleWidth(segment.text), 0);
        const body = truncatedLine.map((segment) => segment.style(segment.text)).join("");
        if (width < 2) {
            return truncateFromEndByWidthPreserveAnsi(body, width);
        }
        const rightPad = this.theme.palette.userReviewSurface(" ".repeat(Math.max(0, contentWidth - usedWidth) + 1));
        return `${this.theme.palette.userReviewSurface(" ")}${body}${rightPad}`;
    }
}
function buildDiffReviewLines(theme, model) {
    const lines = [
        [
            reviewMain(theme, `diff tool ${getStatusLabel(model.status)}`),
            reviewMuted(theme, ` (${model.command})`),
        ],
    ];
    if (model.status === "active" || model.status === "preparing") {
        const diffToolLines = splitUiText(model.uiText).map((line) => [reviewDim(theme, line)]);
        if (diffToolLines.length > 0) {
            lines.push(...diffToolLines);
        }
        const reviewAgentLines = buildReviewAgentLines(theme, model.reviewAgents);
        if (reviewAgentLines.length > 0) {
            if (diffToolLines.length > 0) {
                lines.push([]);
            }
            lines.push(...reviewAgentLines);
        }
    }
    else if (model.status === "failed" && model.detail?.trim()) {
        lines.push([reviewMuted(theme, model.detail.trim())]);
    }
    return trimTrailingBlankLines(lines);
}
function buildReviewAgentLines(theme, reviewAgents) {
    if (!reviewAgents || reviewAgents.length === 0) {
        return [];
    }
    const lines = [];
    reviewAgents.forEach((agent, index) => {
        lines.push([reviewMain(theme, agent.threadId), reviewMuted(theme, ` (${agent.status})`)]);
        const activityText = formatToolActivityText(agent.lastActivityText ?? "");
        if (activityText) {
            lines.push([reviewDim(theme, activityText)]);
        }
        lines.push([
            reviewMuted(theme, `${formatUsageSnapshot(agent.usage)} · ${formatUsdCost(agent.costTotal)}`),
        ]);
        if (index < reviewAgents.length - 1) {
            lines.push([]);
        }
    });
    return lines;
}
function reviewMain(theme, text) {
    return createReviewSegment(theme, theme.palette.userReviewText, text);
}
function reviewMuted(theme, text) {
    return createReviewSegment(theme, theme.palette.userReviewTextMuted, text);
}
function reviewDim(theme, text) {
    return createReviewSegment(theme, theme.palette.userReviewTextDim, text);
}
function createReviewSegment(theme, textColor, text) {
    return {
        text,
        style: (value) => theme.palette.userReviewSurface(textColor(value)),
    };
}
function getStatusLabel(status) {
    switch (status) {
        case "preparing":
            return "preparing";
        case "active":
            return "active";
        case "returned":
            return "completed";
        case "cancelled":
            return "cancelled";
        case "failed":
            return "failed";
    }
}
function splitUiText(text) {
    const trimmed = text?.trim();
    if (!trimmed) {
        return [];
    }
    return trimmed.split(/\r?\n/).map((line) => line.trimEnd());
}
function truncateLineSegments(segments, maxWidth) {
    if (maxWidth <= 0 || segments.length === 0) {
        return [];
    }
    const totalWidth = segments.reduce((sum, segment) => sum + visibleWidth(segment.text), 0);
    if (totalWidth <= maxWidth) {
        return segments;
    }
    const contentWidth = Math.max(0, maxWidth - 1);
    const truncated = [];
    let usedWidth = 0;
    for (const segment of segments) {
        if (usedWidth >= contentWidth) {
            break;
        }
        const remainingWidth = contentWidth - usedWidth;
        const segmentWidth = visibleWidth(segment.text);
        if (segmentWidth <= remainingWidth) {
            truncated.push(segment);
            usedWidth += segmentWidth;
            continue;
        }
        const partial = truncateToWidth(segment.text, remainingWidth, "");
        if (partial.length > 0) {
            truncated.push({ ...segment, text: partial });
        }
        break;
    }
    const ellipsisSegment = truncated[truncated.length - 1] ?? segments[0];
    return ellipsisSegment ? [...truncated, { ...ellipsisSegment, text: "…" }] : [];
}
function trimTrailingBlankLines(lines) {
    let end = lines.length;
    while (end > 0 && lines[end - 1]?.length === 0) {
        end -= 1;
    }
    return lines.slice(0, end);
}
//# sourceMappingURL=diff_review_message.js.map