<script lang="ts">
    import {DisplayMode} from "../common/DisplayMode";
    import prefixFilter from "../utils/prefixFilter";
    import {onMount} from "svelte";
    import Icon from "../icon";
    import {forwardAllEvents} from "../lib/forwardAllEvents";

    const excludeAttrs = ['readonly', 'disabled', 'required', "rows", "form", "wrap"];

    export let disabled: boolean = false;
    export let readonly: boolean = false;
    export let variant: '' | 'plain' | 'outlined' | 'filled' = '';
    export {className as class};
    export let style: string = '';
    export let value: string = '';
    export let wrap: "hard" | "soft" = "hard";
    export let resize: 'none' | 'horizontal' | 'vertical' | 'both' = 'none';
    export let displayMode: DisplayMode = DisplayMode.Edit;
    export let input$rows: number = 3;
    export let showIndicator: boolean = false;
    export let maxLength: number | null = null;

    let input$;
    let className: string = '';
    let textValue: string;
    let len: number;
    let editor: HTMLTextAreaElement;
    let width: number = 0;

    const escapeHTML = (text: string) => {
        return text == null ? '' : text.replace(/</g, "&lt;").replace(/>/g, "&gt;");
    };

    // 根据 displayMode 显示内容
    $: textValue = displayMode === DisplayMode.View
        ? escapeHTML(value).replace(/\n/g, "<br/>").replace(/ /g, '&nbsp;')
        : value;

    $: input$ = prefixFilter($$props, "input$", excludeAttrs);
    $: len = textValue?.length ?? 0;

    // 失焦/回车确认 change
    let oldValue = value;

    function handleInput(e: InputEvent) {
        value = (e.target as HTMLTextAreaElement).value;
    }

    function handleChange(e: Event) {
        if (oldValue !== value) {
            oldValue = value;
        }
    }

    // 自动计算宽度
    onMount(() => {
        if (editor) {
            const resizeObserver = new ResizeObserver(entries => {
                for (let entry of entries) {
                    const style = getComputedStyle(editor);
                    const paddingLeft = parseFloat(style.paddingLeft);
                    const paddingRight = parseFloat(style.paddingRight);
                    width = entry.contentRect.width + paddingLeft + paddingRight;
                }
            });
            resizeObserver.observe(editor);
            const forward = forwardAllEvents(editor, $$props, {
                input: handleInput,
                change: handleChange
            });

            return () => {
                resizeObserver.disconnect();
                forward.destroy?.();
            }
        }
    });

    const clean = () => {
        value = '';
        editor?.focus();
    };
</script>

{#if displayMode === DisplayMode.View}
    <div class="uniface-display-field" style="width:100%; min-height: 60px; {style};">
        {@html textValue}
    </div>
{:else if readonly}
    <textarea
            style="width:100%; {style}; resize: {resize}"
            class="uniface-memo-editor {variant} {className}"
            {readonly}
            rows={input$rows ?? 3}
            {value}
            {disabled}
            {...input$}
    ></textarea>
{:else}
    <div class="uniface-memo-editor-wrapper" tabindex="-1" style="position: relative; {style}">
        <textarea
                bind:this={editor}
                style="width:100%; resize: {resize}"
                class="uniface-memo-editor {variant} {className}"
                rows={input$rows ?? 3}
                {wrap}
                bind:value
                {disabled}
                {...input$}
                maxlength={maxLength}
                on:blur
                on:focus
                on:keydown
                on:keyup
                on:keypress
                on:input
                on:change
                on:compositionstart
                on:compositionend
                on:compositionupdate
        ></textarea>

        {#if showIndicator && maxLength}
            <div class="uniface-memo-indicator" style="width: {width}px">
                <span>{len} / {maxLength}</span>
            </div>
        {/if}

        {#if !disabled && value?.length > 0}
            <div class="action-button-wrapper" style="position: absolute; top: 0; left: 0; width: {width}px;">
                <Icon name="icon_google_clear" class="uniface-editor-clean-icon" onclick={clean}/>
            </div>
        {/if}
    </div>
{/if}
