/**
 * Block Kit element + message types for the unified Slack notification factory.
 *
 * These are internal render types (not a trust boundary): the factory produces
 * them, Slack consumes them. `SlackMessage` is the one envelope shared by the
 * eval adapter/sink and the api gateway, replacing the two former local copies.
 */
import type { DigestSummary, Report } from "../../types/index.js";
import type { NotificationDelivery } from "../../types/team.js";
import type { ChannelDelivery } from "../../ports/notification.js";
import type { AskJobOutcome, FailureAlertInput } from "../gateway-events.js";
export interface SlackPlainText {
    type: "plain_text";
    text: string;
    emoji?: boolean;
}
export interface SlackMrkdwnText {
    type: "mrkdwn";
    text: string;
}
export type SlackTextObject = SlackPlainText | SlackMrkdwnText;
export interface SlackConfirmObject {
    title: {
        type: "plain_text";
        text: string;
    };
    text: {
        type: "mrkdwn";
        text: string;
    };
    confirm: {
        type: "plain_text";
        text: string;
    };
    deny: {
        type: "plain_text";
        text: string;
    };
    style?: "primary" | "danger";
}
export interface SlackButtonElement {
    type: "button";
    text: {
        type: "plain_text";
        text: string;
        emoji?: boolean;
    };
    /** Set for a link button (opens a URL, no interactivity handler needed). */
    url?: string;
    /** Set for an interactive button (requires the W-slack-interactivity handler). */
    value?: string;
    style?: "primary" | "danger";
    action_id?: string;
    confirm?: SlackConfirmObject;
}
export interface SlackOverflowElement {
    type: "overflow";
    action_id?: string;
    options: {
        text: {
            type: "plain_text";
            text: string;
        };
        value: string;
    }[];
}
export type SlackActionElement = SlackButtonElement | SlackOverflowElement;
export interface SlackBlock {
    type: "header" | "section" | "context" | "divider" | "actions";
    text?: SlackTextObject;
    fields?: SlackTextObject[];
    elements?: (SlackTextObject | SlackActionElement)[];
    block_id?: string;
}
/**
 * Slack's native `markdown` block (Block Kit, Feb 2025). Its `text` is a raw
 * standard-Markdown string that Slack translates to mrkdwn on render — bold,
 * italic, links, headings, lists, code blocks, tables. Distinct from
 * `SlackBlock` because its `text` is a plain string, not a text object. The
 * cumulative `text` across markdown blocks in one message caps at 12,000 chars.
 */
export interface SlackMarkdownBlock {
    type: "markdown";
    text: string;
}
export interface SlackAttachment {
    color?: string;
    blocks: SlackBlock[];
}
/** The single envelope every Slack-bound notification produces. */
export interface SlackMessage {
    /** Fallback / notification text, always present. */
    text: string;
    /** Top-level blocks (digest, ask-answer). */
    blocks?: (SlackBlock | SlackMarkdownBlock)[];
    /** Color-barred wrapper (report templates, admin alert). */
    attachments?: SlackAttachment[];
    /** Ask bot visibility; unused by chat.postMessage. */
    responseType?: "in_channel" | "ephemeral";
}
/** Discriminated input to the factory, one variant per notifiable surface. */
export type SlackNotificationEvent = {
    kind: "report";
    report: Report;
    delivery?: ChannelDelivery;
} | {
    kind: "digest";
    digest: DigestSummary;
    cadence: NotificationDelivery;
    delivery?: ChannelDelivery;
} | {
    kind: "admin-alert";
    alert: FailureAlertInput;
} | {
    kind: "ask-answer";
    outcome: AskJobOutcome;
    channelName?: string;
};
/** Stable ids for every button/overflow the factory can emit. */
export type SlackActionId = "viewReport" | "viewPr" | "openDashboard" | "openRequest" | "acknowledge" | "rerun" | "retry" | "feedback" | "overflow";
export interface SlackBuildOptions {
    /** Resolved dashboard base URL (env read at the composition/command root). */
    dashboardBaseUrl: string;
    /** Per-area score rendering: ASCII bars (default) or field columns. */
    areaViz?: "bars" | "fields";
    /** Provenance verbosity: one slim context line (default) or the full block. */
    provenance?: "slim" | "full";
    /** Per-action enable map; an action is suppressed only when explicitly `false`. */
    actions?: Partial<Record<SlackActionId, boolean>>;
}
