import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, HostListener, Output, inject, } from '@angular/core';
import { Subject, takeUntil } from 'rxjs';
import { LogError } from '@memberjunction/core';
import { MJNotificationService } from '@memberjunction/ng-notifications';
import { ComponentStudioStateService } from '../../services/component-studio-state.service';
import { generateCodeFromCanvas } from '../../services/canvas-to-code';
import { parseCanvasFromCode } from '../../services/code-to-canvas';
import { buildEmptyCanvas, generateCanvasId, } from '../../services/form-canvas-model';
import * as i0 from "@angular/core";
import * as i1 from "./form-builder-canvas.component";
const _forTrack0 = ($index, $item) => $item.Name;
function FormBuilderTabComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵtext(0);
} if (rf & 2) {
    const ctx_r0 = i0.ɵɵnextContext();
    i0.ɵɵtextInterpolate1(" ", ctx_r0.state.FormTargetEntityName, " ");
} }
function FormBuilderTabComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "em");
    i0.ɵɵtext(1, "Pick entity\u2026");
    i0.ɵɵelementEnd();
} }
function FormBuilderTabComponent_Conditional_10_For_4_Conditional_0_Template(rf, ctx) { if (rf & 1) {
    const _r3 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "li", 27);
    i0.ɵɵlistener("click", function FormBuilderTabComponent_Conditional_10_For_4_Conditional_0_Template_li_click_0_listener() { i0.ɵɵrestoreView(_r3); const e_r4 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnEntityPicked(e_r4.Name)); });
    i0.ɵɵelementStart(1, "span", 28);
    i0.ɵɵtext(2);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(3, "span", 29);
    i0.ɵɵtext(4);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const e_r4 = i0.ɵɵnextContext().$implicit;
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(e_r4.DisplayName);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(e_r4.Name);
} }
function FormBuilderTabComponent_Conditional_10_For_4_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵconditionalCreate(0, FormBuilderTabComponent_Conditional_10_For_4_Conditional_0_Template, 5, 2, "li", 26);
} if (rf & 2) {
    const ɵ$index_30_r5 = ctx.$index;
    i0.ɵɵconditional(ɵ$index_30_r5 < 50 ? 0 : -1);
} }
function FormBuilderTabComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
    const _r2 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "div", 23);
    i0.ɵɵlistener("click", function FormBuilderTabComponent_Conditional_10_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r2); return i0.ɵɵresetView($event.stopPropagation()); });
    i0.ɵɵelementStart(1, "input", 24);
    i0.ɵɵlistener("input", function FormBuilderTabComponent_Conditional_10_Template_input_input_1_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnEntityPickerSearch($event)); });
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(2, "ul", 25);
    i0.ɵɵrepeaterCreate(3, FormBuilderTabComponent_Conditional_10_For_4_Template, 1, 1, null, null, _forTrack0);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const ctx_r0 = i0.ɵɵnextContext();
    i0.ɵɵadvance();
    i0.ɵɵproperty("value", ctx_r0.EntityPickerSearch);
    i0.ɵɵadvance(2);
    i0.ɵɵrepeater(ctx_r0.filteredEntityChoices);
} }
function FormBuilderTabComponent_Conditional_30_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 22);
    i0.ɵɵelement(1, "i", 30);
    i0.ɵɵelementStart(2, "h3");
    i0.ɵɵtext(3, "Pick an entity to start the form");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(4, "p");
    i0.ɵɵtext(5, "Choose the target entity from the toolbar. Form Studio loads the curated schema and lets you drag fields onto the canvas.");
    i0.ɵɵelementEnd()();
} }
function FormBuilderTabComponent_Conditional_31_Conditional_0_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 31);
    i0.ɵɵelement(1, "i", 33);
    i0.ɵɵtext(2, " Some parts of this form's code can't be represented on the canvas. Edit them in the Code tab to avoid losing them. ");
    i0.ɵɵelementEnd();
} }
function FormBuilderTabComponent_Conditional_31_Template(rf, ctx) { if (rf & 1) {
    const _r6 = i0.ɵɵgetCurrentView();
    i0.ɵɵconditionalCreate(0, FormBuilderTabComponent_Conditional_31_Conditional_0_Template, 3, 0, "div", 31);
    i0.ɵɵelementStart(1, "mj-form-builder-canvas", 32);
    i0.ɵɵlistener("CanvasChanged", function FormBuilderTabComponent_Conditional_31_Template_mj_form_builder_canvas_CanvasChanged_1_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnCanvasChanged($event)); })("ElementSelected", function FormBuilderTabComponent_Conditional_31_Template_mj_form_builder_canvas_ElementSelected_1_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnElementSelected($event)); })("SectionSelected", function FormBuilderTabComponent_Conditional_31_Template_mj_form_builder_canvas_SectionSelected_1_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnSectionSelected($event)); })("Deselected", function FormBuilderTabComponent_Conditional_31_Template_mj_form_builder_canvas_Deselected_1_listener() { i0.ɵɵrestoreView(_r6); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnDeselected()); });
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r0 = i0.ɵɵnextContext();
    i0.ɵɵconditional(ctx_r0.state.FormCodeOnlySectionsDetected ? 0 : -1);
    i0.ɵɵadvance();
    i0.ɵɵproperty("Canvas", ctx_r0.state.FormCanvas)("Schema", ctx_r0.state.FormSchema)("SelectedElementId", ctx_r0.state.FormSelectedElementId)("SelectedSectionId", ctx_r0.state.FormSelectedSectionId);
} }
/**
 * Form Builder tab — the visual drag-and-drop canvas surface that appears
 * in Component Studio's editor-tabs strip when the active spec is form-role.
 *
 * The canvas is the source-of-truth while this tab is active. On save, the
 * dashboard serialises the canvas to JSX via `generateCodeFromCanvas` and
 * pushes that into `state.EditableCode`. When the user opens an existing
 * form-role Component, `parseCanvasFromCode` reconstructs the canvas
 * (lossily) from the stored code; if the round-trip is too lossy, we leave
 * the canvas empty and steer the user toward the Code tab.
 *
 * The component is presentational where it can be — the heavy state
 * (canvas, schema, selection, preview mode) lives on
 * `ComponentStudioStateService`. This keeps the right-panel and the live
 * preview pane in sync with whatever the user is doing in here.
 */
export class FormBuilderTabComponent {
    /** Notifies the parent (dashboard) that the user wants to switch to the Code tab. */
    RequestCodeTab = new EventEmitter();
    /** Fired separately for the dashboard's NavigationService bridge. */
    OpenInChatRequested = new EventEmitter();
    IsEntityPickerOpen = false;
    EntityPickerSearch = '';
    EntityChoices = [];
    state = inject(ComponentStudioStateService);
    cdr = inject(ChangeDetectorRef);
    notifications = inject(MJNotificationService);
    destroy$ = new Subject();
    // ------------------------------------------------------------------
    // Lifecycle
    // ------------------------------------------------------------------
    ngOnInit() {
        this.state.StateChanged.pipe(takeUntil(this.destroy$)).subscribe(() => {
            this.cdr.markForCheck();
        });
        // Lazily hydrate the canvas if we have a target entity but no canvas
        // (typical when the user lands here from the Code tab).
        this.hydrateCanvasFromState();
        this.refreshEntityChoices();
    }
    ngOnDestroy() {
        this.destroy$.next();
        this.destroy$.complete();
    }
    // ------------------------------------------------------------------
    // Entity picker
    // ------------------------------------------------------------------
    ToggleEntityPicker() {
        this.IsEntityPickerOpen = !this.IsEntityPickerOpen;
        if (this.IsEntityPickerOpen)
            this.refreshEntityChoices();
        this.cdr.markForCheck();
    }
    OnEntityPickerSearch(event) {
        this.EntityPickerSearch = event.target.value;
        this.cdr.markForCheck();
    }
    OnEntityPicked(entityName) {
        this.IsEntityPickerOpen = false;
        const schema = this.state.BuildFormSchema(entityName);
        if (!schema) {
            this.notifications.CreateSimpleNotification(`Couldn't load schema for ${entityName}.`, 'error', 4000);
            return;
        }
        this.state.FormTargetEntityName = entityName;
        // Try to seed canvas from existing code first; otherwise start empty.
        const existing = this.state.EditableCode ?? '';
        if (existing.length > 0) {
            const result = parseCanvasFromCode(existing, schema);
            if (result.canvas) {
                this.state.FormCanvas = result.canvas;
                this.state.FormCodeOnlySectionsDetected = result.hasUnknownConstructs;
            }
            else {
                this.state.FormCanvas = buildEmptyCanvas(entityName, schema.displayName);
                this.state.FormCodeOnlySectionsDetected = true;
            }
        }
        else {
            this.state.FormCanvas = buildEmptyCanvas(entityName, schema.displayName);
            this.state.FormCodeOnlySectionsDetected = false;
        }
        this.state.FormSelectedElementId = null;
        this.state.FormSelectedSectionId = this.state.FormCanvas?.sections[0]?.id ?? null;
        this.regenerateCode();
        this.cdr.markForCheck();
    }
    get filteredEntityChoices() {
        const q = this.EntityPickerSearch.trim().toLowerCase();
        if (!q)
            return this.EntityChoices;
        return this.EntityChoices.filter(e => e.Name.toLowerCase().includes(q) ||
            e.DisplayName.toLowerCase().includes(q));
    }
    refreshEntityChoices() {
        const provider = this.state.Provider;
        if (!provider) {
            this.EntityChoices = [];
            return;
        }
        this.EntityChoices = (provider.Entities ?? [])
            .filter(e => e.AllowCreateAPI || e.AllowUpdateAPI)
            .map(e => ({ Name: e.Name, DisplayName: e.DisplayName ?? e.Name }))
            .sort((a, b) => a.DisplayName.localeCompare(b.DisplayName));
    }
    // ------------------------------------------------------------------
    // Preview-mode pills (synced with state.FormPreviewMode)
    // ------------------------------------------------------------------
    SetPreviewMode(mode) {
        this.state.FormPreviewMode = mode;
    }
    // ------------------------------------------------------------------
    // Canvas events
    // ------------------------------------------------------------------
    OnCanvasChanged(next) {
        this.state.FormCanvas = next;
        this.state.HasUnsavedChanges = true;
        this.regenerateCode();
    }
    OnElementSelected(payload) {
        this.state.FormSelectedSectionId = null;
        this.state.FormSelectedElementId = payload.elementId;
    }
    OnSectionSelected(sectionId) {
        this.state.FormSelectedElementId = null;
        this.state.FormSelectedSectionId = sectionId;
    }
    OnDeselected() {
        this.state.FormSelectedElementId = null;
        this.state.FormSelectedSectionId = null;
    }
    OnElementChanged(next) {
        const canvas = this.state.FormCanvas;
        if (!canvas)
            return;
        const updated = {
            ...canvas,
            sections: canvas.sections.map(s => ({
                ...s,
                elements: s.elements.map(e => e.id === next.id ? next : e),
            })),
        };
        this.OnCanvasChanged(updated);
    }
    OnSectionChanged(next) {
        const canvas = this.state.FormCanvas;
        if (!canvas)
            return;
        const updated = {
            ...canvas,
            sections: canvas.sections.map(s => s.id === next.id ? next : s),
        };
        this.OnCanvasChanged(updated);
    }
    OnElementDeleted(elementId) {
        const canvas = this.state.FormCanvas;
        if (!canvas)
            return;
        const updated = {
            ...canvas,
            sections: canvas.sections.map(s => ({
                ...s,
                elements: s.elements.filter(e => e.id !== elementId),
            })),
        };
        this.state.FormSelectedElementId = null;
        this.OnCanvasChanged(updated);
    }
    OnSectionDeleted(sectionId) {
        const canvas = this.state.FormCanvas;
        if (!canvas)
            return;
        const updated = {
            ...canvas,
            sections: canvas.sections.filter(s => s.id !== sectionId),
        };
        this.state.FormSelectedSectionId = null;
        this.OnCanvasChanged(updated);
    }
    OnFieldAddedFromPalette(payload) {
        const canvas = this.state.FormCanvas;
        if (!canvas)
            return;
        const target = this.findFocusedSection(canvas);
        if (!target)
            return;
        const updated = {
            ...canvas,
            sections: canvas.sections.map(s => s.id === target.id
                ? { ...s, elements: [...s.elements, {
                            id: generateCanvasId('field'),
                            type: 'field',
                            fieldName: payload.fieldName,
                            span: 1,
                        }] }
                : s),
        };
        this.OnCanvasChanged(updated);
    }
    findFocusedSection(canvas) {
        if (this.state.FormSelectedSectionId) {
            const s = canvas.sections.find(s => s.id === this.state.FormSelectedSectionId);
            if (s)
                return s;
        }
        if (this.state.FormSelectedElementId) {
            const s = canvas.sections.find(sec => sec.elements.some(e => e.id === this.state.FormSelectedElementId));
            if (s)
                return s;
        }
        return canvas.sections[0] ?? null;
    }
    // ------------------------------------------------------------------
    // Open in Chat
    // ------------------------------------------------------------------
    /**
     * Bubble up — the dashboard wires up `navigationService.SetAgentContext`
     * via the state event because we don't extend BaseResourceComponent
     * here. The tab also fires a local Output for the editor-tabs parent in
     * case it wants to react.
     */
    OnOpenInChat() {
        this.OpenInChatRequested.emit();
        this.state.OpenInChatRequested.emit();
    }
    // ------------------------------------------------------------------
    // View Code toggle
    // ------------------------------------------------------------------
    OnViewCode() {
        // Make sure the latest canvas is reflected in code before switching.
        this.regenerateCode();
        this.RequestCodeTab.emit();
    }
    // ------------------------------------------------------------------
    // Keyboard
    // ------------------------------------------------------------------
    OnKeyDown(event) {
        const target = event.target;
        const isInput = target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable;
        if (event.key === 'Delete' && !isInput && this.state.FormSelectedElementId) {
            this.OnElementDeleted(this.state.FormSelectedElementId);
        }
        if (event.key === 'Escape' && !isInput) {
            this.OnDeselected();
        }
    }
    // ------------------------------------------------------------------
    // Helpers
    // ------------------------------------------------------------------
    /**
     * Build a fresh canvas if the spec already has a target entity but no
     * canvas yet (e.g. tab activated for the first time). Best-effort — if
     * the spec's code is too lossy to parse, we leave the canvas empty and
     * show a banner.
     */
    hydrateCanvasFromState() {
        const entity = this.state.FormTargetEntityName;
        if (!entity || this.state.FormCanvas)
            return;
        const schema = this.state.BuildFormSchema(entity);
        if (!schema)
            return;
        const existing = this.state.EditableCode ?? '';
        if (existing.length > 0) {
            const result = parseCanvasFromCode(existing, schema);
            if (result.canvas) {
                this.state.FormCanvas = result.canvas;
                this.state.FormCodeOnlySectionsDetected = result.hasUnknownConstructs;
                return;
            }
        }
        this.state.FormCanvas = buildEmptyCanvas(entity, schema.displayName);
    }
    /**
     * Mirror the canvas into ComponentStudioStateService.EditableCode so the
     * Code tab, the preview, and the eventual Save flow all see the same
     * source. Quietly no-op if we don't have enough to render.
     */
    regenerateCode() {
        try {
            const canvas = this.state.FormCanvas;
            const schema = this.state.FormSchema;
            if (!canvas || !schema)
                return;
            const name = canvas.title?.trim() || schema.displayName;
            const code = generateCodeFromCanvas(canvas, schema, name);
            this.state.EditableCode = code;
        }
        catch (err) {
            LogError(`FormBuilderTab.regenerateCode: ${err instanceof Error ? err.message : String(err)}`);
        }
    }
    static ɵfac = function FormBuilderTabComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || FormBuilderTabComponent)(); };
    static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: FormBuilderTabComponent, selectors: [["mj-form-builder-tab"]], hostBindings: function FormBuilderTabComponent_HostBindings(rf, ctx) { if (rf & 1) {
            i0.ɵɵlistener("keydown", function FormBuilderTabComponent_keydown_HostBindingHandler($event) { return ctx.OnKeyDown($event); }, i0.ɵɵresolveDocument);
        } }, outputs: { RequestCodeTab: "RequestCodeTab", OpenInChatRequested: "OpenInChatRequested" }, standalone: false, decls: 32, vars: 12, consts: [[1, "form-builder-tab"], [1, "fbt-toolbar"], [1, "fbt-toolbar-left"], [1, "fbt-entity-picker"], [1, "fbt-entity-btn", 3, "click"], [1, "fa-solid", "fa-table"], [1, "fa-solid", "fa-chevron-down", "chev"], [1, "fbt-entity-popover"], ["role", "radiogroup", "aria-label", "Preview mode", 1, "fbt-mode-pills"], ["title", "View mode \u2014 read-only", 1, "fbt-mode-pill", 3, "click"], [1, "fa-solid", "fa-eye"], ["title", "Edit mode \u2014 fields editable", 1, "fbt-mode-pill", 3, "click"], [1, "fa-solid", "fa-pen"], ["title", "Create mode \u2014 empty record", 1, "fbt-mode-pill", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "fbt-toolbar-spacer"], [1, "fbt-toolbar-right"], ["title", "View generated code", 1, "fbt-tool-btn", 3, "click"], [1, "fa-solid", "fa-code"], ["title", "Hand off the current canvas to the chat agent", 1, "fbt-tool-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-comment-dots"], [1, "fbt-canvas-host"], [1, "fbt-empty"], [1, "fbt-entity-popover", 3, "click"], ["type", "text", "placeholder", "Search entities\u2026", 1, "fbt-entity-search", 3, "input", "value"], [1, "fbt-entity-list"], [1, "fbt-entity-item"], [1, "fbt-entity-item", 3, "click"], [1, "fbt-entity-display"], [1, "fbt-entity-name"], [1, "fa-solid", "fa-table-list"], ["role", "alert", 1, "fbt-lossy-banner"], [3, "CanvasChanged", "ElementSelected", "SectionSelected", "Deselected", "Canvas", "Schema", "SelectedElementId", "SelectedSectionId"], [1, "fa-solid", "fa-triangle-exclamation"]], template: function FormBuilderTabComponent_Template(rf, ctx) { if (rf & 1) {
            i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "div", 3)(4, "button", 4);
            i0.ɵɵlistener("click", function FormBuilderTabComponent_Template_button_click_4_listener() { return ctx.ToggleEntityPicker(); });
            i0.ɵɵelement(5, "i", 5);
            i0.ɵɵelementStart(6, "span");
            i0.ɵɵconditionalCreate(7, FormBuilderTabComponent_Conditional_7_Template, 1, 1)(8, FormBuilderTabComponent_Conditional_8_Template, 2, 0, "em");
            i0.ɵɵelementEnd();
            i0.ɵɵelement(9, "i", 6);
            i0.ɵɵelementEnd();
            i0.ɵɵconditionalCreate(10, FormBuilderTabComponent_Conditional_10_Template, 5, 1, "div", 7);
            i0.ɵɵelementEnd();
            i0.ɵɵelementStart(11, "div", 8)(12, "button", 9);
            i0.ɵɵlistener("click", function FormBuilderTabComponent_Template_button_click_12_listener() { return ctx.SetPreviewMode("view"); });
            i0.ɵɵelement(13, "i", 10);
            i0.ɵɵtext(14, " View ");
            i0.ɵɵelementEnd();
            i0.ɵɵelementStart(15, "button", 11);
            i0.ɵɵlistener("click", function FormBuilderTabComponent_Template_button_click_15_listener() { return ctx.SetPreviewMode("edit"); });
            i0.ɵɵelement(16, "i", 12);
            i0.ɵɵtext(17, " Edit ");
            i0.ɵɵelementEnd();
            i0.ɵɵelementStart(18, "button", 13);
            i0.ɵɵlistener("click", function FormBuilderTabComponent_Template_button_click_18_listener() { return ctx.SetPreviewMode("create"); });
            i0.ɵɵelement(19, "i", 14);
            i0.ɵɵtext(20, " Create ");
            i0.ɵɵelementEnd()()();
            i0.ɵɵelement(21, "div", 15);
            i0.ɵɵelementStart(22, "div", 16)(23, "button", 17);
            i0.ɵɵlistener("click", function FormBuilderTabComponent_Template_button_click_23_listener() { return ctx.OnViewCode(); });
            i0.ɵɵelement(24, "i", 18);
            i0.ɵɵtext(25, " View Code ");
            i0.ɵɵelementEnd();
            i0.ɵɵelementStart(26, "button", 19);
            i0.ɵɵlistener("click", function FormBuilderTabComponent_Template_button_click_26_listener() { return ctx.OnOpenInChat(); });
            i0.ɵɵelement(27, "i", 20);
            i0.ɵɵtext(28, " Open in Chat ");
            i0.ɵɵelementEnd()()();
            i0.ɵɵelementStart(29, "div", 21);
            i0.ɵɵconditionalCreate(30, FormBuilderTabComponent_Conditional_30_Template, 6, 0, "div", 22)(31, FormBuilderTabComponent_Conditional_31_Template, 2, 5);
            i0.ɵɵelementEnd()();
        } if (rf & 2) {
            i0.ɵɵadvance(3);
            i0.ɵɵclassProp("open", ctx.IsEntityPickerOpen);
            i0.ɵɵadvance(4);
            i0.ɵɵconditional(ctx.state.FormTargetEntityName ? 7 : 8);
            i0.ɵɵadvance(3);
            i0.ɵɵconditional(ctx.IsEntityPickerOpen ? 10 : -1);
            i0.ɵɵadvance(2);
            i0.ɵɵclassProp("active", ctx.state.FormPreviewMode === "view");
            i0.ɵɵadvance(3);
            i0.ɵɵclassProp("active", ctx.state.FormPreviewMode === "edit");
            i0.ɵɵadvance(3);
            i0.ɵɵclassProp("active", ctx.state.FormPreviewMode === "create");
            i0.ɵɵadvance(8);
            i0.ɵɵproperty("disabled", !ctx.state.FormCanvas);
            i0.ɵɵadvance(4);
            i0.ɵɵconditional(!ctx.state.FormTargetEntityName ? 30 : 31);
        } }, dependencies: [i1.FormBuilderCanvasComponent], styles: ["[_nghost-%COMP%] {\n    display: flex;\n    flex: 1;\n    overflow: hidden;\n}\n\n.form-builder-tab[_ngcontent-%COMP%] {\n    display: flex;\n    flex-direction: column;\n    flex: 1;\n    overflow: hidden;\n    background: var(--mj-bg-page);\n}\n\n\n\n\n\n.fbt-toolbar[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    gap: 12px;\n    padding: 8px 12px;\n    background: var(--mj-bg-surface);\n    border-bottom: 1px solid var(--mj-border-default);\n    flex-shrink: 0;\n}\n\n.fbt-toolbar-left[_ngcontent-%COMP%], \n.fbt-toolbar-right[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    gap: 8px;\n}\n\n.fbt-toolbar-spacer[_ngcontent-%COMP%] {\n    flex: 1;\n}\n\n\n\n\n\n.fbt-entity-picker[_ngcontent-%COMP%] {\n    position: relative;\n}\n\n.fbt-entity-btn[_ngcontent-%COMP%] {\n    display: inline-flex;\n    align-items: center;\n    gap: 8px;\n    padding: 6px 12px;\n    background: var(--mj-bg-surface-card);\n    border: 1px solid var(--mj-border-default);\n    border-radius: 6px;\n    color: var(--mj-text-primary);\n    font-size: 13px;\n    cursor: pointer;\n    font-family: inherit;\n    transition: background 0.15s ease;\n}\n\n.fbt-entity-btn[_ngcontent-%COMP%]:hover {\n    background: var(--mj-bg-surface-hover);\n}\n\n.fbt-entity-btn[_ngcontent-%COMP%]   em[_ngcontent-%COMP%] {\n    color: var(--mj-text-muted);\n    font-style: italic;\n}\n\n.fbt-entity-btn[_ngcontent-%COMP%]   .chev[_ngcontent-%COMP%] {\n    font-size: 10px;\n    color: var(--mj-text-muted);\n}\n\n.fbt-entity-popover[_ngcontent-%COMP%] {\n    position: absolute;\n    top: calc(100% + 4px);\n    left: 0;\n    width: 320px;\n    max-height: 360px;\n    background: var(--mj-bg-surface);\n    border: 1px solid var(--mj-border-default);\n    border-radius: 6px;\n    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);\n    z-index: 30;\n    display: flex;\n    flex-direction: column;\n    overflow: hidden;\n}\n\n.fbt-entity-search[_ngcontent-%COMP%] {\n    padding: 8px 10px;\n    border: none;\n    border-bottom: 1px solid var(--mj-border-default);\n    background: var(--mj-bg-surface);\n    color: var(--mj-text-primary);\n    font-size: 13px;\n    font-family: inherit;\n    outline: none;\n}\n\n.fbt-entity-search[_ngcontent-%COMP%]:focus {\n    background: var(--mj-bg-surface-hover);\n}\n\n.fbt-entity-list[_ngcontent-%COMP%] {\n    list-style: none;\n    margin: 0;\n    padding: 4px;\n    overflow-y: auto;\n    flex: 1;\n}\n\n.fbt-entity-item[_ngcontent-%COMP%] {\n    display: flex;\n    flex-direction: column;\n    gap: 2px;\n    padding: 6px 10px;\n    border-radius: 4px;\n    cursor: pointer;\n    transition: background 0.1s ease;\n}\n\n.fbt-entity-item[_ngcontent-%COMP%]:hover {\n    background: var(--mj-bg-surface-hover);\n}\n\n.fbt-entity-display[_ngcontent-%COMP%] {\n    font-size: 13px;\n    color: var(--mj-text-primary);\n    font-weight: 500;\n}\n\n.fbt-entity-name[_ngcontent-%COMP%] {\n    font-size: 11px;\n    color: var(--mj-text-muted);\n}\n\n\n\n\n\n.fbt-mode-pills[_ngcontent-%COMP%] {\n    display: inline-flex;\n    background: var(--mj-bg-surface-sunken);\n    border: 1px solid var(--mj-border-default);\n    border-radius: 6px;\n    overflow: hidden;\n}\n\n.fbt-mode-pill[_ngcontent-%COMP%] {\n    display: inline-flex;\n    align-items: center;\n    gap: 5px;\n    padding: 5px 12px;\n    background: transparent;\n    border: none;\n    color: var(--mj-text-secondary);\n    font-size: 12px;\n    font-family: inherit;\n    cursor: pointer;\n    transition: all 0.15s ease;\n    border-right: 1px solid var(--mj-border-default);\n}\n\n.fbt-mode-pill[_ngcontent-%COMP%]:last-child {\n    border-right: none;\n}\n\n.fbt-mode-pill[_ngcontent-%COMP%]:hover {\n    background: var(--mj-bg-surface-hover);\n    color: var(--mj-text-primary);\n}\n\n.fbt-mode-pill.active[_ngcontent-%COMP%] {\n    background: var(--mj-bg-surface);\n    color: var(--mj-brand-primary);\n    font-weight: 600;\n}\n\n\n\n\n\n.fbt-tool-btn[_ngcontent-%COMP%] {\n    display: inline-flex;\n    align-items: center;\n    gap: 6px;\n    padding: 6px 12px;\n    background: var(--mj-bg-surface-card);\n    border: 1px solid var(--mj-border-default);\n    border-radius: 6px;\n    color: var(--mj-text-primary);\n    font-size: 12px;\n    font-family: inherit;\n    cursor: pointer;\n    transition: background 0.15s ease;\n}\n\n.fbt-tool-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n    background: var(--mj-bg-surface-hover);\n}\n\n.fbt-tool-btn[_ngcontent-%COMP%]:disabled {\n    opacity: 0.5;\n    cursor: not-allowed;\n}\n\n\n\n\n\n.fbt-canvas-host[_ngcontent-%COMP%] {\n    flex: 1;\n    overflow: auto;\n    padding: 16px;\n    display: flex;\n    flex-direction: column;\n    gap: 12px;\n}\n\n.fbt-canvas-host[_ngcontent-%COMP%]    > mj-form-builder-canvas[_ngcontent-%COMP%] {\n    flex: 1;\n    display: flex;\n    flex-direction: column;\n}\n\n.fbt-empty[_ngcontent-%COMP%] {\n    flex: 1;\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    justify-content: center;\n    gap: 12px;\n    text-align: center;\n    color: var(--mj-text-muted);\n    padding: 48px;\n}\n\n.fbt-empty[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] {\n    font-size: 36px;\n    color: var(--mj-text-disabled);\n}\n\n.fbt-empty[_ngcontent-%COMP%]   h3[_ngcontent-%COMP%] {\n    margin: 0;\n    font-size: 16px;\n    color: var(--mj-text-primary);\n}\n\n.fbt-empty[_ngcontent-%COMP%]   p[_ngcontent-%COMP%] {\n    margin: 0;\n    max-width: 380px;\n    font-size: 13px;\n    line-height: 1.5;\n}\n\n.fbt-lossy-banner[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    gap: 8px;\n    padding: 8px 12px;\n    background: var(--mj-status-warning-bg);\n    color: var(--mj-status-warning-text);\n    border: 1px solid var(--mj-status-warning-border);\n    border-radius: 6px;\n    font-size: 12px;\n}"], changeDetection: 0 });
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FormBuilderTabComponent, [{
        type: Component,
        args: [{ standalone: false, selector: 'mj-form-builder-tab', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"form-builder-tab\">\n\n  <!-- ============================================================\n       TOP TOOLBAR \u2014 entity picker, mode pills, code & chat handoff\n       ============================================================ -->\n  <div class=\"fbt-toolbar\">\n    <div class=\"fbt-toolbar-left\">\n      <!-- Entity picker -->\n      <div class=\"fbt-entity-picker\" [class.open]=\"IsEntityPickerOpen\">\n        <button class=\"fbt-entity-btn\" (click)=\"ToggleEntityPicker()\">\n          <i class=\"fa-solid fa-table\"></i>\n          <span>\n            @if (state.FormTargetEntityName) {\n              {{ state.FormTargetEntityName }}\n            } @else {\n              <em>Pick entity\u2026</em>\n            }\n          </span>\n          <i class=\"fa-solid fa-chevron-down chev\"></i>\n        </button>\n        @if (IsEntityPickerOpen) {\n          <div class=\"fbt-entity-popover\" (click)=\"$event.stopPropagation()\">\n            <input type=\"text\"\n                   class=\"fbt-entity-search\"\n                   placeholder=\"Search entities\u2026\"\n                   [value]=\"EntityPickerSearch\"\n                   (input)=\"OnEntityPickerSearch($event)\" />\n            <ul class=\"fbt-entity-list\">\n              @for (e of filteredEntityChoices; track e.Name; let idx = $index) {\n                @if (idx < 50) {\n                  <li class=\"fbt-entity-item\" (click)=\"OnEntityPicked(e.Name)\">\n                    <span class=\"fbt-entity-display\">{{ e.DisplayName }}</span>\n                    <span class=\"fbt-entity-name\">{{ e.Name }}</span>\n                  </li>\n                }\n              }\n            </ul>\n          </div>\n        }\n      </div>\n\n      <!-- Mode pills -->\n      <div class=\"fbt-mode-pills\" role=\"radiogroup\" aria-label=\"Preview mode\">\n        <button class=\"fbt-mode-pill\"\n                [class.active]=\"state.FormPreviewMode === 'view'\"\n                (click)=\"SetPreviewMode('view')\"\n                title=\"View mode \u2014 read-only\">\n          <i class=\"fa-solid fa-eye\"></i> View\n        </button>\n        <button class=\"fbt-mode-pill\"\n                [class.active]=\"state.FormPreviewMode === 'edit'\"\n                (click)=\"SetPreviewMode('edit')\"\n                title=\"Edit mode \u2014 fields editable\">\n          <i class=\"fa-solid fa-pen\"></i> Edit\n        </button>\n        <button class=\"fbt-mode-pill\"\n                [class.active]=\"state.FormPreviewMode === 'create'\"\n                (click)=\"SetPreviewMode('create')\"\n                title=\"Create mode \u2014 empty record\">\n          <i class=\"fa-solid fa-plus\"></i> Create\n        </button>\n      </div>\n    </div>\n\n    <div class=\"fbt-toolbar-spacer\"></div>\n\n    <div class=\"fbt-toolbar-right\">\n      <button class=\"fbt-tool-btn\"\n              (click)=\"OnViewCode()\"\n              title=\"View generated code\">\n        <i class=\"fa-solid fa-code\"></i> View Code\n      </button>\n      <button class=\"fbt-tool-btn\"\n              [disabled]=\"!state.FormCanvas\"\n              (click)=\"OnOpenInChat()\"\n              title=\"Hand off the current canvas to the chat agent\">\n        <i class=\"fa-solid fa-comment-dots\"></i> Open in Chat\n      </button>\n    </div>\n  </div>\n\n  <!-- ============================================================\n       CANVAS BODY\n       ============================================================ -->\n  <div class=\"fbt-canvas-host\">\n    @if (!state.FormTargetEntityName) {\n      <div class=\"fbt-empty\">\n        <i class=\"fa-solid fa-table-list\"></i>\n        <h3>Pick an entity to start the form</h3>\n        <p>Choose the target entity from the toolbar. Form Studio loads the curated schema and lets you drag fields onto the canvas.</p>\n      </div>\n    } @else {\n      @if (state.FormCodeOnlySectionsDetected) {\n        <div class=\"fbt-lossy-banner\" role=\"alert\">\n          <i class=\"fa-solid fa-triangle-exclamation\"></i>\n          Some parts of this form's code can't be represented on the canvas. Edit them in the Code tab to avoid losing them.\n        </div>\n      }\n      <mj-form-builder-canvas\n        [Canvas]=\"state.FormCanvas\"\n        [Schema]=\"state.FormSchema\"\n        [SelectedElementId]=\"state.FormSelectedElementId\"\n        [SelectedSectionId]=\"state.FormSelectedSectionId\"\n        (CanvasChanged)=\"OnCanvasChanged($event)\"\n        (ElementSelected)=\"OnElementSelected($event)\"\n        (SectionSelected)=\"OnSectionSelected($event)\"\n        (Deselected)=\"OnDeselected()\">\n      </mj-form-builder-canvas>\n    }\n  </div>\n</div>\n", styles: [":host {\n    display: flex;\n    flex: 1;\n    overflow: hidden;\n}\n\n.form-builder-tab {\n    display: flex;\n    flex-direction: column;\n    flex: 1;\n    overflow: hidden;\n    background: var(--mj-bg-page);\n}\n\n/* ============================================================\n   TOOLBAR\n   ============================================================ */\n.fbt-toolbar {\n    display: flex;\n    align-items: center;\n    gap: 12px;\n    padding: 8px 12px;\n    background: var(--mj-bg-surface);\n    border-bottom: 1px solid var(--mj-border-default);\n    flex-shrink: 0;\n}\n\n.fbt-toolbar-left,\n.fbt-toolbar-right {\n    display: flex;\n    align-items: center;\n    gap: 8px;\n}\n\n.fbt-toolbar-spacer {\n    flex: 1;\n}\n\n/* ============================================================\n   ENTITY PICKER\n   ============================================================ */\n.fbt-entity-picker {\n    position: relative;\n}\n\n.fbt-entity-btn {\n    display: inline-flex;\n    align-items: center;\n    gap: 8px;\n    padding: 6px 12px;\n    background: var(--mj-bg-surface-card);\n    border: 1px solid var(--mj-border-default);\n    border-radius: 6px;\n    color: var(--mj-text-primary);\n    font-size: 13px;\n    cursor: pointer;\n    font-family: inherit;\n    transition: background 0.15s ease;\n}\n\n.fbt-entity-btn:hover {\n    background: var(--mj-bg-surface-hover);\n}\n\n.fbt-entity-btn em {\n    color: var(--mj-text-muted);\n    font-style: italic;\n}\n\n.fbt-entity-btn .chev {\n    font-size: 10px;\n    color: var(--mj-text-muted);\n}\n\n.fbt-entity-popover {\n    position: absolute;\n    top: calc(100% + 4px);\n    left: 0;\n    width: 320px;\n    max-height: 360px;\n    background: var(--mj-bg-surface);\n    border: 1px solid var(--mj-border-default);\n    border-radius: 6px;\n    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);\n    z-index: 30;\n    display: flex;\n    flex-direction: column;\n    overflow: hidden;\n}\n\n.fbt-entity-search {\n    padding: 8px 10px;\n    border: none;\n    border-bottom: 1px solid var(--mj-border-default);\n    background: var(--mj-bg-surface);\n    color: var(--mj-text-primary);\n    font-size: 13px;\n    font-family: inherit;\n    outline: none;\n}\n\n.fbt-entity-search:focus {\n    background: var(--mj-bg-surface-hover);\n}\n\n.fbt-entity-list {\n    list-style: none;\n    margin: 0;\n    padding: 4px;\n    overflow-y: auto;\n    flex: 1;\n}\n\n.fbt-entity-item {\n    display: flex;\n    flex-direction: column;\n    gap: 2px;\n    padding: 6px 10px;\n    border-radius: 4px;\n    cursor: pointer;\n    transition: background 0.1s ease;\n}\n\n.fbt-entity-item:hover {\n    background: var(--mj-bg-surface-hover);\n}\n\n.fbt-entity-display {\n    font-size: 13px;\n    color: var(--mj-text-primary);\n    font-weight: 500;\n}\n\n.fbt-entity-name {\n    font-size: 11px;\n    color: var(--mj-text-muted);\n}\n\n/* ============================================================\n   MODE PILLS\n   ============================================================ */\n.fbt-mode-pills {\n    display: inline-flex;\n    background: var(--mj-bg-surface-sunken);\n    border: 1px solid var(--mj-border-default);\n    border-radius: 6px;\n    overflow: hidden;\n}\n\n.fbt-mode-pill {\n    display: inline-flex;\n    align-items: center;\n    gap: 5px;\n    padding: 5px 12px;\n    background: transparent;\n    border: none;\n    color: var(--mj-text-secondary);\n    font-size: 12px;\n    font-family: inherit;\n    cursor: pointer;\n    transition: all 0.15s ease;\n    border-right: 1px solid var(--mj-border-default);\n}\n\n.fbt-mode-pill:last-child {\n    border-right: none;\n}\n\n.fbt-mode-pill:hover {\n    background: var(--mj-bg-surface-hover);\n    color: var(--mj-text-primary);\n}\n\n.fbt-mode-pill.active {\n    background: var(--mj-bg-surface);\n    color: var(--mj-brand-primary);\n    font-weight: 600;\n}\n\n/* ============================================================\n   RIGHT-SIDE TOOLBAR BUTTONS\n   ============================================================ */\n.fbt-tool-btn {\n    display: inline-flex;\n    align-items: center;\n    gap: 6px;\n    padding: 6px 12px;\n    background: var(--mj-bg-surface-card);\n    border: 1px solid var(--mj-border-default);\n    border-radius: 6px;\n    color: var(--mj-text-primary);\n    font-size: 12px;\n    font-family: inherit;\n    cursor: pointer;\n    transition: background 0.15s ease;\n}\n\n.fbt-tool-btn:hover:not(:disabled) {\n    background: var(--mj-bg-surface-hover);\n}\n\n.fbt-tool-btn:disabled {\n    opacity: 0.5;\n    cursor: not-allowed;\n}\n\n/* ============================================================\n   CANVAS HOST + EMPTY STATE\n   ============================================================ */\n.fbt-canvas-host {\n    flex: 1;\n    overflow: auto;\n    padding: 16px;\n    display: flex;\n    flex-direction: column;\n    gap: 12px;\n}\n\n.fbt-canvas-host > mj-form-builder-canvas {\n    flex: 1;\n    display: flex;\n    flex-direction: column;\n}\n\n.fbt-empty {\n    flex: 1;\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    justify-content: center;\n    gap: 12px;\n    text-align: center;\n    color: var(--mj-text-muted);\n    padding: 48px;\n}\n\n.fbt-empty i {\n    font-size: 36px;\n    color: var(--mj-text-disabled);\n}\n\n.fbt-empty h3 {\n    margin: 0;\n    font-size: 16px;\n    color: var(--mj-text-primary);\n}\n\n.fbt-empty p {\n    margin: 0;\n    max-width: 380px;\n    font-size: 13px;\n    line-height: 1.5;\n}\n\n.fbt-lossy-banner {\n    display: flex;\n    align-items: center;\n    gap: 8px;\n    padding: 8px 12px;\n    background: var(--mj-status-warning-bg);\n    color: var(--mj-status-warning-text);\n    border: 1px solid var(--mj-status-warning-border);\n    border-radius: 6px;\n    font-size: 12px;\n}\n"] }]
    }], null, { RequestCodeTab: [{
            type: Output
        }], OpenInChatRequested: [{
            type: Output
        }], OnKeyDown: [{
            type: HostListener,
            args: ['document:keydown', ['$event']]
        }] }); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(FormBuilderTabComponent, { className: "FormBuilderTabComponent", filePath: "src/ComponentStudio/components/form-builder/form-builder-tab.component.ts", lineNumber: 48 }); })();
//# sourceMappingURL=form-builder-tab.component.js.map