import { __decorate } from "tslib";
import { html } from 'lit';
import { property } from 'lit/decorators.js';
import { ApiDocumentationBase } from './ApiDocumentationBase.js';
import { Events } from '../../events/amf/Events.js';
import '../../define/amf/api-payload-document.js';
import '../../define/amf/api-parameter-document.js';
import '../../define/ui/ui-radio.js';
/**
 * A web component that renders the documentation page for an API response object.
 */
export default class ApiResponseDocument extends ApiDocumentationBase {
    /**
     * @returns true when has headers parameters definition
     */
    get hasHeaders() {
        const response = this.responseValue;
        if (!response) {
            return false;
        }
        return Array.isArray(response.headers) && !!response.headers.length;
    }
    get payloadValue() {
        const { mimeType } = this;
        const payloads = this.payloadsValue;
        if (!Array.isArray(payloads) || !payloads.length) {
            return undefined;
        }
        if (!mimeType) {
            return payloads[0];
        }
        return payloads.find((item) => item.mediaType === mimeType);
    }
    get response() {
        return this.responseValue;
    }
    set response(value) {
        const old = this.responseValue;
        if (old === value) {
            return;
        }
        this.responseValue = value;
        this.processGraph();
    }
    /**
     * Queries the graph store for the API Response data.
     */
    async processGraph() {
        await this.queryResponse();
        await this.queryPayloads();
        this.requestUpdate();
        await this.updateComplete;
    }
    /**
     * Queries the store for the response data, when needed.
     */
    async queryResponse() {
        const { domainId } = this;
        if (!domainId) {
            // this.responseValue = undefined;
            return;
        }
        if (this.responseValue && this.responseValue.id === domainId) {
            // in case the response model was provided via the property setter.
            return;
        }
        try {
            const info = await Events.Response.get(this, domainId);
            this.responseValue = info;
        }
        catch (e) {
            this.responseValue = undefined;
            const ex = e;
            Events.Telemetry.exception(this, ex.message, false);
            Events.Reporting.error(this, ex, `Unable to query for API response data: ${ex.message}`, this.localName);
        }
    }
    async queryPayloads() {
        const { response } = this;
        if (!response || !Array.isArray(response.payloads) || !response.payloads.length) {
            this.payloadsValue = undefined;
            return;
        }
        this.payloadsValue = response.payloads;
    }
    handleMediaTypeSelect(e) {
        const button = e.target;
        if (!button.checked) {
            return;
        }
        const mime = button.value;
        this.mimeType = mime;
    }
    render() {
        if (!this.responseValue) {
            return html ``;
        }
        return html `
    ${this.customDomainPropertiesTemplate(this.responseValue.customDomainProperties)}
    ${this.descriptionTemplate(this.responseValue.description)}
    ${this.renderHeaders()}
    ${this.renderLinks()}
    ${this.renderPayload()}
    `;
    }
    /**
     * @returns The template for the headers
     */
    renderHeaders() {
        const { response } = this;
        if (!this.hasHeaders || !response) {
            return '';
        }
        const content = response.headers.map((id) => this.schemaItemTemplate(id));
        return this.paramsSectionTemplate('Headers', 'headersOpened', content, { innerSection: true });
    }
    /**
     * @returns The template for the payload section
     */
    renderPayload() {
        const payload = this.payloadValue;
        if (!payload) {
            return '';
        }
        const content = html `
    ${this.renderPayloadSelector()}
    <api-payload-document .domainId="${payload.id}" .payload="${payload}"></api-payload-document>
    `;
        // return this.paramsSectionTemplate('Response body', 'payloadOpened', content);
        return html `
    <div class="inner-section">
      <div class="params-title"><span class="label">Response body</span></div>
      ${content}
    </div>
    `;
    }
    /**
     * @returns The template for the payload media type selector.
     */
    renderPayloadSelector() {
        const payloads = this.payloadsValue;
        if (!Array.isArray(payloads) || payloads.length < 2) {
            return '';
        }
        const mime = [];
        payloads.forEach((item) => {
            if (item.mediaType) {
                mime.push(item.mediaType);
            }
        });
        if (!mime.length) {
            return '';
        }
        const mimeType = this.mimeType || mime[0];
        return html `
    <div class="media-type-selector">
      <span id="mimeLabel" class="label-large">Body content type</span>
      ${mime.map((item) => html `
      <label class="label-large">
        <ui-radio
          class="response-toggle"
          name="responseMime"
          value="${item}"
          .checked="${mimeType === item}" 
          @change="${this.handleMediaTypeSelect}"
          aria-describedby="mimeLabel"
        ></ui-radio>
        ${item}
      </label>
      `)}
    </div>
    `;
    }
    /**
     * @returns The template for the response links
     */
    renderLinks() {
        const { response } = this;
        if (!response) {
            return '';
        }
        const { links = [] } = response;
        if (!Array.isArray(links) || !links.length) {
            return '';
        }
        return html `
    <div class="links-header">Links</div>
    ${links.map((link) => this.renderLink(link))}
    `;
    }
    /**
     * @returns A template for the link
     */
    renderLink(link) {
        const { name, mapping, operationId, } = link;
        return html `
    <div class="link-header text-selectable">${name}</div>
    ${this.renderLinkOperation(operationId)}
    <div slot="markdown-html" class="link-table text-selectable">
      ${this.renderLinkMappings(mapping)}
    </div>
    `;
    }
    /**
     * @returns The template for the link's operation
     */
    renderLinkOperation(operationId) {
        if (!operationId) {
            return '';
        }
        return html `
    <div class="operation-id">
      <span class="label">Operation ID:</span>
      <span class="operation-name text-selectable">${operationId}</span>
    </div>
    `;
    }
    /**
     * @returns The template for the link's operation
     */
    renderLinkMappings(mappings) {
        if (!mappings) {
            return '';
        }
        return html `
    <table class="mapping-table text-selectable">
      <tr>
        <th>Variable</th>
        <th>Expression</th>
      </tr>
      ${mappings.map(item => this.renderLinkMapping(item))}
    </table>
    `;
    }
    /**
     * @returns The template for the link's operation
     */
    renderLinkMapping(mapping) {
        const { linkExpression, templateVariable } = mapping;
        return html `
    <tr>
      <td>${templateVariable}</td>
      <td>${linkExpression}</td>
    </tr>
    `;
    }
}
__decorate([
    property({ type: Object })
], ApiResponseDocument.prototype, "response", null);
__decorate([
    property({ type: Boolean, reflect: true })
], ApiResponseDocument.prototype, "headersOpened", void 0);
__decorate([
    property({ type: Boolean, reflect: true })
], ApiResponseDocument.prototype, "payloadOpened", void 0);
__decorate([
    property({ type: String, reflect: true })
], ApiResponseDocument.prototype, "mimeType", void 0);
//# sourceMappingURL=ApiResponseDocument.element.js.map