<!-- #region MapperTool [C:3] [TYPE Component] [SEMANTICS mapper, dataset, column, mapping, sqllab] -->
<!-- @BRIEF UI component for mapping dataset column verbose names using Superset SQL Lab or Excel files. -->
<!-- @LAYER UI -->
<!-- @UX_STATE Idle -> Form fields visible, action buttons enabled. -->
<!-- @UX_STATE Loading -> Action buttons disabled, spinner active on clicked button. -->
<!-- @UX_STATE Error -> Validation errors shown inline, toast notifications displayed. -->
<!-- @UX_FEEDBACK Toast notifications on success/error. -->
<!-- @UX_RECOVERY Fix validation errors, retry operation. -->
<!--
@SEMANTICS: mapper, tool, dataset, sqllab, excel
@PURPOSE: UI component for mapping dataset column verbose names using Superset SQL Lab or Excel files.
@LAYER UI
@RELATION USES -> [ToolsService]
-->
<script lang="ts">
    // [SECTION: IMPORTS]
    import { onMount } from 'svelte';
    import { runTask } from '../../services/toolsService.js';
    import { api } from '../../lib/api';
    import { selectedTask } from '$lib/stores.svelte.js';
    import { addToast } from '$lib/toasts.svelte.js';
    import { t } from '$lib/i18n/index.svelte.js';
    import { Button, Card, Select, Input, Icon } from '../../lib/ui';
    import DocPreview from '../llm/DocPreview.svelte';
    // [/SECTION]

    let envs = [];
    let selectedEnv = '';
    let datasetId = '';
    let source = 'sqllab';
    let databaseId = '';
    let sqlQuery = '';
    let excelPath = '';
    let isRunning = false;
    let isGeneratingDocs = false;
    let generatedDoc = null;

    // #region fetchData:Function [TYPE Function]
    // @PURPOSE: Fetches environments.
    // @PRE: None.
    // @POST: envs array is populated.
    async function fetchData() {
        try {
            envs = await api.fetchApi('/environments');
            // Pre-fill with active environment from global context
            const { get } = await import('svelte/store');
            const envCtx = await import('$lib/stores/environmentContext.svelte.js');
            const state = get(envCtx.environmentContextStore);
            if (state.selectedEnvId && envs.some((e) => e.id === state.selectedEnvId)) {
                selectedEnv = state.selectedEnvId;
            }
        } catch (e) {
            addToast($t.mapper.errors.fetch_failed, 'error');
        }
    }
    // #endregion fetchData:Function

    // #region handleRunMapper:Function [TYPE Function]
    // @PURPOSE: Triggers the MapperPlugin task via new sqllab/excel sources.
    // @PRE: selectedEnv and datasetId are set; source-specific fields are valid.
    // @POST: Mapper task is started and selectedTask is updated.
    async function handleRunMapper() {
        if (!selectedEnv || !datasetId) {
            addToast($t.mapper.errors.required_fields, 'warning');
            return;
        }

        if (source === 'sqllab' && !databaseId) {
            addToast($t.mapper.errors.sqllab_required, 'warning');
            return;
        }

        if (source === 'excel' && !excelPath) {
            addToast($t.mapper.errors.excel_required, 'warning');
            return;
        }

        isRunning = true;
        try {
            const env = envs.find(e => e.id === selectedEnv);
            const task = await runTask('dataset-mapper', {
                env: env.name,
                dataset_id: parseInt(datasetId),
                source,
                database_id: databaseId ? parseInt(databaseId) : undefined,
                sql_query: sqlQuery || undefined,
                excel_path: excelPath
            });
            
            selectedTask.set(task);
            addToast($t.mapper.success.started, 'success');
        } catch (e) {
            addToast(e.message, 'error');
        } finally {
            isRunning = false;
        }
    }
    // #endregion handleRunMapper:Function

    // #region handleGenerateDocs:Function [TYPE Function]
    // @PURPOSE: Triggers the LLM Documentation task.
    // @PRE: selectedEnv and datasetId are set.
    // @POST: Documentation task is started.
    async function handleGenerateDocs() {
        if (!selectedEnv || !datasetId) {
            addToast($t.mapper.errors.required_fields, 'warning');
            return;
        }

        isGeneratingDocs = true;
        try {
             // Fetch active provider first
            const providers = await api.fetchApi('/llm/providers');
            const activeProvider = providers.find(p => p.is_active);
            
            if (!activeProvider) {
                addToast($t.mapper?.errors?.no_active_llm_provider, 'error');
                return;
            }

            const task = await runTask('llm_documentation', {
                dataset_id: datasetId,
                environment_id: selectedEnv,
                provider_id: activeProvider.id
            });
            
            selectedTask.set(task);
            addToast($t.mapper?.success?.docs_started, 'success');
        } catch (e) {
            addToast(e.message || $t.mapper?.errors?.docs_start_failed, 'error');
        } finally {
            isGeneratingDocs = false;
        }
    }
    // #endregion handleGenerateDocs:Function

    async function handleApplyDoc(doc) {
        try {
            await api.put(`/mappings/datasets/${datasetId}/metadata`, doc);
            generatedDoc = null;
            addToast($t.mapper?.success?.docs_applied, 'success');
        } catch (err) {
            addToast(err.message || $t.mapper?.errors?.docs_apply_failed, 'error');
        }
    }

    onMount(fetchData);
</script>

<!-- [SECTION: TEMPLATE] -->
<div class="space-y-6">
    <!-- Main Configuration Card -->
    <div class="bg-white rounded-xl border border-gray-200 shadow-sm overflow-hidden">
        <!-- Card Header -->
        <div class="px-6 py-4 bg-gradient-to-r from-blue-50 to-indigo-50 border-b border-gray-100">
            <div class="flex items-center gap-3">
                <div class="flex items-center justify-center w-10 h-10 rounded-lg bg-blue-100 text-blue-600">
                    <Icon name="database" size={20} />
                </div>
                <div>
                    <h2 class="text-lg font-semibold text-gray-900">{$t.mapper.title}</h2>
                    <p class="text-sm text-gray-500">Настройте параметры маппинга колонок</p>
                </div>
            </div>
        </div>

        <!-- Card Body -->
        <div class="p-6">
            <!-- Environment & Dataset ID Row -->
            <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
                <div class="space-y-2">
                    <label class="flex items-center gap-2 text-sm font-medium text-gray-700">
                        <Icon name="settings" size={16} className="text-gray-400" />
                        {$t.mapper.environment}
                        <span class="text-red-500">*</span>
                    </label>
                    <Select
                        bind:value={selectedEnv}
                        options={[
                            { value: '', label: $t.mapper.select_env },
                            ...envs.map(e => ({ value: e.id, label: e.name }))
                        ]}
                    />
                </div>
                <div class="space-y-2">
                    <label class="flex items-center gap-2 text-sm font-medium text-gray-700">
                        <Icon name="clipboard" size={16} className="text-gray-400" />
                        {$t.mapper.dataset_id}
                        <span class="text-red-500">*</span>
                    </label>
                    <Input
                        type="number"
                        bind:value={datasetId}
                        placeholder="Введите ID датасета..."
                    />
                </div>
            </div>

            <!-- Source Selection -->
            <div class="mb-6">
                <label class="flex items-center gap-2 text-sm font-medium text-gray-700 mb-3">
                    <Icon name="layers" size={16} className="text-gray-400" />
                    {$t.mapper.source}
                </label>
                <div class="flex gap-4">
                    <label class="flex-1 relative cursor-pointer">
                        <input 
                            type="radio" 
                            bind:group={source} 
                            value="sqllab" 
                            class="peer sr-only" 
                        />
                        <div class="flex items-center gap-3 p-4 rounded-lg border-2 border-gray-200 bg-gray-50 
                                    hover:border-blue-300 hover:bg-blue-50 
                                    peer-checked:border-blue-500 peer-checked:bg-blue-50 peer-checked:ring-2 peer-checked:ring-blue-500/20
                                    transition-all duration-200">
                            <div class="flex items-center justify-center w-10 h-10 rounded-lg bg-blue-100 text-blue-600 peer-checked:bg-blue-600 peer-checked:text-white">
                                <Icon name="database" size={20} />
                            </div>
                            <div>
                                <div class="font-medium text-gray-900">{$t.mapper.source_sqllab}</div>
                                <div class="text-xs text-gray-500">Подключение через SQL Lab</div>
                            </div>
                        </div>
                    </label>
                    <label class="flex-1 relative cursor-pointer">
                        <input 
                            type="radio" 
                            bind:group={source} 
                            value="excel" 
                            class="peer sr-only" 
                        />
                        <div class="flex items-center gap-3 p-4 rounded-lg border-2 border-gray-200 bg-gray-50 
                                    hover:border-green-300 hover:bg-green-50 
                                    peer-checked:border-green-500 peer-checked:bg-green-50 peer-checked:ring-2 peer-checked:ring-green-500/20
                                    transition-all duration-200">
                            <div class="flex items-center justify-center w-10 h-10 rounded-lg bg-green-100 text-green-600 peer-checked:bg-green-600 peer-checked:text-white">
                                <Icon name="clipboard" size={20} />
                            </div>
                            <div>
                                <div class="font-medium text-gray-900">{$t.mapper.source_excel}</div>
                                <div class="text-xs text-gray-500">Импорт из Excel файла</div>
                            </div>
                        </div>
                    </label>
                </div>
            </div>

            <!-- Source-specific Configuration -->
            <div class="rounded-xl border border-gray-200 bg-gray-50 p-5 mb-6">
                {#if source === 'sqllab'}
                    <div class="space-y-4">
                        <div class="flex items-center gap-2 mb-4">
                            <Icon name="database" size={18} className="text-blue-600" />
                            <h3 class="text-sm font-semibold text-gray-900">Настройки SQL Lab</h3>
                        </div>
                        <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                            <div class="space-y-2">
                                <label class="text-sm font-medium text-gray-700">
                                    {$t.mapper.database_id}
                                    <span class="text-red-500">*</span>
                                </label>
                                <Input
                                    type="number"
                                    bind:value={databaseId}
                                    placeholder={$t.mapper.database_id_placeholder}
                                />
                            </div>
                            <div class="space-y-2">
                                <label class="text-sm font-medium text-gray-700">
                                    {$t.mapper.sql_query_label}
                                </label>
                                <Input
                                    type="text"
                                    bind:value={sqlQuery}
                                    placeholder={$t.mapper.sql_query_placeholder}
                                />
                            </div>
                        </div>
                    </div>
                {:else}
                    <div class="space-y-4">
                        <div class="flex items-center gap-2 mb-4">
                            <Icon name="clipboard" size={18} className="text-green-600" />
                            <h3 class="text-sm font-semibold text-gray-900">Настройки Excel</h3>
                        </div>
                        <div class="space-y-2">
                            <label class="text-sm font-medium text-gray-700">
                                {$t.mapper.excel_path}
                                <span class="text-red-500">*</span>
                            </label>
                            <Input
                                type="text"
                                bind:value={excelPath}
                                placeholder={$t.mapper?.excel_placeholder}
                            />
                        </div>
                    </div>
                {/if}
            </div>

            <!-- Action Buttons -->
            <div class="flex flex-col sm:flex-row justify-end gap-3 pt-4 border-t border-gray-100">
                <Button
                    variant="secondary"
                    onclick={handleGenerateDocs}
                    disabled={isGeneratingDocs || isRunning}
                    class="flex items-center gap-2"
                >
                    {#if isGeneratingDocs}
                        <svg class="animate-spin h-4 w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
                            <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
                            <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
                        </svg>
                        {$t.mapper?.generating}
                    {:else}
                        <Icon name="layers" size={16} />
                        {$t.datasets?.generate_docs}
                    {/if}
                </Button>
                <Button
                    variant="primary"
                    onclick={handleRunMapper}
                    disabled={isRunning}
                    class="flex items-center gap-2"
                >
                    {#if isRunning}
                        <svg class="animate-spin h-4 w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
                            <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
                            <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
                        </svg>
                        {$t.mapper.starting}
                    {:else}
                        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                            <polygon points="5 3 19 12 5 21 5 3"></polygon>
                        </svg>
                        {$t.mapper.run}
                    {/if}
                </Button>
            </div>
        </div>
    </div>

    <!-- Documentation Preview -->
    <DocPreview
        documentation={generatedDoc}
        onCancel={() => generatedDoc = null}
        onSave={handleApplyDoc}
    />
</div>
<!-- [/SECTION] -->
<!-- #endregion MapperTool -->
