/**
 * statusBadge — small helpers that build Node-RED status objects
 * ({ fill, shape, text }) consistently across every node.
 *
 * See CONTRACTS.md §7. Domains compose badges via these helpers so the
 * editor look-and-feel converges instead of every node rolling its own
 * emoji + colour rules.
 */

'use strict';

const MAX_TEXT = 60;
const SEPARATOR = ' | ';

const DEFAULT_BADGE = { fill: 'green', shape: 'dot' };
const ERROR_BADGE   = { fill: 'red',   shape: 'ring' };
const IDLE_BADGE    = { fill: 'blue',  shape: 'dot' };
const UNKNOWN_BADGE = { fill: 'grey',  shape: 'ring' };

// Truncate to MAX_TEXT keeping room for the ellipsis. Editor clips the
// rest visually anyway, but we want the cut to be deterministic so
// snapshot tests don't drift across Node-RED versions.
function _clip(text) {
    if (text == null) return '';
    const s = String(text);
    if (s.length <= MAX_TEXT) return s;
    return s.slice(0, MAX_TEXT - 1) + '…';
}

function _joinParts(parts) {
    if (!Array.isArray(parts) || parts.length === 0) return '';
    const kept = parts.filter((p) => p != null && p !== false && p !== '');
    if (kept.length === 0) return '';
    return kept.map(String).join(SEPARATOR);
}

function compose(parts, opts) {
    const text = _clip(_joinParts(parts));
    return {
        fill:  (opts && opts.fill)  || DEFAULT_BADGE.fill,
        shape: (opts && opts.shape) || DEFAULT_BADGE.shape,
        text,
    };
}

function error(message) {
    return {
        fill:  ERROR_BADGE.fill,
        shape: ERROR_BADGE.shape,
        text:  _clip(`⚠ ${message == null ? '' : message}`),
    };
}

function idle(label) {
    return {
        fill:  IDLE_BADGE.fill,
        shape: IDLE_BADGE.shape,
        text:  _clip(`⏸️ ${label == null ? '' : label}`),
    };
}

// Look up a state-template badge and optionally compose extra parts
// into its text. Missing template falls back to a grey "unknown state"
// badge — silent so caller can still surface the bad state through logs.
function byState(stateMap, currentState, opts) {
    const template = stateMap && stateMap[currentState];
    if (!template) {
        return {
            fill:  UNKNOWN_BADGE.fill,
            shape: UNKNOWN_BADGE.shape,
            text:  _clip(`unknown state: ${currentState == null ? '' : currentState}`),
        };
    }
    const baseText = template.text == null ? '' : String(template.text);
    const extras   = opts && Array.isArray(opts.compose) ? opts.compose : [];
    const merged   = extras.length > 0
        ? _joinParts([baseText, ...extras])
        : baseText;
    return {
        fill:  template.fill  || DEFAULT_BADGE.fill,
        shape: template.shape || DEFAULT_BADGE.shape,
        text:  _clip(merged),
    };
}

function text(string, opts) {
    return {
        fill:  (opts && opts.fill)  || DEFAULT_BADGE.fill,
        shape: (opts && opts.shape) || DEFAULT_BADGE.shape,
        text:  _clip(string == null ? '' : string),
    };
}

const statusBadge = { compose, error, idle, byState, text };

module.exports = { statusBadge, MAX_TEXT };
