<script lang="ts">
// *** Import Svelte core
import { createEventDispatcher, onMount } from 'svelte';

// *** Import Aether core variables and functions
import type { key_val } from '$lib/ae_stores';
// import { api } from '$lib/api';
import { core_func } from '$lib/ae_core/ae_core_functions';
// import { ae_loc, ae_sess, ae_api, ae_trig, slct, slct_trigger } from '$lib/ae_stores';

// *** Import Aether core components
// *** Import Aether module variables and functions
// *** Import Aether module components

// *** Export/Exposed variables and functions for component
export let log_lvl: number = 0;
export let trigger_patch: any = null;
export let api_cfg: key_val = {'api_crud_super_key': null};
// export let api_crud_super_key: null|string = api_cfg.api_crud_super_key;
export let object_type: string;
export let object_id: string;
export let field_name: string;
export let field_type: string = 'text'; // button, text, textarea, template (older method), select (in progress method)
export let field_value: any;
export let allow_null: boolean = false;
export let select_option_li: key_val = {};
export let val_empty_is_null: boolean = false; // This was added to help with a select option list. If the value is empty (''), it will be set to null.
export let edit_label: string = 'Edit';
export let display_inline: boolean = false;
export let display_block_edit: boolean = false;

export let textarea_cols: number = 80;
export let textarea_rows: number = 5;

// export let input_field_template: null|object = null;

export let hide_edit_btn = false;
export let outline_element = false;
export let show_crud = false;
export let btn_label = null; // '<span class="fas fa-check mx-1"></span> Save'; // PATCH

// export let show_field_name = true;
// export let show_original_value = true;
// export let trim_string = false;
// export let remove_breaks = false;

export let class_li: string = '';

// *** Set initial variables
let ae_promises: key_val = {}; // Promise<any>;
let patch_result: null|Promise<any>|key_val|string;

let original_field_value = field_value;

const dispatch = createEventDispatcher();


onMount(() => {
    if (log_lvl) {
        console.log(`Element AE CRUD: Object Type: ${object_type}; Object ID: ${object_id}; Field Name: ${field_name}; Field Value: ${field_value} (Original: ${original_field_value})`);
        // ; Super Key: ${api_crud_super_key}
    }
});


$: if (trigger_patch == true) {
    console.log('AE CRUD: Patch triggered!');
    trigger_patch = null;
    handle_obj_field_patch(field_value);
}



// Updated 2024-03-22
async function handle_obj_field_patch(new_field_value: any) {
    console.log('*** handle_obj_field_patch() ***');

    patch_result = null;

    // This was added to help with a select option list. If the value is empty (''), it will be set to null.
    if (val_empty_is_null && new_field_value == '') {
        new_field_value = null;
    }

    // NOTE: Is this needed? The field_name, field_value, and fields parameters for update_ae_obj_id_crud() already take care of the data portion. They are added to data_list object as part of the JSON request.
    // NOTE: Currently this only handles one field and value at a time. This may need to be changed in the future to use the "fields" parameter as well.
    // let patch_data = {}

    // if (remove_breaks) {
    //     patch_data['field_value'] = field_value.replace(/(\r\n|\n|\r)/gm, "");
    // } else {
    //     patch_data['field_value'] = field_value;
    // }

    // patch_data[field_name] = field_value;
    // console.log(patch_data);

    // let params = {};

    ae_promises.api_update__ae_obj = core_func.handle_update_ae_obj_id_crud({
        api_cfg: api_cfg,
        object_type: object_type,
        object_id: object_id,
        field_name: field_name,
        new_field_value: new_field_value,
        params: {},
        try_cache: false,
        log_lvl: 0
        })
    .then(function (results) {
        console.log('Field PATCH Promise', results);

        if (results) {
            console.log(`Patched - Field Name: ${field_name} with new Field Value: ${new_field_value}; Original Field Value: ${original_field_value}`);
            patch_result = 'PATCH complete';
            original_field_value = new_field_value;
        } else {
            console.log(`Not Patched - Field Name: ${field_name} with new Field Value: ${new_field_value}; Original Field Value: ${original_field_value}`);
            patch_result = 'PATCH failed';
            return false;
        }
        return true;
    })
    .catch(function (error) {
        console.log('Something went wrong patching the record.');
        console.log(error);
        return false;
    })
    .finally(function () {
        console.log('Field PATCH Promise finally');
        // This dispatch() must be under "finally".
        dispatch(
            'ae_crud_updated',
            {
                'type': object_type,
                'id': object_id,
                'field_name': field_name,
                'field_value': new_field_value,
                'original_value': original_field_value,
            }
        );
    });

    return ae_promises.api_update__ae_obj;
}
</script>


<div
    class="{class_li} ae_crud"
    class:show_crud
    class:display_inline
    class:outline_element
    >
    <span class="field_viewing_wrapper">
        <slot></slot>

        <button
            class="btn btn-sm preset-tonal-warning hover:preset-tonal-error border border-error-500 field_show_btn"
            class:hide_edit_btn
            class:show_crud
            on:dblclick={() => {
                show_crud = true;
            }}
            title="Double click to edit property"
            >
            <span class="fas fa-edit"></span>
            <span class="hidden">Edit</span>
        </button>
    </span>

    <div
        class:display_block_edit
        class="field_editing_wrapper min-w-content w-100 max-w-full"
        >
        <!-- <span class="grow flex flex-row items-center justify-between"> -->
            <span class="hidden">
            {edit_label}
            </span>

            <button
                class="btn btn-md ae_btn_neutral m-1"
                class:show_crud
                on:click={() => {
                    show_crud = false;
                }}
                title="Close field editing"
                >
                <span class="fas fa-window-close"></span>
                <span class="hidden md:inline">Close</span>
            </button>
        <!-- </span> -->

        <span
            class="field_value grow min-w-content max-w-full"
            class:show_crud
            >
        {#if field_type == 'template'}
            <!-- <Element_input_v2 {...input_field_template} bind:value={field_value} /> -->
        {:else if field_type == 'button'}
            <!-- <input type="button" bind:value={field_value}> -->
            {field_value}
        {:else if field_type == 'select'}
            <select
                bind:value={field_value}
                class="select"
                >
                {#if select_option_li && Object.keys(select_option_li).length == 0}
                    <option value="">-- not set --</option>
                {:else if select_option_li && Object.keys(select_option_li).length > 0}
                    {#each Object.keys(select_option_li) as option}
                        <option value={option}>{select_option_li[option]}</option>
                    {/each}
                {:else}
                    <option value="">-- no list --</option>
                {/if}
            </select>

        {:else if field_type == 'text'}
            <input
                bind:value={field_value}
                class="input min-w-64 w-96 max-w-full"
                >
        {:else if field_type == 'textarea'}
            <textarea
                bind:value={field_value}
                cols={textarea_cols}
                rows={textarea_rows}
                class="textarea"
                ></textarea>
        {:else}
            <input
                bind:value={field_value}
                class="input w-fit"
                >
        {/if}
        {#if allow_null}
            <button
                class="btn btn-sm preset-tonal-warning hover:preset-tonal-warning border border-warning-500 m-1"
                on:click={() => {
                    field_value = null;
                }}
                title="Set value to NULL"
                >
                Ø
                NULL
            </button>
        {/if}
        </span>

        <button
            class="btn btn-lg ae_btn_warning m-1"
            class:show_crud
            disabled={field_value == original_field_value}
            on:click={async () => {
                handle_obj_field_patch(field_value);
            }}
            title="Save new field value"
            >
            {#if field_value == original_field_value}
                {#if (btn_label)}
                    {@html btn_label}
                {:else}
                    <span class="fas fa-check mx-1"></span>
                    <span>Save</span>
                {/if}
                <!-- <span>{patch_result}</span> -->
            {:else}
                {#if (btn_label)}
                    {@html btn_label}
                {:else}
                    <span class="fas fa-save mx-1"></span>
                    <span>Save?</span>
                {/if}
            {/if}

        </button>

        <div class="field_patch_result" class:show_crud>
            {#await ae_promises.api_update__ae_obj}
                <span class="fas fa-spinner fa-spin mx-1"></span>
                <span>Processing...</span>
            {:then}
                {#if patch_result}
                    <span class="fas fa-check mx-1"></span>
                    <span>{patch_result}</span>
                {:else}
                    <!-- <div>Nothing to show yet...</div> -->
                {/if}
            {/await}
        </div>
    </div>
</div>


<style>
/* .ae_crud .field_editing_wrapper {
    font-size: 1em;
} */


/* BEGIN: Svelte CRUD (update) component  */
/* .ae_crud {
    margin: 0;
    padding: 0;
} */

.ae_crud.display_inline {
    /* outline: solid thin red; */
    display: inline;
}

.ae_crud.show_crud .field_viewing_wrapper .field_show_btn {
    display: none;
}

.ae_crud.outline_element .field_viewing_wrapper {
    outline: dotted thin hsla(0,50%,50%,0);
    transition: outline 3s 1s;
}
.ae_crud.outline_element .field_viewing_wrapper:hover {
    outline: dashed thin hsla(0,50%,50%,.9);
    transition: outline 1s .5s;
}

.ae_crud .field_viewing_wrapper .field_show_btn.hide_edit_btn {
    display: none;
}

.ae_crud .field_viewing_wrapper .field_show_btn {
    margin: 0;
    padding: 0;

    /* color: hsla(0,0%,50%,.8); */
    opacity: .25;

    /* NOTE: transition when hover ends */
    transition-property: opacity, background-color, border-color, color, height, width;
    transition-delay: 1.00s; /* no delay */
    transition-duration: .55s;
    transition-timing-function: linear;
}

.ae_crud .field_viewing_wrapper:hover .field_show_btn {
    /* outline: solid thin hsla(0,50%,50%,.9); */
    /* color: hsla(0,50%,50%,.9); */

    opacity: 1;

    /* NOTE: transition when hover starts */
    transition-property: opacity, background-color, border-color, color, height, width;
    transition-delay: .25s; /* no delay */
    transition-duration: .50s;
    transition-timing-function: linear;
}

.ae_crud .field_editing_wrapper {
    /* outline: dashed thin pink; */

    display: none;
    /* position: relative; */

    /* contain: layout; */
    /* contain: size; */
    /* contain: none; */
    contain: content;

    box-shadow: .5em .5em .75em .75em hsla(0,0%,0%,0.5);

    /* color: hsla(0,0%,50%,.8); */
    background-color: hsla(0,0%,50%,.5);
    border: dashed thin transparent;

    /* font-size: 1em; */
    /* line-height: 1em; */

    height: 1em;
    width: 1em;

    /* NOTE: transition when hover ends */
    transition-property: background-color, border-color, color, height, width;
    transition-delay: .75s; /* short delay */
    transition-duration: .50s;
    transition-timing-function: linear;

}

.ae_crud.show_crud .field_editing_wrapper {
    /* display: initial; */
    display: block;
    contain: content;

    /* background-color: yellow; */
    background-color: hsla(60,50%,80%,.95);
    border: solid thin hsla(0,50%,50%,.50);
    border-radius: .5em;

    height: auto;
    /* height: 100%; */
    max-height: 100%;

    min-width: fit-content;
    width: auto;
    max-width: 100%;

    /* NOTE: transition when hover starts */
    transition-property: background-color, border-color, height, width;
    transition-delay: .25s; /* no delay */
    transition-duration: .25s;
    transition-timing-function: linear;

    /* position: absolute; */
    /* position: fixed; */
    /* position: relative; */
    /* top: 1em; */
    /* left: 1em; */
    /* right: 1em; */
    /* bottom: 1em; */

    z-index: 1;

    padding: .5em;
}

.ae_crud.show_crud.display_inline .field_editing_wrapper {
    /* display: block; */
    display: inline-block;
    /* display: inline; */

    box-shadow: initial;
    background-color: hsla(60,50%,80%,.3);

    padding: .25em;

    position: initial;

    z-index: 0;

    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
    gap: .5em;

    width: 30%;
}

.ae_crud.show_crud.display_inline .field_editing_wrapper.display_block_edit {
    /* display: block; */

    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: .5em;

    flex-grow: 1;

    height: auto;
    width: 100%;
}

.ae_crud textarea {
    height: auto;
}
/* END: Svelte CRUD (update) component  */
</style>
