import { ReactNode } from 'react';

/**
 * Wire shape the backend `/api/v1/workflow-template` endpoint is expected
 * to return. Top-level fields mirror the persistence model; everything
 * UI-related lives under `templateUI`. Use with `templateRegistry.registerFromApi(list)`.
 */
export declare interface ApiWorkflowTemplate {
    key: string;
    name: string;
    state?: string;
    description?: string;
    allowedTasks?: string[];
    allowedSources?: string[];
    configuration?: Record<string, unknown>;
    templateUI?: Partial<Omit<WorkflowTemplate, 'triggerKey' | 'label' | 'description' | 'availableTasks'>>;
}

declare type BranchChain = CanvasSlot[];

declare interface BranchMap {
    [filterId: string]: {
        [branchKey: string]: BranchChain;
    };
}

declare interface CanvasSlot {
    id: string;
    kind: SlotKind;
    reactFlowType: string;
    descriptorType?: string;
    formData?: Record<string, unknown>;
    nodeData?: Record<string, unknown>;
    deletable?: boolean;
    label?: string;
    /** Maps branch key → display label. e.g. { pass: 'Pass', fail: 'Fail' } */
    branchLabels?: Record<string, string>;
}

declare interface FixedEdge {
    id: string;
    source: string;
    target: string;
}

declare interface FixedNode {
    id: string;
    type: string;
    data?: Record<string, unknown>;
    deletable?: false;
}

declare type SlotKind = 'start' | 'end' | 'addTrigger' | 'triggerFixed' | 'userTask' | 'addStep' | 'filter' | 'approval';

export declare class TemplateRegistry {
    private templates;
    /**
     * Register a template. Normalises `allowedTasks` (the backend's name) →
     * `availableTasks` (FlowForge's canonical name) so consumers can pass
     * either without rewriting.
     */
    register(template: WorkflowTemplate): this;
    /**
     * Register a list of templates fetched from `GET /api/v1/workflow-template`.
     *
     * The API shape is:
     *   {
     *     key, name, description, allowedTasks, allowedSources,
     *     configuration,            // runtime BPMN — ignored by the canvas
     *     templateUI: {             // ← UI bag, spread onto the template
     *       triggerCategory, icon, tags, category, author, popularity,
     *       source, product, taskLabels, maxTasks, skeletonState, …
     *     }
     *   }
     *
     * Anything in `templateUI` overrides the top-level shorthand where there's
     * an overlap. Bad rows (missing `key`) are skipped with a DEV warning
     * rather than throwing, so one broken template doesn't blank the picker.
     *
     * Returns `this` for chaining and the count of templates registered.
     */
    registerFromApi(list: ApiWorkflowTemplate[]): this;
    lookup(triggerKey: string): WorkflowTemplate | undefined;
    list(): WorkflowTemplate[];
    listByCategory(category: string): WorkflowTemplate[];
    listByTag(tag: string): WorkflowTemplate[];
    search(query: string): WorkflowTemplate[];
    categories(): string[];
    /** Remove every template — useful before re-loading from backend. */
    clear(): this;
}

export declare const templateRegistry: TemplateRegistry;

declare interface WorkflowState {
    slots: CanvasSlot[];
    branches: BranchMap;
}

export declare interface WorkflowTemplate {
    triggerKey: string;
    label: string;
    description?: string;
    icon?: ReactNode;
    triggerCategory?: 'event' | 'scheduler' | 'webhook' | string;
    /**
     * Task IDs (descriptor types) that can be inserted into this workflow.
     * `allowedTasks` is accepted as an alias for backend payloads that use
     * that name — TemplateRegistry.register() normalises them.
     */
    availableTasks?: string[];
    allowedTasks?: string[];
    maxTasks?: number;
    taskLabels?: Record<string, string>;
    fixedNodes?: FixedNode[];
    fixedEdges?: FixedEdge[];
    insertionPoints?: string[];
    source?: string;
    product?: string;
    /** Pre-built workflow state to clone when user selects this template */
    skeletonState?: WorkflowState;
    /** Tags for filtering in the template library */
    tags?: string[];
    /** Category grouping in the library */
    category?: string;
    /** Team or author that owns this template */
    author?: string;
    /** Relative popularity score (higher = shown first in library) */
    popularity?: number;
}

export { }
