var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
    if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
    if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
    return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
    if (kind === "m") throw new TypeError("Private method is not writable");
    if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
    if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
    return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var _DevvitFormDialog_onEvent, _DevvitFormDialog_idMap, _DevvitFormDialog_makeIdMap, _DevvitFormDialog_collectValues, _DevvitFormDialog_submitForm, _DevvitFormDialog_onKeyUp, _DevvitFormDialog_cancelClicked, _DevvitFormDialog_onDialogClosed, _DevvitFormDialog_dispatchFormStatusToHost, _DevvitFormDialog_fixFocustrap, _DevvitFormDialog_renderTitle, _DevvitFormDialog_renderDescription, _DevvitFormDialog_renderButtons;
import '@reddit/faceplate-ui/templateRenderingStrategy/clientStrategy.js';
import '@reddit/faceplate-ui/components/faceplate-dialog';
import '@reddit/faceplate/components/faceplate-form.js';
import { FormFieldType } from '@devvit/protos';
import { UIEvent } from '@devvit/protos/types/devvit/ui/events/v1alpha/event.js';
import { FormFieldValue } from '@devvit/protos/types/devvit/ui/form_builder/v1alpha/value.js';
import { formKeyToHookId } from '@devvit/shared-types/useForm.js';
import { FaceplateForm } from '@reddit/faceplate/components/faceplate-form.js';
import { customEvent } from '@reddit/faceplate/lib/custom-event.js';
import { msg } from '@reddit/faceplate/lib/i18n/localize.js';
import { FaceplateDialog } from '@reddit/faceplate-ui/components/faceplate-dialog.js';
import { button, ButtonSize } from '@reddit/faceplate-ui/templates/client/button.js';
import { html, LitElement } from 'lit';
import { customElement, property, query } from 'lit/decorators.js';
import { when } from 'lit/directives/when.js';
import { styles } from '../../styles.js';
import { renderFormFields } from './fields/index.js';
/**
 * Devvit form dialog.
 *
 * Renders the form fields, handles form submission
 *
 * @fires {unknown} devvit-image-upload
 */
let DevvitFormDialog = class DevvitFormDialog extends LitElement {
    constructor() {
        super(...arguments);
        _DevvitFormDialog_onEvent.set(this, () => { });
        _DevvitFormDialog_idMap.set(this, {});
        _DevvitFormDialog_makeIdMap.set(this, (fields) => fields.reduce((map, field) => {
            if (field.fieldType === FormFieldType.GROUP) {
                return {
                    ...map,
                    ...__classPrivateFieldGet(this, _DevvitFormDialog_makeIdMap, "f").call(this, field.fieldConfig?.groupConfig?.fields ?? []),
                };
            }
            map[field.fieldId] = field;
            return map;
        }, {}));
        _DevvitFormDialog_collectValues.set(this, () => {
            const values = {};
            if (!this.$form) {
                return values;
            }
            for (const f of this.$form.elementsIterator()) {
                const { name, value } = f;
                const { fieldType } = __classPrivateFieldGet(this, _DevvitFormDialog_idMap, "f")[name];
                const fieldValue = FormFieldValue.fromPartial({
                    fieldType,
                });
                switch (fieldType) {
                    case FormFieldType.STRING:
                    case FormFieldType.PARAGRAPH:
                    case FormFieldType.IMAGE: // the string value is the URL
                        if (value === null || value.trim() === '') {
                            continue;
                        }
                        fieldValue.stringValue = value;
                        break;
                    case FormFieldType.NUMBER:
                        fieldValue.numberValue = Number(value || 0);
                        break;
                    case FormFieldType.BOOLEAN:
                        fieldValue.boolValue = value === 'true' || value === 'on';
                        break;
                    case FormFieldType.SELECTION:
                        if (value === null || value.trim() === '') {
                            continue;
                        }
                        fieldValue.selectionValue = { values: value.split(',') };
                        break;
                }
                values[name] = fieldValue;
            }
            return values;
        });
        _DevvitFormDialog_submitForm.set(this, () => {
            const invalidFields = this.$form?.querySelectorAll('[faceplate-validity="invalid"]');
            if (!invalidFields || invalidFields.length > 0) {
                return;
            }
            if (!this.form?.id) {
                throw new Error(`Cannot submit form due to missing form id. If you are using 'useForm' please make sure that it is not called conditionally inside of your component.`);
            }
            __classPrivateFieldGet(this, _DevvitFormDialog_onEvent, "f").call(this, UIEvent.fromPartial({
                hook: formKeyToHookId(this.form.id),
                formSubmitted: {
                    formId: this.form.id,
                    results: __classPrivateFieldGet(this, _DevvitFormDialog_collectValues, "f").call(this),
                },
            }));
            this.$dialog?.close();
        });
        _DevvitFormDialog_onKeyUp.set(this, (event) => {
            if (event.key === 'Enter' && !event.target.tagName.includes('TEXTAREA')) {
                __classPrivateFieldGet(this, _DevvitFormDialog_submitForm, "f").call(this);
            }
        });
        _DevvitFormDialog_cancelClicked.set(this, () => {
            this.$dialog?.close();
        });
        // don't call directly, should be used as event listener to dialog closed
        _DevvitFormDialog_onDialogClosed.set(this, () => {
            this.form = undefined;
            __classPrivateFieldSet(this, _DevvitFormDialog_idMap, {}, "f");
            __classPrivateFieldGet(this, _DevvitFormDialog_dispatchFormStatusToHost, "f").call(this, { open: false });
        });
        _DevvitFormDialog_dispatchFormStatusToHost.set(this, ({ open }) => {
            this.dispatchEvent(customEvent('devvit-form-dialog-event', { open }));
        });
        _DevvitFormDialog_fixFocustrap.set(this, (event) => {
            // faceplate-dialog has a known issue with focus management.
            // Inputs are not registered as "focusable" so click on input label is handled by focus trap incorrectly
            // faceplate-ui team knows about it, but the solution is not yet ready
            // this is a band-aid that prevents focus trap from knowing that we did the click
            // and blocks incorrect behaviour from happening
            event.stopPropagation();
        });
        _DevvitFormDialog_renderTitle.set(this, () => html `<span class="text-32 py-sm">${this.form?.title}</span>`);
        _DevvitFormDialog_renderDescription.set(this, () => html `<span class="pb-md">${this.form?.shortDescription}</span>`);
        _DevvitFormDialog_renderButtons.set(this, () => html `
    <div class="flex justify-end space-x-xs">
      ${button({
            appearance: 'secondary',
            size: ButtonSize.Medium,
            children: this.form?.cancelLabel ??
                msg('Cancel', { desc: 'Cancel custom action and dismiss dialog' }),
            attributes: {
                onclick: __classPrivateFieldGet(this, _DevvitFormDialog_cancelClicked, "f"),
            },
        })}
      ${button({
            appearance: 'primary',
            size: ButtonSize.Medium,
            children: this.form?.acceptLabel ?? msg('OK', { desc: 'Submit input for the custom action' }),
            attributes: {
                type: 'submit',
                onclick: __classPrivateFieldGet(this, _DevvitFormDialog_submitForm, "f"),
            },
        })}
    </div>
  `);
    }
    static get styles() {
        return [styles];
    }
    showForm(form, onEvent) {
        if (this.$dialog) {
            this.form = form;
            __classPrivateFieldSet(this, _DevvitFormDialog_idMap, __classPrivateFieldGet(this, _DevvitFormDialog_makeIdMap, "f").call(this, form.fields), "f");
            __classPrivateFieldSet(this, _DevvitFormDialog_onEvent, onEvent, "f");
            this.$dialog.showModal();
            __classPrivateFieldGet(this, _DevvitFormDialog_dispatchFormStatusToHost, "f").call(this, { open: true });
        }
    }
    render() {
        return html `
      <faceplate-dialog
        class="z-dialog w-[32rem] overflow-auto"
        @faceplate-close="${__classPrivateFieldGet(this, _DevvitFormDialog_onDialogClosed, "f")}"
      >
        <div
          class="flex flex-col gap-y-sm"
          @focusin="${__classPrivateFieldGet(this, _DevvitFormDialog_fixFocustrap, "f")}"
          @keyup="${__classPrivateFieldGet(this, _DevvitFormDialog_onKeyUp, "f")}"
        >
          ${when(this.form?.title, __classPrivateFieldGet(this, _DevvitFormDialog_renderTitle, "f"))}
          ${when(this.form?.shortDescription, __classPrivateFieldGet(this, _DevvitFormDialog_renderDescription, "f"))}
          <faceplate-form
            @faceplate-submit="${(ev) => ev.preventDefault()}"
            class="flex flex-col gap-y-sm"
          >
            ${renderFormFields(this.form?.fields ?? [])}
            <!---->
            ${__classPrivateFieldGet(this, _DevvitFormDialog_renderButtons, "f").call(this)}
          </faceplate-form>
        </div>
      </faceplate-dialog>
    `;
    }
};
_DevvitFormDialog_onEvent = new WeakMap();
_DevvitFormDialog_idMap = new WeakMap();
_DevvitFormDialog_makeIdMap = new WeakMap();
_DevvitFormDialog_collectValues = new WeakMap();
_DevvitFormDialog_submitForm = new WeakMap();
_DevvitFormDialog_onKeyUp = new WeakMap();
_DevvitFormDialog_cancelClicked = new WeakMap();
_DevvitFormDialog_onDialogClosed = new WeakMap();
_DevvitFormDialog_dispatchFormStatusToHost = new WeakMap();
_DevvitFormDialog_fixFocustrap = new WeakMap();
_DevvitFormDialog_renderTitle = new WeakMap();
_DevvitFormDialog_renderDescription = new WeakMap();
_DevvitFormDialog_renderButtons = new WeakMap();
__decorate([
    property({ attribute: false }),
    __metadata("design:type", Object)
], DevvitFormDialog.prototype, "form", void 0);
__decorate([
    query('faceplate-dialog', true),
    __metadata("design:type", FaceplateDialog)
], DevvitFormDialog.prototype, "$dialog", void 0);
__decorate([
    query('faceplate-form', true),
    __metadata("design:type", FaceplateForm)
], DevvitFormDialog.prototype, "$form", void 0);
DevvitFormDialog = __decorate([
    customElement('devvit-form-dialog')
], DevvitFormDialog);
export { DevvitFormDialog };
//# sourceMappingURL=devvit-form-dialog.js.map