<script lang="ts">
/**
 * AE_AITools.svelte
 * GENERIC Aether AI Toolset (Runes/Svelte 5)
 * Extracted logic from Journals module to be system-wide.
 */
import OpenAI from 'openai';
import { Modal } from 'flowbite-svelte';
import {
    Bot,
    BotMessageSquare,
    Eye,
    EyeOff,
    Globe,
    Copy,
    Loader,
    Save,
    FilePenLine,
    RotateCcw,
    Settings,
} from '@lucide/svelte';
import { ae_loc } from '$lib/stores/ae_stores';
import AE_Comp_Editor_CodeMirror from '$lib/elements/element_editor_codemirror.svelte';

interface Props {
    // Core Props
    content: string | null | undefined; // The text to summarize/analyze
    summary: string | null | undefined; // The result (bindable)

    // Configuration (Bindable for global settings persistence)
    model?: string;
    baseUrl?: string;
    token?: string;
    systemPrompt?: string;
    maxTokens?: number;
    temperature?: number;

    // Callbacks
    onSave?: (newSummary: string) => void;
    onSyncConfig?: () => void; // Optional: callback to sync from global site config

    // UI Customization
    buttonClass?: string;
    log_lvl?: number;
}

let {
    content,
    summary = $bindable(),
    model = $bindable(),
    baseUrl = $bindable(),
    token = $bindable(),
    systemPrompt = $bindable(),
    maxTokens = $bindable(),
    temperature = $bindable(),
    onSave,
    onSyncConfig,
    buttonClass = 'btn btn-sm preset-tonal-primary shadow-lg hover:scale-105 transition-all',
    log_lvl = 0
}: Props = $props();

// Apply defaults if undefined (Safe for Svelte 5 Runes)
if (model === undefined) model = 'dgrzone-deepseek-8b-quick';
if (baseUrl === undefined) baseUrl = 'https://ai.dgrzone.com/api';
if (token === undefined) token = '';
if (systemPrompt === undefined) systemPrompt = 'You are a helpful assistant.';
if (maxTokens === undefined) maxTokens = 512;
if (temperature === undefined) temperature = 0.7;

// Internal State
let ae_promises = $state<Promise<unknown> | null>(null);
let show_modal = $state(false);
let active_tab: 'result' | 'settings' = $state('result');
let tmp_summary = $state('');
let show_api_token = $state(false);

const panel_class = 'space-y-4 rounded-xl border border-surface-500/20 bg-surface-500/5 p-4 shadow-sm';
const panel_title_class = 'flex items-center gap-2 border-b border-surface-500/20 pb-2 text-lg font-bold';
const tab_button_base_class = 'btn btn-sm border transition-all duration-200';
const tab_button_active_class = 'border-surface-200-800 bg-surface-200-800 text-surface-950-50 shadow-sm';
const tab_button_inactive_class = 'border-transparent bg-surface-50-900/60 text-surface-600-400 hover:border-surface-200-800 hover:bg-surface-100-900 hover:text-surface-950-50';

function tab_button_class(is_active: boolean): string {
    return `${tab_button_base_class} ${is_active ? tab_button_active_class : tab_button_inactive_class}`;
}

async function generate_ai_result() {
    if (!content) {
        alert('No content available to analyze.');
        return;
    }

    active_tab = 'result';

    // If no token is provided, trigger a "Demo Mode" placeholder after a fake delay
    if (!token || token === '') {
        if (log_lvl > 0) {
            console.log('AE_AITools: No token provided. Entering Demo Mode.');
        }
        ae_promises = new Promise((resolve) => {
            setTimeout(() => {
                tmp_summary = `### AI Summary (DEMO MODE)\n\nThis is a placeholder summary because no API token was provided in the settings. \n\n**Original Content Length:** ${content.length} characters.\n\n**System Prompt:** ${systemPrompt}\n\n**Model:** ${model}`;
                show_modal = true;
                resolve(true);
            }, 1500);
        });
        return;
    }

    const ai_client = new OpenAI({
        apiKey: token,
        baseURL: baseUrl,
        dangerouslyAllowBrowser: true
    });

    try {
        ae_promises = ai_client.chat.completions
            .create({
                model: model || 'dgrzone-deepseek-8b-quick',
                max_tokens: maxTokens,
                temperature: temperature,
                messages: [
                    {
                        role: 'system',
                        content: systemPrompt || 'You are a helpful assistant.'
                    },
                    { role: 'user', content: content }
                ]
            })
            .then((resp) => {
                const result =
                    resp?.choices?.[0]?.message?.content ||
                    'No result generated.';
                tmp_summary = result;
                show_modal = true;
            });
    } catch (err: unknown) {
        if (log_lvl > 0) {
            console.error('AE_AITools: AI Error:', err);
        }
        const err_msg = err instanceof Error ? err.message : String(err);
        // Even on error, show the modal with the error message so the UI can be inspected
        tmp_summary = `### AI Error\n\nFailed to connect to the AI service.\n\n**Error:** ${err_msg}\n\nCheck your Settings tab for Base URL and Token configuration.`;
        show_modal = true;
        ae_promises = Promise.resolve();
    }
}

function handle_save() {
    summary = tmp_summary;
    if (onSave) onSave(tmp_summary);
    show_modal = false;
}
</script>

<div class="ae-ai-tools-wrapper inline-flex items-center gap-1">
    <!-- Trigger Button -->
    <button
        type="button"
        onclick={() => {
            if (summary) {
                tmp_summary = summary;
                active_tab = 'result';
                show_modal = true;
            } else {
                generate_ai_result();
            }
        }}
        class={buttonClass}
        title={summary ? 'View existing AI summary' : 'Generate AI summary/analysis'}>
        {#await ae_promises}
            <Loader class="mr-1 inline-block animate-spin" size="1.2em" />
            <span class="text-sm">Processing...</span>
        {:then}
            <BotMessageSquare class="mr-1 inline-block" size="1.2em" />
            <span class="text-sm hidden">Summarize</span>
        {:catch}
            <span class="text-sm text-red-500">Error</span>
        {/await}
    </button>

    <!-- Quick Settings Button -->
    <button
        type="button"
        onclick={() => {
            active_tab = 'settings';
            show_modal = true;
        }}
        class="btn btn-sm preset-tonal-surface shadow-md"
        title="AI Settings">
        <Settings size="1.2em" />
        <span class="text-sm hidden">Settings</span>
    </button>

    <!-- Unified AI Modal -->
    {#if show_modal}
        <Modal
            title="Aether AI Assistant"
            bind:open={show_modal}
            size="lg"
            class="relative mx-auto flex h-[calc(100dvh-2rem)] max-h-[calc(100dvh-2rem)] w-full flex-col rounded-xl border border-surface-200-800 bg-surface-50-900 text-surface-950-50 shadow-xl">
            <div class="min-h-0 flex-1 space-y-4 overflow-y-auto px-4 py-3">
                <!-- Tab Navigation -->
                <div class="bg-surface-500/10 sticky top-0 z-10 mx-auto flex max-w-fit justify-center gap-1 rounded-lg p-1 backdrop-blur-sm">
                    <button
                        class={tab_button_class(active_tab === 'result')}
                        onclick={() => (active_tab = 'result')}>
                        <Bot size="1.1em" class="mr-1" /> Result
                    </button>
                    <button
                        class={tab_button_class(active_tab === 'settings')}
                        onclick={() => (active_tab = 'settings')}>
                        <Settings size="1.1em" class="mr-1" /> Settings
                    </button>
                </div>

                {#if active_tab === 'result'}
                    <div class="animate-in fade-in space-y-4 duration-200">
                        <div class="flex justify-start gap-2">
                            <button
                                class="btn btn-sm preset-filled-success"
                                onclick={handle_save}>
                                <Save size="1.1em" class="mr-1" /> Save Result
                            </button>
                            <button
                                class="btn btn-sm preset-tonal-primary"
                                onclick={generate_ai_result}>
                                <RotateCcw size="1.1em" class="mr-1" /> Re-run
                            </button>
                        </div>

                        <AE_Comp_Editor_CodeMirror
                            content={tmp_summary}
                            bind:new_content={tmp_summary}
                            theme_mode={$ae_loc.theme_mode}
                            placeholder="AI Result will appear here..."
                            class_li="p-2 border rounded-lg h-96 shadow-inner bg-surface-500/5" />
                    </div>
                {:else}
                    <div
                        class="animate-in slide-in-from-left-4 space-y-6 duration-200">
                        <!-- Connection Settings -->
                        <section class={panel_class}>
                            <h3 class={panel_title_class}>
                                <Globe size="1.1em" /> API Connection
                            </h3>

                            {#if onSyncConfig}
                                <button
                                    class="btn btn-sm preset-tonal-primary"
                                    onclick={onSyncConfig}>
                                    <Copy size="1.1em" class="mr-1" /> Sync Global
                                    Defaults
                                </button>
                            {/if}

                            <div class="grid grid-cols-1 gap-4 md:grid-cols-2">
                                <label class="label">
                                    <span>Base URL</span>
                                    <input
                                        type="text"
                                        autocomplete="off"
                                        autocapitalize="off"
                                        autocorrect="off"
                                        spellcheck="false"
                                        bind:value={baseUrl}
                                        class="input input-sm" />
                                </label>
                                <label class="label">
                                    <span>Model</span>
                                    <input
                                        type="text"
                                        autocomplete="off"
                                        autocapitalize="off"
                                        autocorrect="off"
                                        spellcheck="false"
                                        name="ai_model"
                                        data-bwignore="true"
                                        data-lpignore="true"
                                        data-1p-ignore="true"
                                        bind:value={model}
                                        class="input input-sm" />
                                </label>
                            </div>
                            <label class="label">
                                <span>API Token</span>
                                <div class="flex gap-2">
                                    <input
                                        type={show_api_token ? 'text' : 'password'}
                                        autocomplete="off"
                                        autocapitalize="off"
                                        autocorrect="off"
                                        spellcheck="false"
                                        name="ai_api_token"
                                        data-bwignore="true"
                                        data-lpignore="true"
                                        data-1p-ignore="true"
                                        bind:value={token}
                                        class="input input-sm font-mono" />
                                    <button
                                        type="button"
                                        class="btn btn-sm preset-tonal-surface"
                                        onclick={() =>
                                            (show_api_token = !show_api_token)}
                                        title={show_api_token
                                            ? 'Hide API Token'
                                            : 'Show API Token'}>
                                        {#if show_api_token}
                                            <EyeOff size="1.1em" />
                                        {:else}
                                            <Eye size="1.1em" />
                                        {/if}
                                    </button>
                                </div>
                            </label>
                        </section>

                        <!-- Model Parameters -->
                        <section class={panel_class}>
                            <h3 class={panel_title_class}>
                                <FilePenLine size="1.1em" /> Inference Parameters
                            </h3>
                            <div class="grid grid-cols-1 gap-4 md:grid-cols-2">
                                <label class="label">
                                    <span>Temperature ({temperature})</span>
                                    <input
                                        type="range"
                                        bind:value={temperature}
                                        min="0"
                                        max="1"
                                        step="0.1"
                                        class="range" />
                                </label>
                                <label class="label">
                                    <span>Max Tokens</span>
                                    <input
                                        type="number"
                                        bind:value={maxTokens}
                                        class="input input-sm" />
                                </label>
                            </div>
                            <label class="label">
                                <span>System Prompt</span>
                                <textarea
                                    bind:value={systemPrompt}
                                    class="textarea h-24 font-mono text-xs bg-surface-50-900"
                                ></textarea>
                            </label>
                        </section>
                    </div>
                {/if}
            </div>
        </Modal>
    {/if}
</div>
