<script lang="ts">
    import { onMount, onDestroy } from "svelte"
    import { invoke } from "@tauri-apps/api/core"
    import { goto } from "@roxi/routify"

    import HDivider from "@/components/elements/HDivider.svelte"
    import Footer from "@/components/Footer.svelte"
    import {
        Button, Space, Text, Notification, Badge, TextInput, Loader,
    } from "@svelteuidev/core"
    import { Play, TrashIcon, Plus, CrossCircled } from "radix-icons-svelte"

    interface MacroInfo {
        name: string
        steps_count: number
        steps: string[]
        created_at: number
        last_run: number | null
    }

    let macros: MacroInfo[] = []
    let loading = true
    let error = ""

    let isRecording = false
    let recordingName: string | null = null
    let newMacroName = ""
    let busyMacro = ""           // macro currently being replayed
    let recordingPoll: ReturnType<typeof setInterval> | null = null

    async function load() {
        loading = true
        error = ""
        try {
            macros = await invoke<MacroInfo[]>("macros_list")
            macros = [...macros].sort((a, b) => a.name.localeCompare(b.name))
            await pollRecording()
        } catch (e) {
            error = String(e)
        } finally {
            loading = false
        }
    }

    async function pollRecording() {
        try {
            isRecording = await invoke<boolean>("macros_is_recording")
            recordingName = await invoke<string | null>("macros_recording_name")
        } catch (e) { /* ignore */ }
    }

    async function startRecording() {
        const name = newMacroName.trim()
        if (!name) { error = "Введите имя макроса"; return }
        try {
            await invoke("macros_start_recording", { name })
            newMacroName = ""
            await pollRecording()
        } catch (e) { error = String(e) }
    }

    async function saveRecording() {
        try {
            const count = await invoke<number>("macros_save_recording")
            await load()
            error = `Сохранил ${count} шагов`
            setTimeout(() => { if (error.startsWith("Сохранил")) error = "" }, 3000)
        } catch (e) { error = String(e) }
    }

    async function cancelRecording() {
        try {
            await invoke("macros_cancel_recording")
            await pollRecording()
        } catch (e) { error = String(e) }
    }

    async function playMacro(name: string) {
        busyMacro = name
        try {
            const count = await invoke<number>("macros_replay", { name })
            // 800ms × count + safety
            setTimeout(() => { busyMacro = "" }, count * 900 + 500)
        } catch (e) {
            error = String(e)
            busyMacro = ""
        }
    }

    async function deleteMacro(name: string) {
        if (!confirm(`Удалить макрос "${name}"?`)) return
        try {
            await invoke("macros_delete", { name })
            await load()
        } catch (e) { error = String(e) }
    }

    onMount(() => {
        load()
        recordingPoll = setInterval(pollRecording, 2000)
    })

    onDestroy(() => {
        if (recordingPoll !== null) clearInterval(recordingPoll)
    })

    function fmtDate(ts: number | null): string {
        if (!ts) return "—"
        return new Date(ts * 1000).toLocaleString()
    }
</script>

<Space h="xl" />

<h2 class="page-title">Макросы</h2>
<Text size="sm" color="gray">
    Запиши последовательность голосовых команд, потом запускай её одной фразой.
</Text>

<Space h="md" />

{#if isRecording}
    <Notification
        title="Идёт запись макроса"
        icon={Play}
        color="orange"
        withCloseButton={false}
    >
        <Text size="sm">
            Записывается макрос <strong>{recordingName ?? "—"}</strong>.
            Произнесите команды, потом нажмите «Сохранить» или скажите «Сохрани макрос».
        </Text>
        <Space h="sm" />
        <Button color="lime" radius="md" size="xs" uppercase on:click={saveRecording}>
            Сохранить
        </Button>
        &nbsp;
        <Button color="gray" radius="md" size="xs" uppercase on:click={cancelRecording}>
            Отменить
        </Button>
    </Notification>
    <Space h="md" />
{:else}
    <div class="new-macro-row">
        <TextInput
            placeholder="Имя нового макроса"
            variant="filled"
            bind:value={newMacroName}
        />
        <Button color="lime" radius="md" size="sm" on:click={startRecording}>
            <Plus size={14} /> &nbsp; Начать запись
        </Button>
    </div>
    <Space h="md" />
{/if}

{#if error}
    <Notification
        title="Сообщение"
        icon={CrossCircled}
        color={error.startsWith("Сохранил") ? "teal" : "red"}
        on:close={() => { error = "" }}
    >
        {error}
    </Notification>
    <Space h="sm" />
{/if}

{#if loading}
    <Loader />
{:else if macros.length === 0}
    <Text size="sm" color="gray">
        Макросов пока нет. Создайте первый: введите имя, нажмите «Начать запись»,
        произнесите команды, нажмите «Сохранить».
    </Text>
{:else}
    <div class="macro-list">
        {#each macros as m}
            <div class="macro-card">
                <div class="macro-header">
                    <span class="macro-name">{m.name}</span>
                    <Badge color="blue" variant="filled" size="sm">
                        {m.steps_count} шагов
                    </Badge>
                </div>
                <div class="macro-steps">
                    {#each m.steps.slice(0, 5) as step}
                        <div class="step">• {step}</div>
                    {/each}
                    {#if m.steps.length > 5}
                        <div class="step muted">+ ещё {m.steps.length - 5}…</div>
                    {/if}
                </div>
                <div class="macro-meta">
                    <small>Создан: {fmtDate(m.created_at)}</small>
                    <small>Последний запуск: {fmtDate(m.last_run)}</small>
                </div>
                <div class="macro-actions">
                    <Button
                        color="lime" radius="md" size="xs" uppercase
                        on:click={() => playMacro(m.name)}
                        disabled={busyMacro === m.name}
                    >
                        {#if busyMacro === m.name}
                            Выполняется…
                        {:else}
                            <Play size={14} /> &nbsp; Запустить
                        {/if}
                    </Button>
                    &nbsp;
                    <Button
                        color="red" radius="md" size="xs" uppercase
                        on:click={() => deleteMacro(m.name)}
                    >
                        <TrashIcon size={14} /> &nbsp; Удалить
                    </Button>
                </div>
            </div>
        {/each}
    </div>
{/if}

<Space h="xl" />

<Button color="gray" radius="md" size="sm" uppercase fullSize on:click={() => $goto("/")}>
    Назад
</Button>

<HDivider />
<Footer />

<style lang="scss">
    .page-title {
        margin: 0 0 4px 0;
        color: #fff;
        font-size: 1.3rem;
        font-weight: 600;
    }

    .new-macro-row {
        display: flex;
        gap: 0.5rem;
        align-items: flex-end;

        :global(.svelteui-Input-root) {
            flex: 1;
        }
    }

    .macro-list {
        display: flex;
        flex-direction: column;
        gap: 0.75rem;
    }

    .macro-card {
        background: rgba(30, 40, 45, 0.75);
        border: 1px solid rgba(255, 255, 255, 0.08);
        border-radius: 10px;
        padding: 0.85rem 1rem;
    }

    .macro-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 0.5rem;
    }

    .macro-name {
        font-size: 0.95rem;
        font-weight: 600;
        color: #fff;
    }

    .macro-steps {
        background: rgba(0, 0, 0, 0.2);
        border-radius: 6px;
        padding: 0.4rem 0.6rem;
        margin-bottom: 0.5rem;

        .step {
            font-size: 0.78rem;
            color: rgba(255, 255, 255, 0.7);
            line-height: 1.4em;

            &.muted {
                color: rgba(255, 255, 255, 0.4);
                font-style: italic;
            }
        }
    }

    .macro-meta {
        display: flex;
        justify-content: space-between;
        color: rgba(255, 255, 255, 0.4);
        font-size: 0.7rem;
        margin-bottom: 0.5rem;
    }

    .macro-actions {
        display: flex;
        gap: 0.4rem;
    }
</style>
