<script lang="ts">
import { createEventDispatcher, onMount } from 'svelte';

import util from './utilities.js';

// import Select_element_lu from './element_select_lu.svelte';


/* *** BEGIN *** Core input settings */

export let id_random: string = ''; // OSIT Aether specific
export let obj_type: string = ''; // OSIT Aether specific
export let obj_prop_name: string = ''; // OSIT Aether specific


export let use_name_prefix: boolean = false;
export let name: string = (use_name_prefix ? `${obj_type}__${obj_prop_name}` : obj_prop_name);
// console.log(name);
export let id: string = `${obj_type}__${obj_prop_name}--${id_random}`; // Same as the value for "for"
// console.log(id);

export let value: null|boolean|number|string = null; // The current value of the property
console.log(`Input name=${name} value=${value}`);
export let default_value: null|boolean|number|string = null; // The default value for when value is ''
// console.log('Default Value:', default_value);
export let original_value: null|boolean|number|string = value; // The original value
console.log('Original Value', original_value);
export let data_type: string = typeof value; // boolean, number, string, json
console.log('Data Type:', data_type);

// hidden, text, email, date, number, select, checkbox, radio, textarea, etc
export let type: string = 'text'; // Input type

let set_input_type = (node) => {
    node.type = 'text';
};
let input_element_type_list = ['checkbox', 'date', 'email', 'hidden', 'number', 'text'];
if (input_element_type_list.includes(type)) {
    set_input_type = (node) => {
        node.type = type;
    };
} else {

}

console.log(`Input name=${name} value=${value} type=${type}`);

export let disabled: boolean = false; // attribute format: disabled
export let readonly: boolean = false; // attribute format: readonly="readonly"
export let required: boolean = false; // attribute format: required="required"
export let pattern: null|string = null;
export let focus: boolean = false;

/* *** END *** Core input settings */


/* *** BEGIN *** Container content, layout, and behavior */

// Input element specific label and placeholder
export let label: string = '';
export let label_date: string = 'Date';
export let label_time: string = 'Time';

export let placeholder: string = label;

// Input description for container
export let description: string = ''; // Description

// Layout and style
export let content_layout: string = ''; // Default empty is label wrap first, label_start, label_end, floating_input

export let class_li: string[] = []; // Classes for the input element
export let style: string = ''; // Style for the input element
export let display: string = ''; // Default empty is inline. inline, block, inline-block, break (break after)

export let label_class_li: string[] = [];
export let label_style: string = '';
export let label_display: string = ''; // Default empty is inline. inline, block, inline-block, break (break after)
export let label_location: string = 'start'; // start, end

export let description_location: string = 'end'; // start, end

export let container_class_li: string[] = []; // Classes for the container element
export let container_style: string = '';
export let container_display: string = ''; // Default empty is div block. inline, block, inline-block, break (break after)

export let multipart_class_li: string[] = [];

export let input_mode: null|string = null; // This is for special/custom modes like a rich text editor or search.
console.log(`Input input_mode=${input_mode}`);

/* *** END *** Container content, layout, and behavior */


/* *** BEGIN *** Input type specific */

// For checkbox, radio, and select option
export let option_li: any[] = []; // For checkbox, radio, and select inputs. Not specific to select options. List of key value pairs.
export let option_none: boolean = false; // If set to true then it will add an option using the select_option_none_text value
export let option_none_text: string = '-- Not Selected --'; // If set to true then it will add an option using the select_option_none_text value

// For textarea
export let size: number = null;
export let rows: number = 3;
export let cols: number = 80;
if (type == 'textarea') {
    console.log(`Input textarea size=${size} rows=${rows} cols=${cols}`);
}

// For custom date_time. Not "date" or "time" input type only.
export let date_time_tz: null|string = null;
let value_datetime = null;
let value_date = null;
let value_time = null;

if (type == 'date_time' && value) {
    console.log(`date_time value: ${value}`);
    value_datetime = new Date(value+'Z'); // Append the Z so it knows it is UTC (YYY-MM-DDTHH:mm:ssZ)
    console.log(value_datetime);

    value_datetime = util.iso_datetime_formatter(value_datetime,'datetime_iso');
    value_date = util.iso_datetime_formatter(value_datetime,'date_iso');
    value_time = util.iso_datetime_formatter(value_datetime,'time_iso');
    // value_date = value_datetime.toLocaleDateString();
    // value_date = value_datetime.toISOString();
    // value_time = value_datetime.toLocaleTimeString();
    // value_time = value_datetime.toISOString();
} else if (type == 'date_time') {
    console.log('No datetime value passed');
}
if (type == 'date_time') {
    console.log(`Input date_time value_datetime=${value_datetime} value_date=${value_date} value_time=${value_time} date_time_tz=${date_time_tz}`);
}

/* *** END *** Input type specific */


/* THIS NEEDS TO BE CLEANED UP */
let multipart_style;
let label_begin;
let checkbox_none;
let checked;
let checkbox_none_text;
let checkbox_li;
let radio_option_class_li;
let radio_none;
let radio_none_text;
let radio_li;
let value_new_line;
let select_option_none;
let select_option_li_lu_name;
let select_option_li;
let select_option_none_text;
/* ^^^ THIS NEEDS TO BE CLEANED UP ^^^ */


const dispatch = createEventDispatcher();

// type Input = {
//   name: string;
//   value: number;
// };
// let input: Input;

/*
 * container_element: span, div, section
 * container_class_li: []
 * content_layout: inline, break, bs_floating
 * content_order: label_value_description, value_label_description, label_description_value
 * label_class_li: []
 * class_li: []
 * start_desc: string
 * end_desc: string
 *
*/

onMount(() => {
    console.log(`** Element Mounted: ** Element Input v2: ${obj_type} ${obj_prop_name}; type=${data_type}; value=${value}`);

    if (input_mode == 'editor_basic_200') {
        rich_editor();
    }
});

// $: if (value) {
//     console.log(`input name=${name} value=${value}`);
//     console.log(typeof value);
// } else if (typeof value === 'undefined') {
//     console.log(`input name=${name} value=undefined; resetting to ''`);
//     value = '';
// }

$: if (disabled) { disabled=true; } // else { disabled=false; }
$: if (readonly) { readonly=true; } // else { readonly=false; }
$: if (required) { required=true; } // else { required=true; }

$: if (data_type) {
    console.log(`Input value data_type=${data_type}`);
} else if (data_type == 'json') {
    console.log(`Need to convert JSON object to string.`);
    if (typeof value === 'object') {
        value = JSON.stringify(value);
        console.log(`Value as data type (${data_type}): ${value}`);
    } else {
        console.log('Value is not an object type')
        console.log(typeof value);
    }
}

// // input_mode options: null or '' assume 'text', 'none', 'text', 'tel', 'url', 'email', 'numeric', 'decimal', and 'search'
// $: if (input_mode === null || input_mode == '') {
//     input_mode = 'text';
// } else if (input_mode == 'json') {
// } else if (input_mode == 'editor_basic_200') {
// }
// console.log(`input_mode=${input_mode}`);

$: if (container_display == '' || container_display == 'block') {
    console.log(`input name=${name} container_display=${container_display}`);
    // NOTE: Using a div will be displayed as block by default
} else if (container_display == 'inline') {
    console.log(`input name=${name} container_display=${container_display}`);
    container_class_li.push('container_inline');
    container_style = 'display: inline;'
} else if (container_display == 'inline-block') {
    console.log(`input name=${name} container_display=${container_display}`);
    container_class_li.push('container_inline_block');
    container_style = 'display: inline-block;'
} else if (typeof container_display === 'undefined') {
    console.log(`input name=${name} container_display=${container_display}`);
}

$: if (content_layout == '' || content_layout == 'label_begin') {
    console.log(`input name=${name} content_layout=${content_layout}`);
    // label_begin = true;
} else if (content_layout == 'label_end') {
    console.log(`input name=${name} content_layout=${content_layout}`);
    // label_begin = false;
} else if (content_layout == 'floating_input') {
    console.log(`input name=${name} content_layout=${content_layout}`);
    // label_begin = false;

    if (type != 'date_time') {
        container_class_li.push('form-floating'); // set the container class list
    } else {
        multipart_class_li.push('form-floating'); // set the container with multi input parts class list
    }

    if (type === 'select') {
        class_li.push('form-select'); // set the select class list
    } else {
        console.log('Make form-control???');
        class_li.push('form-control'); // set the input, select, textarea class list
    }

    if (type === 'textarea') {
        let estimate_row_rem = rows + 5.5;
        style = `height: calc(2px + ${estimate_row_rem}rem);`;
    }
} else if (typeof content_layout === 'undefined') {
    console.log(`input name=${name} content_layout=${content_layout}`);
}

// function handle_oninput_dispatch() {
//     console.log(input);
//     dispatch('oninput', {
//         name: input.name,
//         value: input.value,
//     });
// }

function handle_oninput_dispatch(event) {
    console.log(event.target);
    console.log(value);
    dispatch('oninput', {
        name: event.target.name,
        value: event.target.value,
    });
}


function rich_editor() {
    console.log('*** rich_editor() ***');


    // let test_element = $('.editor_basic_200');
    // console.log(test_element);

    // let textarea_element = document.querySelector('.editor_basic_200');

    // let toolbar_element = document.querySelector('.quilljs_toolbar');
    // console.log(toolbar_element);

    let editor_element = document.querySelector('.quilljs_editor');
    console.log(editor_element);

    // var editor = new Quill(editor_element, {
    //     modules: {
    //         'multi-cursor': true,
    //         'toolbar': { container: '#quilljs_toolbar' },
    //         // 'link-tooltip': true,
    //     },
    //     placeholder: 'Text goes here',
    //     theme: 'snow'
    // });

    var editor = new Quill(editor_element, {
        modules: {
            'multi-cursor': true,
            toolbar: [
                [{
                    header: [1, 2, false]
                }],
                ['bold', 'italic', 'underline'],
                ['image', 'code-block']
            ]
            // 'link-tooltip': true,
        },
        placeholder: 'Text goes here',
        theme: 'snow'
    });



    /*
    textarea_element.summernote(
    {
        tabsize: 4,
        height: 200,
        toolbar: [
            ['cleaner',['cleaner']], // The Button
            ['edit', ['undo', 'redo']],
            ['font', ['bold', 'italic', 'underline', 'strikethrough', 'superscript', 'subscript', 'clear']],
            ['color', ['forecolor']],
            ['para', ['ul', 'ol', 'paragraph']],
            ['insert', ['link']],
            ['view', ['codeview', 'help']]
        ],
        cleaner:{
            action: 'both', // both|button|paste 'button' only cleans via toolbar button, 'paste' only clean when pasting content, both does both options.
            newline: '<br>', // Summernote's default is to use '<p><br></p>'
            notStyle: '', // Position of Notification
            icon: '<i class="fas fa-paste"></i>',
            keepHtml: true, // Remove all Html formats
            keepOnlyTags: ['<p>', '<br>', '<ul>', '<li>', '<b>', '<strong>','<i>', '<a>'], // If keepHtml is true, remove all tags except these
            keepClasses: false, // Remove Classes
            badTags: ['style', 'script', 'applet', 'embed', 'noframes', 'noscript', 'html'], // Remove full tags with contents
            badAttributes: ['style', 'start'], // Remove attributes from remaining tags
            limitChars: false, // 0/false|# 0/false disables option
            limitDisplay: 'none', // none|text|html|both
            limitStop: false // true/false
        }
    });
    */
}
</script>

<div class="element element_input {container_class_li.join(' ')}" style={container_style}>

{#if type === 'email' || type === 'date' || type === 'number' || type === 'tel'  || type === 'text' || type === 'time' || type === 'url' }
    {#if (content_layout == 'label_start' && label)}
        <label for={id} class={label_class_li.join(' ')} style={label_style}>{label}</label>
    {/if}

    <input {id} {name} class={class_li.join(' ')} {style} use:set_input_type {placeholder} {size} {pattern} {readonly} {disabled} {required} inputmode={input_mode} data-id_random={id_random} data-obj_type={obj_type} data-obj_prop_name={obj_prop_name} use:util.set_focus={focus} on:input={handle_oninput_dispatch} bind:value={value} />

    {#if (content_layout != 'label_start' && label)}
        <label for={id} class={label_class_li.join(' ')} style={label_style}>{label}</label>
    {/if}

    <span>{description}</span>

{:else if type === 'date_time' }
    {#if (content_layout == 'label_start' && label)}
        <span class={label_class_li.join(' ')} style={label_style}>{label}</span>
        <!-- <label for={id} class={label_class_li.join(' ')} style={label_style}>{label}</label> -->
    {/if}

    <div class="element_input multipart {multipart_class_li.join(' ')}" style={multipart_style}>
        {#if label_begin}
            <label for={`${id}_date`} class={label_class_li.join(' ')} style={label_style}>{label_date}</label>
        {/if}

        <input id={id+'_date'} name={name+'_date'} {style} class={class_li.join(' ')} type="date" value={value_date} {placeholder} {readonly} {disabled} {required} data-id_random={id_random} data-obj_type={obj_type} data-obj_prop_name={obj_prop_name} on:input={handle_oninput_dispatch} />

        {#if !label_begin}
            <label for={`${id}_date`} class={label_class_li.join(' ')} style={label_style}>{label_date}</label>
        {/if}
    </div>

    <div class="element_input multipart {multipart_class_li.join(' ')}" style={multipart_style}>
        {#if label_begin}
            <label for={`${id}_time`} class={label_class_li.join(' ')} style={label_style}>{label_time}</label>
        {/if}

        <input id={id+'_time'} name={name+'_time'} {style} class={class_li.join(' ')} type="time" value={value_time} {placeholder} {readonly} {disabled} {required} data-id_random={id_random} data-obj_type={obj_type} data-obj_prop_name={obj_prop_name} on:input={handle_oninput_dispatch} />

        {#if !label_begin}
            <label for={`${id}_time`} class={label_class_li.join(' ')} style={label_style}>{label_time}</label>
        {/if}
    </div>


    {#if (content_layout != 'label_start' && label)}
        <span class={label_class_li.join(' ')} style={label_style}>{label}</span>
        <!-- <label for={id} class={label_class_li.join(' ')} style={label_style}>{label}</label> -->
    {/if}

    <span>{description}</span>

{:else if type === 'checkbox' }
    {#if checkbox_none}
        {#if !value}
            {checked='checked'}
        {/if}
        <label>{checkbox_none_text}
        <input {name} type="checkbox" value="" {readonly} {disabled} {required} {checked} on:input={handle_oninput_dispatch} />
        </label>
    {/if}
    {#if checkbox_li.length}
        {#if (content_layout == 'label_start' && label)}
            <span class="input_container_label label_begin">{label}</span>
        {/if}

        {#each Object.entries(checkbox_li) as [li_key, li_value]}
            {#if li_key.toString() === value.toString() }
                <label>{li_value}
                    <input {name} type="checkbox" value="{li_key}" checked on:input={handle_oninput_dispatch}>
                </label>
            {:else}
                <label>{li_value}
                    <input {name} type="checkbox" value="{li_key}" on:input={handle_oninput_dispatch}>
                </label>
            {/if}
        {/each}

        {#if (content_layout != 'label_start' && label)}
            <span class="input_container_label label_end">{label}</span>
        {/if}
    {:else}
        {#if label_begin}
            <label for={id} class={label_class_li.join(' ')} style={label_style}>{label}</label>
        {/if}

        <input {id} {name} class={class_li.join(' ')} {style} type="checkbox" {value} {placeholder} {readonly} {disabled} {required} data-id_random={id_random} data-obj_type={obj_type} data-obj_prop_name={obj_prop_name} {checked} on:input={handle_oninput_dispatch} />
    {/if}

    <span>{description}</span>

{:else if type === 'radio' }
    {#if radio_none}
        {#if !value}
            {checked='checked'}
        {/if}
        <label class={radio_option_class_li.join(' ')}>{@html radio_none_text}
        <input {name} type="radio" value="" {readonly} {disabled} {required} {checked} on:input={handle_oninput_dispatch} />
        </label>
    {/if}
    {#if radio_li}
        {#if (content_layout == 'label_start' && label)}
            <span class="input_container_label label_begin">{label}:</span>
        {/if}

        <span class="input_container_radio_options">
        {#each Object.entries(radio_li) as [li_key, li_value]}
            {#if value === null} <!-- If null then no option should be selected. -->
                <label>{@html li_value}
                    <input {name} type="radio" bind:group={value} value="{li_key}" on:input={handle_oninput_dispatch}>
                </label>
            {:else if ( li_key.toString() === value.toString() || (li_key == 'true' && value == true) || (li_key == 'false' && value == false) ) }
                <label>{@html li_value}
                    <input {name} type="radio" bind:group={value} value="{li_key}" checked on:input={handle_oninput_dispatch}> Z
                </label>
            {:else}
                <label>{@html li_value}
                    <input {name} type="radio" bind:group={value} value="{li_key}" on:input={handle_oninput_dispatch}>
                </label>
            {/if}

            <!-- <label>{@html li_value}
                <input {name} type="radio" bind:group={value} value="{li_key}" on:input={handle_oninput_dispatch}>
            </label> -->
        {/each}
        </span>

        {#if !label_begin}
            <span class="input_container_label label_end">{label}:</span>
        {/if}
    {:else}
        {#if label_begin}
            <label for={id} class={label_class_li.join(' ')} style={label_style}>{@html label}</label>
        {/if}

        <input {id} {name} class={class_li.join(' ')} {style} type="radio" {value} {placeholder} {readonly} {disabled} {required} data-id_random={id_random} data-obj_type={obj_type} data-obj_prop_name={obj_prop_name} {checked} on:input={handle_oninput_dispatch} />

        {#if !label_begin}
            <label for={id} class={label_class_li.join(' ')} style={label_style}>{@html label}</label>
        {/if}
    {/if}

    <span>{description}</span>

{:else if type === 'textarea'}
    {#if label_begin}
        <label for={id} class={label_class_li.join(' ')} style={label_style}>{label}</label>
    {/if}

    {#if value_new_line}<br>{/if}
    <textarea {id} {name} class={class_li.join(' ')} {style} bind:value={value} {placeholder} {readonly} {disabled} {required} {rows} {cols} data-id_random={id_random} data-obj_type={obj_type} data-obj_prop_name={obj_prop_name} on:input={handle_oninput_dispatch}></textarea>
    <!-- rows="" cols="" maxlength="" -->

    {#if !label_begin}
        <label for={id} class={label_class_li.join(' ')} style={label_style}>{label}</label>
    {/if}

    <span>{description}</span>

{:else if type === 'hidden'}
    <input {id} {name} class={class_li.join(' ')} type="hidden" bind:value={value} {placeholder} {readonly} {disabled} {required} data-id_random={id_random} data-obj_type={obj_type} data-obj_prop_name={obj_prop_name} />

{:else if type === 'select'}
    {#if label_begin}
        <label for={id} class={label_class_li.join(' ')} style={label_style}>
            {label}
            <!-- {#if value} <span class="label_select_value">{value}</span>{/if} -->
        </label>
    {/if}

    <select {id} {name} class={class_li.join(' ')} {style} {readonly} {disabled} {required} data-id_random={id_random} data-obj_type={obj_type} data-obj_prop_name={obj_prop_name} on:input={handle_oninput_dispatch}>
        {#if select_option_none}
            <option value="">{select_option_none_text}</option>
        {/if}
        {#if select_option_li_lu_name}
            <!-- <Select_element_lu lu_list_name={select_option_li_lu_name} params={select_option_li_lu_params} value_field_name={select_option_lu_value_field_name} text_field_name={select_option_lu_text_field_name} slct_value={value} /> -->
        {:else}
            {#each Object.entries(select_option_li) as [li_key, li_value]}
                {#if value === null} <!-- If null then no option should be selected. -->
                    <option value="{li_key}">
                        {li_value}
                    </option>
                {:else if li_key.toString() === value.toString() }
                    <option value="{li_key}" selected>
                        {li_value}
                    </option>
                {:else}
                    <option value="{li_key}">
                        {li_value}
                    </option>
                {/if}
            {/each}
        {/if}
    </select>

    {#if !label_begin}
        <label for={id} class={label_class_li.join(' ')} style={label_style}>
            {label}
            {#if value} <span class="label_select_value">{value}</span>{/if}
        </label>
    {/if}

    <span>{description}</span>
{/if}

<slot name="more_html">
</slot>

</div>


<style>
.container_inline {
    display: inline;
}
</style>