<script lang="ts">
    // untrack import removed — task_id sync now uses direct $effect (no untrack needed)
    // Imports
    // Import components and elements
    import * as Lucide from 'lucide-svelte';
    import Element_input_files_tbl from '$lib/elements/element_input_files_tbl.svelte';

    // Import storage, functions, and libraries
    import type { key_val } from '$lib/stores/ae_stores';

    import { api } from '$lib/api/api';
    import {
        ae_snip,
        ae_loc,
        ae_sess,
        ae_api,
        ae_trig,
        slct,
        slct_trigger
    } from '$lib/stores/ae_stores';

    // Exports

    interface Props {
        log_lvl?: number;
        // Expecting these for link_to_type: 'event', 'event_location', 'archive_content', etc
        link_to_type: string;
        link_to_id: string;
        input_name?: string;
        multiple?: boolean;
        required?: boolean;
        accept?: string;
        class_li_default?: string;
        class_li?: string;
        input_class_li?: string[];
        table_class_li?: string[];
        upload_complete?: boolean;
        submit_status?: null | string;
        hosted_file_id_li?: string[];
        hosted_file_obj_li?: any[];
        hosted_file_obj_kv?: key_val;
        label?: import('svelte').Snippet;
    }

    let {
        log_lvl = 0,
        link_to_type,
        link_to_id,
        input_name = 'file_list',
        multiple = true,
        required = true,
        accept = 'audio/*, image/*, video/*, .bak, .cfg, .css, .csv, .doc, .docx, .gz, .htm, .html, .ini, .iso, .j2, .json, .key, .keynote, .md, .pdf, .ppt, .pptx, .rar, .rtf, .sql, .svelte, ttf, .txt, .xls, .xlsx, .xz, .zip, .bin, .dmg, .exe, .js, .msi, .php, .py, .sh',
        class_li_default = 'flex flex-col gap-1 items-center justify-center w-full max-w-2xl mx-auto my-1',
        class_li = '',
        input_class_li = ['file_drop_area'],
        table_class_li = ['table', 'table-sm', 'table-striped', '', 'text-sm'],
        upload_complete = $bindable(false),
        submit_status = $bindable(null),
        hosted_file_id_li = $bindable([]),
        hosted_file_obj_li = $bindable([]),
        hosted_file_obj_kv = $bindable({}),
        label
    }: Props = $props();

    // Local Variables
    let task_id: string = $state('');
    let input_file_list: any = $state(null);
    let ae_promises: key_val = $state({}); // Promise<any>;
    let ae_triggers: key_val = {};

    let input_element_id = 'ae_comp__hosted_files_upload__input';

    $effect(() => {
        if (log_lvl) {
            console.log(`*** ae_comp__hosted_files_upload.svelte ***`);
            console.log(`link_to_type: ${link_to_type} link_to_id: ${link_to_id}`);
        }
    });

    $effect(() => {
        // Sync task_id with link_to_id prop so it resets when navigating to a different object.
        task_id = link_to_id;
    });

    // *** Functions and Logic
    async function handle_submit_form_files(event: SubmitEvent) {
        console.log('*** handle_submit_form() ***');
        event.preventDefault();

        if (!event) {
            return;
        }

        $ae_sess.files.disable_submit__hosted_file_obj = true;
        $ae_sess.files.submit_status = 'saving';
        submit_status = 'saving';
        upload_complete = false;

        hosted_file_id_li = [];
        hosted_file_obj_li = [];
        hosted_file_obj_kv = {};

        let hosted_file_results;

        const target = event.currentTarget as HTMLFormElement;
        const file_input = target ? (target[input_element_id] as HTMLInputElement) : null;

        if (
            target &&
            file_input &&
            file_input.files &&
            file_input.files.length > 0
        ) {
            task_id = link_to_id; // Ideally this should be the file hash, but we may be uploading multiple files at once. This should be done with a loop instead?

            // Loop through each file and upload them individually in event.target[input_element_id].files
            // The task_id should be the file hash.
            // processed_file_list[i] has the file hash_sha256, hash_sha256_match, warnings, uploaded, uploaded_bytes, filename, and file_size_bytes.
            for (let i = 0; i < file_input.files.length; i++) {
                let tmp_file = file_input.files[i];

                task_id = $ae_sess.files.processed_file_list[i].hash_sha256;

                // hosted_file_results = await handle_input_upload_files([tmp_file], task_id);
                hosted_file_results = await handle_input_upload_files({
                    input_upload_files: [tmp_file],
                    task_id: task_id
                });

                if (hosted_file_results) {
                    console.log(`hosted_file_results:`, hosted_file_results);
                } else {
                    console.log(`hosted_file_results:`, hosted_file_results);
                }
            }
            // hosted_file_results = await handle_input_upload_files(event.target[input_element_id].files, task_id);
            $ae_sess.files.processed_file_list = [];
            $ae_sess = $ae_sess; // Is this needed? 2025-03-17
            target.reset();
            // await tick();

            if (log_lvl) {
                console.log(`hosted_file_id_li: ${hosted_file_id_li}`, hosted_file_id_li);
            } else if (log_lvl > 1) {
                console.log('hosted_file_results:', hosted_file_results);
            }
        }

        $ae_sess.files.disable_submit__hosted_file_obj = false;
        $ae_sess.files.submit_status = 'saved';
        submit_status = 'saved';
        upload_complete = true;
    }

    async function handle_input_upload_files({
        input_upload_files,
        task_id
    }: {
        input_upload_files: any[];
        task_id: string;
    }) {
        console.log('*** handle_input_upload_files() ***');

        const form_data = new FormData();

        form_data.append('account_id', $ae_loc.account_id);
        form_data.append('link_to_type', link_to_type);
        form_data.append('link_to_id', link_to_id);

        for (let i = 0; i < input_upload_files.length; i++) {
            form_data.append(`file_list`, input_upload_files[i]);
        }

        // hash_sha256, uploaded, uploaded_bytes
        // $ae_sess.files.processed_file_list[i] = {
        //     ...$ae_sess.files.processed_file_list[i],
        //     uploaded: $ae_sess.api_upload_kv[link_to_id].percent_completed,
        //     uploaded_bytes: $ae_sess.api_upload_kv[link_to_id].uploaded_bytes,
        // };

        let params = null;

        let endpoint = '/hosted_file/upload_files';

        console.log(form_data);

        params = null;

        // Uncomment and the post_promise is not seen by the "await" below
        // post_promise = await api.post_object({api_cfg: $cfg.api, endpoint: endpoint, params: params, data:form_data});
        // Uncomment so that the post_promise is not seen by the "await" below
        ae_promises.upload__hosted_file_obj = api
            .post_object({
                api_cfg: $ae_api,
                endpoint: endpoint,
                // params: params,
                form_data: form_data,
                task_id: task_id,
                log_lvl: log_lvl
                // retry_count: 1,
            })
            .then(async function (result) {
                // WARNING!!!! ONLY ONE FILE IS EXPECTED TO BE UPLOADED AT A TIME!!!
                // NOTE: The /hosted_file/upload_files endpoint will always return a list of successful files uploaded. In this case we are only uploading one file and expecting a list of one item.
                let x = 0;
                console.log(result[x]);
                let hosted_file_obj = result[x];

                let hosted_file_id = hosted_file_obj.hosted_file_id;

                hosted_file_id_li.push(hosted_file_id);
                hosted_file_obj_li.push(hosted_file_obj);

                let hosted_file_data: key_val = {};
                hosted_file_data['id'] = hosted_file_id; // Same as the hosted_file_id
                hosted_file_data['hosted_file_id'] = hosted_file_id;
                hosted_file_data['for_type'] = link_to_type;
                hosted_file_data['for_id'] = link_to_id;
                hosted_file_data['hash_sha256'] = hosted_file_obj.hash_sha256;
                hosted_file_data['filename'] = hosted_file_obj.filename;
                hosted_file_data['extension'] = hosted_file_obj.extension;
                hosted_file_data['content_type'] = hosted_file_obj.content_type;
                hosted_file_data['size'] = hosted_file_obj.size;
                hosted_file_data['enable'] = true;
                hosted_file_data['created_on'] = hosted_file_obj.created_on;
                hosted_file_data['updated_on'] = hosted_file_obj.updated_on;
                console.log(hosted_file_data);

                hosted_file_obj_kv[hosted_file_id] = hosted_file_data;

                if (log_lvl) {
                    console.log(`hosted_file_data:`, hosted_file_data);
                }

                return hosted_file_data;

                // $ae_sess.files.new_upload_list[i].uploaded_bytes = 10; // fake 10 bytes at least...

                // let event_file_id = await events_func.create_hosted_file_obj_from_hosted_file_async({
                //     api_cfg: $ae_api,
                //     hosted_file_id: hosted_file_id,
                //     data: event_file_data,
                //     log_lvl: log_lvl
                //     })
                // .then(function (create_result) {
                //     console.log(create_result); // NOTE: This should be the event_file_id string
                //     // let event_file_id = create_result;
                //     return create_result;
                // });

                // return event_file_id;
            })
            // .then(function (hosted_file_data) {
            //     return hosted_file_data;
            // })
            .catch(function (error: any) {
                console.log('Something went wrong.');
                console.log(error);
                return false;
            })
            .finally(function () {
                $slct_trigger = 'load__hosted_file_obj_li';
            });

        if (log_lvl) {
            console.log(`Waiting for upload__hosted_file_obj promise...`);
        }
        let hosted_file_result = ae_promises.upload__hosted_file_obj;

        return hosted_file_result;
    }
</script>

<!-- class:hidden={!$ae_loc.trusted_access} -->
<form onsubmit={handle_submit_form_files} class="{class_li_default} {class_li}">
    {#await ae_promises.upload__hosted_file_obj}
        <div class="text-lg flex flex-row gap-1 items-center justify-center">
            <Lucide.LoaderCircle class="animate-spin m-1" />
            <span class="">
                Uploading
                {#if $ae_sess.api_upload_kv[task_id]}
                    {$ae_sess.api_upload_kv[task_id].percent_completed}%
                {/if}
            </span>
        </div>
    {/await}

    <label
        for="ae_comp__hosted_files_upload__input"
        class="svelte_input_file_label text-center"
        class:hidden={$ae_sess.files.disable_submit__hosted_file_obj}
    >
        {#if label}{@render label()}{:else}
            <div class="flex items-center justify-center gap-2 mb-2">
                <Lucide.Upload class="text-primary-500" />
                <strong class="preset-tonal-primary px-3 py-1 rounded-full">Select Files</strong>
            </div>
            <span class="text-sm text-gray-600 dark:text-gray-400 italic">
                <strong>Supported formats</strong><br />
                (PowerPoint, Keynote, PDF, Media, etc)
            </span>
        {/if}
    </label>

    <input
        id={input_element_id}
        type="file"
        bind:files={input_file_list}
        {multiple}
        {required}
        {accept}
        name={input_name}
        class="
            svelte_input_file_element
            file-dropzone-input
            px-1
            block w-full text-lg
            preset-filled-surface-50-950
            text-surface-900 dark:text-surface-100
            border border-surface-300 dark:border-surface-700 rounded-lg
            cursor-pointer
            focus:outline-hidden focus:ring-2 focus:ring-primary-500
            {input_class_li.join(' ')}
            "
        class:hidden={$ae_sess.files.disable_submit__hosted_file_obj}
    />

    <Element_input_files_tbl
        bind:input_file_list
        bind:file_list_status={$ae_sess.files.status__file_list}
        bind:processed_file_list={$ae_sess.files.processed_file_list}
        {table_class_li}
    />

    <button
        type="submit"
        class="btn btn-lg btn-primary preset-tonal-primary border border-primary-500 hover:preset-tonal-success hover:border-success-500 w-54"
        disabled={$ae_sess.files.disable_submit__hosted_file_obj ||
            $ae_sess.files.status__file_list != 'ready'}
    >
        {#await ae_promises.upload__hosted_file_obj}
            <Lucide.LoaderCircle class="animate-spin m-1" />
            <span class="">
                {#if $ae_sess.api_upload_kv[task_id]}
                    {$ae_sess.api_upload_kv[task_id].percent_completed}%
                {:else}
                    ...
                {/if}
            </span>
        {:then}
            <Lucide.UploadCloud class="m-1" size={20} />
            <span class="text-sm"> Upload </span>
            <span class="grow font-bold ml-2">
                {#if $ae_sess.files.processed_file_list?.length > 0}
                    {$ae_sess.files.processed_file_list.length} { $ae_sess.files.processed_file_list.length === 1 ? 'file' : 'files' }
                {:else}
                    <span class="text-xs"> 0 </span>
                {/if}
            </span>
        {/await}
    </button>
</form>
