import { isRelation, isSingleRelation, } from "@limetech/lime-web-components";
/**
 * Get the color for a limetype from its UI configuration
 *
 * @param limetype the limetype
 * @returns the color string (CSS variable or RGB)
 */
export function getColor(limetype) {
    var _a;
    const limetypeWithUI = limetype;
    const color = ((_a = limetypeWithUI === null || limetypeWithUI === void 0 ? void 0 : limetypeWithUI.ui) === null || _a === void 0 ? void 0 : _a.color) || 'rgb(var(--color-gray-default))';
    return getLimeColor(color);
}
/**
 * Convert lime color references to CSS variables
 *
 * @param color the color string
 * @returns CSS-ready color string
 */
function getLimeColor(color) {
    if (color.startsWith('lime-')) {
        return `var(--${color})`;
    }
    return color;
}
/**
 * Get the icon configuration for a limetype
 *
 * @param limetype the limetype
 * @returns Icon object with name and color
 */
export function getIcon(limetype) {
    var _a;
    const limetypeWithUI = limetype;
    return {
        name: ((_a = limetypeWithUI === null || limetypeWithUI === void 0 ? void 0 : limetypeWithUI.ui) === null || _a === void 0 ? void 0 : _a.icon) || 'decision',
        color: getColor(limetype),
    };
}
/**
 * Whether the given object has the given label or not.
 *
 * @param object the object to check label for
 * @param label the label to check for
 * @returns true if the object has the label
 */
export function hasLabel(object, label) {
    return object.label === label;
}
/**
 * Whether the given property is a hasmany relation or not.
 *
 * @param property the property to check
 * @returns true if the property is a hasmany relation
 */
export function isManyRelation(property) {
    return isRelation(property) && !isSingleRelation(property);
}
/**
 * Finds a relation property on the given limetype that is related to a
 * limetype with the given label.
 *
 * @param limetype the limetype to search for the relation property
 * @param label the label of the target limetype to match
 * @returns the relation property or undefined
 */
export function getRelationProperty(limetype, label) {
    return Object.values(limetype.properties).find((property) => property &&
        property.relation &&
        hasLabel(property.relation.getLimetype(), label));
}
/**
 * Whether the limetype has a hasmany relation of a limetype with the given label
 *
 * @param limetype the limetype
 * @param relatedLabel the label of the related limetype
 * @returns true if the limetype has the hasmany relation
 */
export function hasHasManyRelation(limetype, relatedLabel) {
    const property = getRelationProperty(limetype, relatedLabel);
    return !!property && isManyRelation(property);
}
/**
 * Find the property on `targetLimetype` whose relation points back to
 * `contextLimetypeName`. This is the property a Lime CRM widget can use
 * to narrow a filter to "items related to the current context object"
 * — for example, "deals belonging to *this* company" when a widget is
 * placed on a company card.
 *
 * Pass `propertyName` (the widget's configured property) to prefer the
 * back-reference of *that* property's relation when ambiguous, falling
 * back to the first matching relation on the limetype otherwise.
 * @param options - the lookup inputs.
 * @param options.targetLimetype - the limetype the filter is querying
 * (i.e. the limetype the explorer would land on). The returned property
 * name is one of *its* properties.
 * @param options.currentLimetype - the limetype of the page hosting the
 * widget, used together with `propertyName` to resolve a back-reference
 * when the configured property is itself a relation.
 * @param options.contextLimetypeName - name of the page's limetype.
 * Returns `undefined` when missing — there is no context to relate to.
 * @param options.contextId - id of the current context object. Returns
 * `undefined` when missing — the relation cannot be narrowed without it.
 * @param options.propertyName - widget-configured property whose
 * relation back-reference should be preferred over a generic limetype
 * scan. Optional.
 * @returns name of the property on `targetLimetype` that points back at
 * the context, or `undefined` when no such relation exists or the
 * required inputs are missing.
 */
export function getRelationPropertyName(options) {
    var _a, _b, _c;
    const { targetLimetype, currentLimetype, contextLimetypeName, contextId, propertyName, } = options;
    if (!targetLimetype || !contextLimetypeName || !contextId) {
        return undefined;
    }
    if (propertyName) {
        const backReference = (_b = (_a = currentLimetype === null || currentLimetype === void 0 ? void 0 : currentLimetype.getProperty(propertyName)) === null || _a === void 0 ? void 0 : _a.relation) === null || _b === void 0 ? void 0 : _b.getBackreference();
        if (backReference) {
            return backReference.name;
        }
    }
    return (_c = Object.values(targetLimetype.properties).find((property) => {
        var _a;
        return ((_a = property.relation) === null || _a === void 0 ? void 0 : _a.getLimetype().name) === contextLimetypeName;
    })) === null || _c === void 0 ? void 0 : _c.name;
}
