import { __esDecorate, __runInitializers } from "tslib";
import { html } from 'lit';
import { property } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { AmfNamespace } from '@api-client/core/amf/definitions/Namespace.js';
import { ApiSchemaGenerator } from '@api-client/core/amf/ApiSchemaGenerator.js';
import { readPropertyTypeLabel, isScalarUnion, isScalarType } from '../../amf/lib/Utils.js';
import { detailsTemplate, paramNameTemplate, typeValueTemplate, fileDetailsTemplate, scalarDetailsTemplate, unionDetailsTemplate, pillTemplate, } from './SchemaCommonTemplates.js';
import { ApiDocumentationBase } from './ApiDocumentationBase.js';
import { Events } from '../../events/amf/Events.js';
import { chevronRight } from '../../md/icons/Icons.js';
import '../../md/radio/ui-radio.js';
const complexTypes = [
    AmfNamespace.w3.shacl.NodeShape,
    AmfNamespace.aml.vocabularies.shapes.UnionShape,
    AmfNamespace.aml.vocabularies.shapes.ArrayShape,
    AmfNamespace.aml.vocabularies.shapes.TupleShape,
    AmfNamespace.aml.vocabularies.shapes.AnyShape,
];
let ApiSchemaDocument = (() => {
    let _classSuper = ApiDocumentationBase;
    let _mimeType_decorators;
    let _mimeType_initializers = [];
    let _mimeType_extraInitializers = [];
    let _forceExamples_decorators;
    let _forceExamples_initializers = [];
    let _forceExamples_extraInitializers = [];
    let _editProperties_decorators;
    let _editProperties_initializers = [];
    let _editProperties_extraInitializers = [];
    let _schemaTitle_decorators;
    let _schemaTitle_initializers = [];
    let _schemaTitle_extraInitializers = [];
    let _noReadOnly_decorators;
    let _noReadOnly_initializers = [];
    let _noReadOnly_extraInitializers = [];
    return class ApiSchemaDocument extends _classSuper {
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            _mimeType_decorators = [property({ type: String, reflect: true })];
            _forceExamples_decorators = [property({ type: Boolean, reflect: true })];
            _editProperties_decorators = [property({ type: Boolean, reflect: true })];
            _schemaTitle_decorators = [property({ type: Boolean, reflect: true })];
            _noReadOnly_decorators = [property({ type: Boolean, reflect: true })];
            __esDecorate(this, null, _mimeType_decorators, { kind: "accessor", name: "mimeType", static: false, private: false, access: { has: obj => "mimeType" in obj, get: obj => obj.mimeType, set: (obj, value) => { obj.mimeType = value; } }, metadata: _metadata }, _mimeType_initializers, _mimeType_extraInitializers);
            __esDecorate(this, null, _forceExamples_decorators, { kind: "accessor", name: "forceExamples", static: false, private: false, access: { has: obj => "forceExamples" in obj, get: obj => obj.forceExamples, set: (obj, value) => { obj.forceExamples = value; } }, metadata: _metadata }, _forceExamples_initializers, _forceExamples_extraInitializers);
            __esDecorate(this, null, _editProperties_decorators, { kind: "accessor", name: "editProperties", static: false, private: false, access: { has: obj => "editProperties" in obj, get: obj => obj.editProperties, set: (obj, value) => { obj.editProperties = value; } }, metadata: _metadata }, _editProperties_initializers, _editProperties_extraInitializers);
            __esDecorate(this, null, _schemaTitle_decorators, { kind: "accessor", name: "schemaTitle", static: false, private: false, access: { has: obj => "schemaTitle" in obj, get: obj => obj.schemaTitle, set: (obj, value) => { obj.schemaTitle = value; } }, metadata: _metadata }, _schemaTitle_initializers, _schemaTitle_extraInitializers);
            __esDecorate(this, null, _noReadOnly_decorators, { kind: "accessor", name: "noReadOnly", static: false, private: false, access: { has: obj => "noReadOnly" in obj, get: obj => obj.noReadOnly, set: (obj, value) => { obj.noReadOnly = value; } }, metadata: _metadata }, _noReadOnly_initializers, _noReadOnly_extraInitializers);
            if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        }
        #mimeType_accessor_storage = __runInitializers(this, _mimeType_initializers, void 0);
        /**
         * The mime type to use to render the examples.
         * @attribute
         */
        get mimeType() { return this.#mimeType_accessor_storage; }
        set mimeType(value) { this.#mimeType_accessor_storage = value; }
        schemaValue = __runInitializers(this, _mimeType_extraInitializers);
        get schema() {
            return this.schemaValue;
        }
        set schema(value) {
            const old = this.schemaValue;
            if (old === value) {
                return;
            }
            this.schemaValue = value;
            this.processGraph();
        }
        #forceExamples_accessor_storage = __runInitializers(this, _forceExamples_initializers, void 0);
        /**
         * Generates examples from the schema properties for the given mime type
         * when examples are not defined in the schema.
         * @attribute
         */
        get forceExamples() { return this.#forceExamples_accessor_storage; }
        set forceExamples(value) { this.#forceExamples_accessor_storage = value; }
        #editProperties_accessor_storage = (__runInitializers(this, _forceExamples_extraInitializers), __runInitializers(this, _editProperties_initializers, void 0));
        /**
         * When set it allows to manipulate the properties.
         * This is to be used with a combination with the `edit` property.
         * @attribute
         */
        get editProperties() { return this.#editProperties_accessor_storage; }
        set editProperties(value) { this.#editProperties_accessor_storage = value; }
        #schemaTitle_accessor_storage = (__runInitializers(this, _editProperties_extraInitializers), __runInitializers(this, _schemaTitle_initializers, void 0));
        /**
         * When set it renders the title with lower emphasis and adding `schema` prefix.
         * @attribute
         */
        get schemaTitle() { return this.#schemaTitle_accessor_storage; }
        set schemaTitle(value) { this.#schemaTitle_accessor_storage = value; }
        #noReadOnly_accessor_storage = (__runInitializers(this, _schemaTitle_extraInitializers), __runInitializers(this, _noReadOnly_initializers, void 0));
        /**
         * When set it does not render read only items.
         * Read only property is a feature of OAS.
         * @attribute
         */
        get noReadOnly() { return this.#noReadOnly_accessor_storage; }
        set noReadOnly(value) { this.#noReadOnly_accessor_storage = value; }
        expandedValue = __runInitializers(this, _noReadOnly_extraInitializers);
        get expanded() {
            return this.expandedValue;
        }
        selectedUnionsValue;
        get selectedUnions() {
            return this.selectedUnionsValue;
        }
        propertyDescriptionEditor;
        constructor() {
            super();
            this.expandedValue = [];
            this.selectedUnionsValue = {};
        }
        willUpdate(cp) {
            super.willUpdate(cp);
            if (cp.has('mimeType') || cp.has('forceExamples')) {
                this.processSchema();
            }
        }
        async processGraph() {
            this.expandedValue = [];
            this.selectedUnionsValue = {};
            await this.querySchema();
            this.processSchema();
            this.requestUpdate();
            await this.updateComplete;
        }
        /**
         * Queries the store for the schema data, when needed.
         */
        async querySchema() {
            const { domainId } = this;
            if (!domainId) {
                // this.schemaValue = undefined;
                return;
            }
            if (this.schemaValue && this.schemaValue.id === domainId) {
                // in case the schema model was provided via the property setter.
                return;
            }
            try {
                const info = await Events.Type.get(this, domainId);
                this.schemaValue = info;
            }
            catch (e) {
                const ex = e;
                Events.Telemetry.exception(this, ex.message, false);
                Events.Reporting.error(this, ex, `Unable to query for API schema data: ${ex.message}`, this.localName);
            }
        }
        /**
         * The logic to perform after schema is ready.
         * This processes examples for the schema.
         */
        processSchema() {
            const type = this.schemaValue;
            if (!type) {
                this.examplesValue = undefined;
                return;
            }
            if (isScalarType(type.types)) {
                // we don't want to render examples for a scalar types.
                this.examplesValue = undefined;
                return;
            }
            const anyShape = type;
            const { examples = [] } = anyShape;
            let examplesCopy = [...examples];
            if (Array.isArray(type.inherits) && type.inherits.length) {
                type.inherits.forEach((item) => {
                    const anyParent = item;
                    if (Array.isArray(anyParent.examples) && anyParent.examples.length) {
                        examplesCopy = examplesCopy.concat([...anyParent.examples]);
                    }
                });
            }
            if (Array.isArray(examplesCopy) && examplesCopy.length) {
                examplesCopy = examplesCopy.filter((i) => !!i.value || !!i.structuredValue);
            }
            if (Array.isArray(examplesCopy) && examplesCopy.length) {
                const { mimeType = '' } = this;
                this.examplesValue = this.evaluateExamples(examplesCopy, mimeType);
            }
            else {
                const { mimeType, forceExamples } = this;
                this.examplesValue = undefined;
                if (mimeType && forceExamples) {
                    const selectedUnions = [];
                    const all = this.selectedUnionsValue;
                    Object.keys(all).forEach((id) => {
                        if (!selectedUnions.includes(all[id])) {
                            selectedUnions.push(all[id]);
                        }
                    });
                    const result = ApiSchemaGenerator.asExample(type, mimeType, {
                        selectedUnions,
                        renderExamples: true,
                        renderOptional: true,
                    });
                    if (result) {
                        this.examplesValue = [result];
                    }
                }
            }
        }
        // /**
        //  * Checks the current schema whether it contains a property with the given id
        //  * and if so it updates its value.
        //  * @param {ApiShapeUnion} schema
        //  * @param {string} id
        //  * @param {any} updated
        //  */
        // [checkSchemaPropertyUpdate](schema: IShapeUnion, id: string, updated): void {
        //   if (!schema) {
        //     return;
        //   }
        //   const { types } = schema;
        //   if (types.includes(AmfNamespace.w3.shacl.NodeShape)) {
        //     const type = /** @type ApiNodeShape */ (schema);
        //     const { properties } = type;
        //     for (let i = 0, len = properties.length; i < len; i++) {
        //       const property = properties[i];
        //       if (property.id === id) {
        //         properties[i] = updated;
        //         this.requestUpdate();
        //         return;
        //       }
        //       if (property.range && property.range.id === id) {
        //         property.range = updated;
        //         this.requestUpdate();
        //         return;
        //       }
        //     }
        //     return;
        //   }
        //   if (types.includes(AmfNamespace.aml.vocabularies.shapes.UnionShape)) {
        //     const type = /** @type ApiUnionShape */ (schema);
        //     const { anyOf, or, and } = type;
        //     if (Array.isArray(anyOf) && anyOf.length) {
        //       anyOf.forEach((item) => this[checkSchemaPropertyUpdate](item, id, updated));
        //     }
        //     if (Array.isArray(or) && or.length) {
        //       or.forEach((item) => this[checkSchemaPropertyUpdate](item, id, updated));
        //     }
        //     if (Array.isArray(and) && and.length) {
        //       and.forEach((item) => this[checkSchemaPropertyUpdate](item, id, updated));
        //     }
        //     return;
        //   }
        //   if (types.includes(AmfNamespace.aml.vocabularies.shapes.ArrayShape) ||
        //      types.includes(ns.aml.vocabularies.shapes.MatrixShape)) {
        //     const type = /** @type ApiArrayShape */ (schema);
        //     if (type.items) {
        //       this[checkSchemaPropertyUpdate](type.items, id, updated)
        //     }
        //   }
        // }
        expandHandler(e) {
            const button = e.currentTarget;
            const { id } = button.dataset;
            this.toggleExpandedProperty(id);
        }
        expandKeydownHandler(e) {
            if (e.code !== 'Space') {
                return;
            }
            e.preventDefault();
            const button = e.currentTarget;
            const { id } = button.dataset;
            this.toggleExpandedProperty(id);
        }
        /**
         * Toggles an "expanded" state for a property children.
         * @param id Parent property id that has children to toggle visibility of.
         */
        toggleExpandedProperty(id) {
            const list = this.expandedValue;
            const index = list.indexOf(id);
            if (index === -1) {
                list.push(id);
            }
            else {
                list.splice(index, 1);
            }
            this.requestUpdate();
        }
        anyOfSelectedHandler(e) {
            const node = e.target;
            const { value, dataset } = node;
            const { schema } = dataset;
            if (!schema) {
                return;
            }
            this.selectedUnionsValue[schema] = value;
            this.processSchema();
            this.requestUpdate();
        }
        /**
         * Orders union items so the first is the one that has properties defined inline.
         */
        orderUnion(shapes) {
            return [...shapes].sort((a, b) => {
                const aHasName = !!a.name && !a.name.startsWith('item');
                const bHasName = !!b.name && !b.name.startsWith('item');
                if (aHasName === bHasName) {
                    return 0;
                }
                return aHasName ? 1 : -1;
            });
        }
        render() {
            const schema = this.schemaValue;
            if (!schema) {
                return html ``;
            }
            return html `
      ${this.titleTemplate(schema)} ${this.descriptionTemplate(schema.description)}
      ${this.customDomainPropertiesTemplate(schema.customDomainProperties)} ${this.examplesTemplate()}
      ${this.schemaContentTemplate(schema)}
    `;
        }
        /**
         * @returns The template for the schema title.
         */
        titleTemplate(schema) {
            const { name, displayName } = schema;
            const label = displayName || name || '';
            if (['schema', 'default'].includes(label)) {
                return '';
            }
            const typeName = name && label !== name && name !== 'schema' ? name : undefined;
            const { schemaTitle } = this;
            const headerCss = {
                'schema-title': true,
                'low-emphasis': !!schemaTitle,
            };
            const prefix = schemaTitle ? 'Schema: ' : '';
            return html `
      <div class="schema-header">
        <div class="${classMap(headerCss)}">
          <span class="headline-medium label text-selectable">${prefix}${label}</span>
          ${typeName ? html `<span class="type-name text-selectable" title="Schema name">(${typeName})</span>` : ''}
        </div>
      </div>
    `;
        }
        /**
         * @param schema The shape to render.
         * @returns The template for the schema properties depending on the type
         */
        schemaContentTemplate(schema) {
            const { noReadOnly } = this;
            if (schema.readOnly && noReadOnly) {
                return '';
            }
            const { types } = schema;
            if (types.includes(AmfNamespace.aml.vocabularies.shapes.ScalarShape)) {
                return this.scalarShapeTemplate(schema);
            }
            if (types.includes(AmfNamespace.w3.shacl.NodeShape)) {
                return this.nodeShapeTemplate(schema);
            }
            if (types.includes(AmfNamespace.aml.vocabularies.shapes.UnionShape)) {
                return this.unionShapeTemplate(schema);
            }
            if (types.includes(AmfNamespace.aml.vocabularies.shapes.FileShape)) {
                return this.fileShapeTemplate(schema);
            }
            if (types.includes(AmfNamespace.aml.vocabularies.shapes.SchemaShape)) {
                return this.schemaShapeTemplate(schema);
            }
            if (types.includes(AmfNamespace.aml.vocabularies.shapes.TupleShape)) {
                return this.tupleShapeTemplate(schema);
            }
            if (types.includes(AmfNamespace.aml.vocabularies.shapes.ArrayShape) ||
                types.includes(AmfNamespace.aml.vocabularies.shapes.MatrixShape)) {
                return this.arrayShapeTemplate(schema);
            }
            if (types.includes(AmfNamespace.aml.vocabularies.shapes.NilShape)) {
                return this.nilShapeTemplate(schema);
            }
            return this.anyShapeTemplate(schema);
        }
        /**
         * @returns The template for the scalar shape.
         */
        scalarShapeTemplate(schema) {
            if (schema.readOnly && this.noReadOnly) {
                return '';
            }
            const type = typeValueTemplate(readPropertyTypeLabel(schema));
            return html ` <div class="scalar-property">${type} ${scalarDetailsTemplate(schema, true)}</div> `;
            // return scalarDetailsTemplate(schema, true);
        }
        /**
         * @returns The template for the node shape.
         */
        nodeShapeTemplate(schema) {
            const { properties, inherits, readOnly } = schema;
            if (readOnly && this.noReadOnly) {
                return '';
            }
            let items = [...(properties || [])];
            if (Array.isArray(inherits) && inherits.length) {
                inherits.forEach((item) => {
                    if (item.types.includes(AmfNamespace.w3.shacl.NodeShape)) {
                        const typed = item;
                        items = items.concat([...(typed.properties || [])]);
                    }
                });
            }
            if (!items.length) {
                return html ` <div class="empty-info">Properties are not defined for this schema.</div> `;
            }
            return html ` <div class="children-section">${items.map((item) => this.shapePropertyTemplate(item))}</div> `;
        }
        // /**
        //  * @param {IShapeUnion[]} parents
        //  * @returns {TemplateResult[]|undefined}
        //  */
        // [inheritedTemplate](parents) {
        //   if (!Array.isArray(parents) || !parents.length) {
        //     return undefined;
        //   }
        //   const parts = [];
        //   parents.forEach((item) => {
        //     const tpl = this.schemaContentTemplate(item);
        //     if (tpl) {
        //       parts.push(tpl);
        //     }
        //   });
        //   if (!parts.length) {
        //     return undefined;
        //   }
        //   return parts;
        // }
        /**
         * @returns The template for the union shape.
         */
        unionShapeTemplate(schema) {
            const unionTemplate = unionDetailsTemplate(schema);
            const allScalar = isScalarUnion(schema);
            if (allScalar) {
                return unionTemplate;
            }
            const { anyOf, or, and, xone } = schema;
            if (Array.isArray(anyOf) && anyOf.length) {
                const schemaContent = this.anyOfUnionTemplate(schema.id, anyOf);
                return html ` ${unionTemplate} ${schemaContent} `;
            }
            if (Array.isArray(xone) && xone.length) {
                const schemaContent = this.anyOfUnionTemplate(schema.id, xone);
                return html ` ${unionTemplate} ${schemaContent} `;
            }
            if (Array.isArray(or) && or.length) {
                const schemaContent = this.anyOfUnionTemplate(schema.id, or);
                return html ` ${unionTemplate} ${schemaContent} `;
            }
            if (Array.isArray(and) && and.length) {
                const items = this.orderUnion(and).map((item) => this.andUnionItemTemplate(item));
                return html ` <div class="combined-union">${items}</div> `;
            }
            return unionTemplate;
        }
        andUnionItemTemplate(shape) {
            return html `
      <div class="and-union-member">${this.inheritanceNameTemplate(shape)} ${this.schemaContentTemplate(shape)}</div>
    `;
        }
        /**
         * @returns The template for the "and" union item's title, if inherited from another type.
         */
        inheritanceNameTemplate(shape) {
            const { name = '' } = shape;
            const hasName = !!name && !name.startsWith('item');
            if (hasName) {
                return html `<p class="inheritance-label text-selectable">Properties inherited from <b>${name}</b>.</p>`;
            }
            return '';
            // return html`<p class="inheritance-label">Properties defined inline.</p>`;
        }
        /**
         * @returns The template for the `any of` union.
         */
        anyOfUnionTemplate(schemaId, items) {
            const allSelected = this.selectedUnionsValue;
            let selected = allSelected[schemaId];
            let renderedItem;
            if (selected) {
                renderedItem = items.find((item) => item.id === selected);
            }
            else {
                ;
                [renderedItem] = items;
                selected = renderedItem.id;
            }
            if (!renderedItem) {
                return '';
            }
            const options = items.map((item) => {
                const label = readPropertyTypeLabel(item);
                // let label = item.name || item.displayName;
                // if (!label && item.types.includes(ns.aml.vocabularies.shapes.ScalarShape)) {
                //   const { dataType } = /** @type ApiScalarShape */ (item);
                //   label = `${schemaToType(dataType)} (#${index + 1})`;
                // }
                // if (!label) {
                //   label = `Option #${index + 1}`;
                // }
                return {
                    label,
                    id: item.id,
                };
            });
            return html `
      <div class="union-container">
        ${this.anyOfOptionsTemplate(schemaId, options, selected)} ${this.schemaContentTemplate(renderedItem)}
      </div>
    `;
        }
        /**
         * @param schemaId The parent schema id value
         * @param options The options to render.
         * @returns The template for the union any of selector.
         */
        anyOfOptionsTemplate(schemaId, options, selected) {
            return html `
      <div class="union-options">
        <p>Any (one or more) of the following schemas</p>
        ${options.map((item) => html `
            <label class="label-large">
              <ui-radio
                class="union-toggle"
                name="unionFor${schemaId}"
                value="${item.id}"
                .checked="${selected === item.id}"
                data-schema="${schemaId}"
                data-member="${item.label}"
                @change="${this.anyOfSelectedHandler}"
                aria-label="${item.label}"
              ></ui-radio>
              ${item.label}
            </label>
          `)}
      </div>
    `;
        }
        /**
         * @returns The template for the file shape.
         */
        fileShapeTemplate(schema) {
            if (schema.readOnly && this.noReadOnly) {
                return '';
            }
            let noDetail = false;
            if (schema === this.schemaValue) {
                noDetail = true;
            }
            return fileDetailsTemplate(schema, noDetail);
        }
        /**
         * @returns The template for the schema shape.
         */
        schemaShapeTemplate(schema) {
            const { raw, readOnly } = schema;
            if (readOnly && this.noReadOnly) {
                return '';
            }
            if (!raw) {
                return html ` <div class="empty-info">Schema is not defined for this message.</div> `;
            }
            return html `
      <div class="schema-content">
        <pre class="code-value text-selectable"><code>${raw}</code></pre>
      </div>
    `;
        }
        /**
         * @returns The template for the array shape.
         */
        arrayShapeTemplate(schema) {
            const { items, readOnly } = schema;
            if (readOnly && this.noReadOnly) {
                return '';
            }
            if (!items) {
                return html `<div class="empty-info">Items are not defined for this array.</div>`;
            }
            let labelTemplate;
            if (schema === this.schemaValue) {
                const label = readPropertyTypeLabel(schema, true);
                labelTemplate = html `
        <div class="schema-property-item">
          <div class="schema-property-label text-selectable">${label}</div>
        </div>
      `;
            }
            if (items.types.includes(AmfNamespace.aml.vocabularies.shapes.ScalarShape)) {
                return this.scalarShapeTemplate(schema);
            }
            return html ` <div class="children-section">${labelTemplate || ''} ${this.schemaContentTemplate(items)}</div> `;
        }
        /**
         * @returns The template for the tuple shape.
         */
        tupleShapeTemplate(schema) {
            const { items, readOnly } = schema;
            if (readOnly && this.noReadOnly) {
                return '';
            }
            if (!items) {
                return html `<div class="empty-info text-selectable">Items are not defined for this array.</div>`;
            }
            return html ` <div class="children-section">${items.map((item) => this.schemaContentTemplate(item))}</div> `;
        }
        /**
         * @returns The template for the Any shape.
         */
        anyShapeTemplate(schema) {
            const { and = [], or = [], readOnly, xone = [] } = schema;
            if (readOnly && this.noReadOnly) {
                return '';
            }
            if (and.length || or.length || xone.length) {
                return this.unionShapeTemplate(schema);
            }
            return html `<p class="any-info text-selectable">Any schema is accepted as the value here.</p>`;
        }
        /**
         * @returns The template for the Any shape.
         */
        nilShapeTemplate(schema) {
            if (schema.readOnly && this.noReadOnly) {
                return '';
            }
            return html `<p class="nil-info text-selectable">The value of this property is <b>nil</b>.</p>`;
        }
        /**
         * @returns The template for the schema property item.
         */
        shapePropertyTemplate(schema) {
            const { range, minCount = 0, readOnly } = schema;
            if (readOnly && this.noReadOnly) {
                return '';
            }
            if (!range) {
                return this.shapePropertyWithoutRangeTemplate(schema);
            }
            const { displayName, deprecated } = range;
            if (range.readOnly && this.noReadOnly) {
                return '';
            }
            const required = minCount > 0;
            const type = readPropertyTypeLabel(range);
            const label = displayName || schema.name || range.name;
            const paramLabel = displayName ? schema.name || range.name : undefined;
            const [domainType] = range.types;
            let isComplex = complexTypes.includes(domainType);
            if (isComplex) {
                if (range.types.includes(AmfNamespace.aml.vocabularies.shapes.TupleShape)) {
                    const { items = [] } = range;
                    isComplex = complexTypes.includes(items[0].types[0]);
                }
                else if (range.types.includes(AmfNamespace.aml.vocabularies.shapes.ArrayShape)) {
                    const { items } = range;
                    if (items) {
                        isComplex = complexTypes.includes(items.types[0]);
                    }
                }
                else if (range.types.includes(AmfNamespace.aml.vocabularies.shapes.UnionShape)) {
                    isComplex = !isScalarUnion(range);
                }
            }
            const allExpanded = this.expandedValue;
            const expanded = isComplex && allExpanded.includes(schema.id);
            const containerClasses = {
                'property-container': true,
                'complex': isComplex,
                expanded,
            };
            return html `
      <div class="${classMap(containerClasses)}" data-name="${schema.name || range.name || ''}">
        <div class="property-border"></div>
        <div class="property-value">
          <div class="property-headline">
            ${this.propertyDecoratorTemplate(isComplex, expanded, schema.id)}
            ${paramNameTemplate(label, required, deprecated, paramLabel)}
            <span class="headline-separator"></span>
            ${typeValueTemplate(type)} ${required ? pillTemplate('Required', 'This property is required.') : ''}
          </div>
          <div class="description-column">${this.propertyDescriptionTemplate(schema)}</div>
          <div class="details-column">${detailsTemplate(range)}</div>
        </div>
      </div>
      ${expanded
                ? html `
            <div class="shape-children">
              <div class="property-border"></div>
              <div>
                <!-- Do not remove this div container. It makes children in place -->
                ${this.schemaContentTemplate(range)}
              </div>
            </div>
          `
                : ''}
    `;
        }
        /**
         * @returns THe template for the line decorator in front of the property name.
         */
        propertyDecoratorTemplate(isComplex, expanded, schemaId) {
            const toggleIcon = isComplex
                ? html ` <span class="object-toggle-icon ${expanded ? 'opened' : ''}">${chevronRight}</span> `
                : '';
            const decoratorClasses = {
                'property-decorator': true,
                'scalar': !isComplex,
                'object': !!isComplex,
            };
            const toggleHandler = isComplex ? this.expandHandler : undefined;
            const keydownHandler = isComplex ? this.expandKeydownHandler : undefined;
            const tabIndex = isComplex ? '0' : '-1';
            return html `
      <div
        class="${classMap(decoratorClasses)}"
        data-id="${schemaId}"
        @click="${toggleHandler}"
        @keydown="${keydownHandler}"
        tabindex="${tabIndex}"
      >
        <hr />
        ${toggleIcon}
      </div>
    `;
        }
        /**
         * @returns The template for the schema property item that has no range information.
         */
        shapePropertyWithoutRangeTemplate(schema) {
            const { minCount = 0, name, displayName, deprecated } = schema;
            const label = name || displayName || 'Unnamed property';
            const required = minCount > 0;
            return html `
      <div class="property-container">
        <div class="name-column">
          ${paramNameTemplate(label, required, deprecated)}
          <div class="param-type text-selectable">Unknown type</div>
        </div>
        <div class="description-column">${this.propertyDescriptionTemplate(schema)}</div>
      </div>
    `;
        }
        propertyDescriptionTemplate(schema) {
            const { range, description } = schema;
            if (!range || description) {
                return this.descriptionTemplate(description);
            }
            return this.descriptionTemplate(range.description);
        }
    };
})();
export default ApiSchemaDocument;
//# sourceMappingURL=ApiSchemaDocument.element.js.map