// Copyright (c) 2026 Modelware. All rights reserved.

export type TemplateValue = string | number | boolean | null | string[] | Record<string, unknown>;

export type TemplateParameterType =
    | 'iri'
    | 'string'
    | 'number'
    | 'boolean'
    | 'iri[]'
    | 'json';

export interface TemplateParameterDefinition {
    id: string;
    type: TemplateParameterType;
    required?: boolean;
    defaultValue?: TemplateValue;
    description?: string;
}

export interface TemplateNavigationMatch {
    anyTypeOf?: string[];
    allTypesOf?: string[];
}

export interface TemplateNavigationExposure {
    kind: 'navigation';
    match?: TemplateNavigationMatch;
}

export interface TemplateComposeExposure {
    kind: 'compose';
}

export interface TemplateCallExposure {
    kind: 'call';
    selection?: {
        min?: number;
        max?: number;
    };
}

export type TemplateExposure =
    | TemplateNavigationExposure
    | TemplateComposeExposure
    | TemplateCallExposure;

export interface TemplateDefinition {
    id: string;
    name?: string;
    rank?: number;
    exposures?: TemplateExposure[];
    parameters?: TemplateParameterDefinition[];
    body: string;
    sourceUri?: string;
}

export type TemplateInvocationMode = 'navigation' | 'compose' | 'call' | 'preview' | 'inline' | 'newDocument';

export interface TemplateInvocationContext {
    invocation: {
        mode: TemplateInvocationMode;
        sourceDocumentUri?: string;
        referenceDocumentUri?: string;
    };
    model?: {
        ontologyIri?: string;
        modelUri?: string;
    };
    focus?: {
        memberIri?: string;
        rdfTypes?: string[];
    };
    selection?: {
        iris?: string[];
        rows?: Array<{ iri: string; cells: Record<string, string> }>;
    };
    vars?: Record<string, TemplateValue>;
}

export interface TemplateInvocation {
    templateId: string;
    mode: TemplateInvocationMode;
    context: TemplateInvocationContext;
    args?: Record<string, TemplateValue>;
}

export interface TemplateResolutionCandidate {
    template: TemplateDefinition;
    score: number;
}

export interface TemplateResolutionResult {
    template?: TemplateDefinition;
    candidates: TemplateResolutionCandidate[];
}

export interface TemplateBindResult {
    values: Record<string, TemplateValue>;
}
