<script lang="ts">
/**
 * ae_comp__journal_entry_obj_file_li.svelte
 * Manages and displays file attachments for Journal Entries.
 * Ported/Refactored 2026-01-26 to include View mode and strictly snake_case.
 */

// *** Import Lucide Icons
import {
    Download,
    ExternalLink,
    FileUp,
    LoaderCircle,
    Paperclip,
    RefreshCw,
    Trash2
} from '@lucide/svelte';
// *** Import Aether specific variables and functions
import type { key_val } from '$lib/stores/ae_stores';
import { ae_util } from '$lib/ae_utils/ae_utils';
import { core_func } from '$lib/ae_core/ae_core_functions';
import { api } from '$lib/ae_api/api';
import {
    ae_snip,
    ae_loc,
    ae_sess,
    ae_api,
    ae_trig,
    slct,
    slct_trigger
} from '$lib/stores/ae_stores';
import {
    journals_loc,
    journals_sess,
    journals_slct,
    journals_trig,
    journals_prom
} from '$lib/ae_journals/ae_journals_stores';
import { journals_func } from '$lib/ae_journals/ae_journals_functions';

import Comp_hosted_files_upload from '$lib/elements/ae_comp__hosted_files_upload.svelte';
import Element_manage_hosted_file_li_wrap from '$lib/elements/element_manage_hosted_file_li_all.svelte';
import AE_Comp_Hosted_Files_Download_Button from '$lib/elements/ae_comp__hosted_files_download_button.svelte';

interface Props {
    log_lvl?: number;
    link_to_type: string;
    link_to_id: string;
    lq__journal_entry_obj: any;
}

let {
    log_lvl = 0,
    link_to_type,
    link_to_id,
    lq__journal_entry_obj
}: Props = $props();

// *** State
let ae_promises: Record<string, any> = $state({});
let upload_complete: boolean = $state(false);

// Selection state for "Select Existing" mode
let slct_hosted_file_kv: key_val = $state({});
let slct_hosted_file_id: string | null = $state(null);
let slct_hosted_file_obj: any = $state(null);

// Selection state for "Upload" mode
let slct_hosted_file_id_li: string[] = $state([]);
let slct_hosted_file_obj_li: any[] = $state([]);

// Derived: Unified file list from both legacy data_json and new linked_li_json
let unified_file_li = $derived.by(() => {
    const entry = $lq__journal_entry_obj;
    if (!entry) return [];

    let files: any[] = [];

    // 1. Check new linked_li_json first
    if (entry.linked_li_json && Array.isArray(entry.linked_li_json)) {
        files = [...entry.linked_li_json];
    }

    // 2. Merge with legacy hosted_file_kv if not already present
    if (entry.data_json?.hosted_file_kv) {
        Object.entries(entry.data_json.hosted_file_kv).forEach(
            ([id, obj]: [string, any]) => {
                if (
                    !files.find(
                        (f) =>
                            (f.hosted_file_id || f.id || f.hosted_file_id) ===
                            id
                    )
                ) {
                    files.push({ ...obj, id: id });
                }
            }
        );
    }

    return files;
});

async function update_journal_entry(updated_files: any[]) {
    let data_kv: key_val = {
        linked_li_json: JSON.stringify(updated_files),
        // Maintain data_json.hosted_file_kv for backward compatibility
        data_json: {
            ...$lq__journal_entry_obj?.data_json,
            hosted_file_kv: Object.fromEntries(
                updated_files.map((f) => [
                    f.hosted_file_id || f.id || f.hosted_file_id,
                    f
                ])
            )
        }
    };

    try {
        await journals_func.update_ae_obj__journal_entry({
            api_cfg: $ae_api,
            journal_entry_id: $lq__journal_entry_obj?.journal_entry_id,
            data_kv: data_kv,
            log_lvl: 1
        });
    } catch (error) {
        console.error('Error updating journal entry files:', error);
    }
}

// *** Effects for File Management

// Handle "Select Existing" completion
$effect(() => {
    if ($lq__journal_entry_obj && slct_hosted_file_id && slct_hosted_file_obj) {
        const new_file = {
            ...slct_hosted_file_obj,
            id: slct_hosted_file_id
        };
        const updated_li = [...unified_file_li, new_file];

        slct_hosted_file_id = null;
        slct_hosted_file_obj = null;

        update_journal_entry(updated_li);
    }
});

// Handle "Upload" completion
$effect(() => {
    if (
        $lq__journal_entry_obj &&
        upload_complete &&
        slct_hosted_file_id_li.length
    ) {
        const new_files = slct_hosted_file_id_li.map((id) => ({
            ...slct_hosted_file_kv[id],
            id: id
        }));
        const updated_li = [...unified_file_li, ...new_files];

        slct_hosted_file_id_li = [];
        upload_complete = false;

        update_journal_entry(updated_li);
    }
});

async function handle_remove_file(file_id: string) {
    if (!confirm('Are you sure you want to remove this file attachment?'))
        return;

    const updated_li = unified_file_li.filter(
        (f) => (f.hosted_file_id || f.id || f.hosted_file_id) !== file_id
    );

    // Also perform physical/orphan deletion if admin
    if ($ae_loc.administrator_access) {
        await core_func.delete_ae_obj_id__hosted_file({
            api_cfg: $ae_api,
            hosted_file_id: file_id,
            link_to_type: link_to_type,
            link_to_id: link_to_id,
            rm_orphan: true,
            fake_delete: false,
            log_lvl
        });
    }

    await update_journal_entry(updated_li);
}
</script>

{#if $ae_loc.edit_mode || unified_file_li.length > 0}
    <section class="ae_section journal_entry_files my-2 w-full space-y-4">
        <!-- Header -->
        <div
            class="border-surface-500/20 flex items-center justify-between border-b pb-2">
            <h3 class="h3 flex items-center gap-2 text-lg font-bold">
                <Paperclip size="1.1em" />
                Attachments
                {#if unified_file_li.length}
                    <span class="badge preset-tonal-surface text-xs"
                        >{unified_file_li.length}</span>
                {/if}
            </h3>

            {#if $ae_loc.edit_mode}
                <button
                    type="button"
                    class="btn btn-sm preset-tonal-warning font-semibold"
                    onclick={() => {
                        $ae_sess.files.add_to_use_files_method =
                            $ae_sess.files.add_to_use_files_method === 'upload'
                                ? 'select'
                                : 'upload';
                    }}>
                    <RefreshCw size="1em" class="mr-2" />
                    {$ae_sess.files.add_to_use_files_method === 'select'
                        ? 'Switch to Upload'
                        : 'Switch to Select'}
                </button>
            {/if}
        </div>

        <!-- File Grid -->
        {#if unified_file_li.length}
            <div class="grid grid-cols-1 gap-3 md:grid-cols-2 lg:grid-cols-3">
                {#each unified_file_li as file (file.hosted_file_id ?? file.id)}
                    {@const file_id =
                        file.hosted_file_id || file.id || file.hosted_file_id}
                    <div
                        class="bg-surface-50-950 border-surface-500/10 group hover:border-primary-500 flex items-center justify-between rounded-xl border p-3 shadow-sm transition-all">
                        <div
                            class="flex grow items-center gap-3 overflow-hidden">
                            <AE_Comp_Hosted_Files_Download_Button
                                hosted_file_id={file_id}
                                hosted_file_obj={file}
                                color="primary"
                                variant="tonal"
                                classes="w-full !justify-start !px-2"
                                show_divider={true}
                                max_filename={25}
                                show_direct_download={$ae_loc.trusted_access &&
                                    $ae_loc.edit_mode} />
                        </div>

                        <div class="ml-2 flex items-center gap-1">
                            {#if $ae_loc.edit_mode}
                                <button
                                    type="button"
                                    class="btn btn-sm preset-tonal-error"
                                    onclick={() => handle_remove_file(file_id)}
                                    title="Remove attachment">
                                    <Trash2 size="1.1em" />
                                </button>
                            {/if}
                        </div>
                    </div>
                {/each}
            </div>
        {/if}

        <!-- Edit/Management Tools -->
        {#if $ae_loc.edit_mode}
            <div
                class="bg-surface-500/5 border-surface-500/20 mt-4 rounded-2xl border-2 border-dashed p-4">
                {#if $ae_sess.files.add_to_use_files_method === 'upload'}
                    <Comp_hosted_files_upload
                        {link_to_type}
                        {link_to_id}
                        bind:upload_complete
                        bind:hosted_file_id_li={slct_hosted_file_id_li}
                        bind:hosted_file_obj_li={slct_hosted_file_obj_li}
                        bind:hosted_file_obj_kv={slct_hosted_file_kv}
                        accept="*/*"
                        class_li="!max-w-none">
                        {#snippet label()}
                            <div class="flex flex-col items-center gap-2 py-2">
                                <div
                                    class="bg-primary-500/10 text-primary-500 rounded-full p-3">
                                    <FileUp size="1.8em" />
                                </div>
                                <div class="text-center">
                                    <p class="font-bold">
                                        Upload new attachment
                                    </p>
                                    <p class="text-xs opacity-60">
                                        Drag and drop or click to browse
                                    </p>
                                </div>
                            </div>
                        {/snippet}
                    </Comp_hosted_files_upload>
                {:else}
                    <div class="space-y-2">
                        <p class="ml-1 text-sm font-bold opacity-70">
                            Select from existing hosted files:
                        </p>
                        <Element_manage_hosted_file_li_wrap
                            link_to_type={'account'}
                            link_to_id={$ae_loc?.account_id}
                            allow_basic={true}
                            allow_moderator={true}
                            class_li={''}
                            bind:slct_hosted_file_kv
                            bind:slct_hosted_file_id
                            bind:slct_hosted_file_obj />
                    </div>
                {/if}
            </div>
        {/if}
    </section>
{/if}
