<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_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'; // text, textarea, template (older method)
export let field_value: any;
export let allow_null: boolean = false;
export let display_inline: 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 = '<span class="fas fa-check"></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(() => {
    // console.log('** Element Mounted: ** Element AE CRUD');
    if (log_lvl) {
        console.log(`Element AE CRUD: Object Type: ${object_type}; Object ID: ${object_id}; Field Name: ${field_name}; Field Value: ${field_value}`); // ; Super Key: ${api_crud_super_key}
    }
});


$: if (trigger_patch == true) {
    console.log('AE CRUD: Patch triggered!');
    // console.log(trigger_patch);
    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;

    // 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,
        })
    .then(function (results) {
        console.log('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';
        } 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;
        }

        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 true;
    })
    .catch(function (error) {
        console.log('Something went wrong patching the record.');
        console.log(error);
        return false;
    })
    .finally(function () {
        console.log('PATCH Promise finally');
    });


    // if (ae_promises.api_update__ae_obj) {
    //     console.log(`Patched - Field Name: ${field_name} with new Field Value: ${new_field_value}; Original Field Value: ${original_field_value}`);
    //     patch_result = 'PATCH complete';
    // } 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;
    // }

    // ae_promises.api_update__ae_obj = api.update_ae_obj_id_crud({
    //     api_cfg: api_cfg,
    //     obj_type: object_type,
    //     obj_id: object_id,
    //     field_name: field_name,
    //     field_value: new_field_value,
    //     // fields: data,
    //     key: api_crud_super_key,
    //     // jwt: null,
    //     // params: params,
    //     // data: patch_data,
    //     log_lvl: 2
    //     })
    // .then(function (results) {
    //     console.log('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';
    //     } 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;
    //     }

    //     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 true;
    // })
    // .catch(function (error) {
    //     console.log('Something went wrong patching the record.');
    //     console.log(error);
    //     return false;
    // })
    // .finally(function () {
    //     console.log('PATCH Promise finally');
    // });

    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 field_show_btn"
            class:hide_edit_btn
            class:show_crud
            on:dblclick={() => {
                show_crud = true;
            }}
            title="Double click to edit"
            >
            <span class="fas fa-edit"></span>
        </button>
    </span>

    <span class="field_editing_wrapper">
        <button
            class="btn btn-sm btn_default field_hide_btn"
            class:show_crud
            on:click={() => {
                show_crud = false;
            }}
            title="Close field editing"
            >
            <span class="fas fa-window-close"></span>
        </button>

        <span class="field_value" 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 == 'text'}
            <input bind:value={field_value}>
        {:else if field_type == 'textarea'}
            <textarea bind:value={field_value} cols={textarea_cols} rows={textarea_rows}></textarea>
        {:else}
            <input bind:value={field_value}>
        {/if}
        {#if allow_null}
            <button
                class="btn btn-sm btn_warning null_value_btn"
                on:click={async () => {
                    field_value = null;
                }}
                title="Set value to NULL"
                >
                {@html '&#0;'} NULL
            </button>
        {/if}
        </span>

        <button
            class="btn btn-md btn_primary field_patch_btn"
            class:show_crud
            on:click={async () => {
                handle_obj_field_patch(field_value);
            }}
            title="Save new field value"
            >
            {@html btn_label}
        </button>

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


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


/* 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);

    /* NOTE: transition when hover ends */
    transition-property: 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);

    /* NOTE: transition when hover starts */
    transition-property: 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: 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%;

    width: auto;
    /* width: 100%; */
    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;
}

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