import { writable } from "svelte/store"
import { invoke } from "@tauri-apps/api/core"

// ### RE-EXPORT IPC STORES
export {
    jarvisState,
    ipcConnected,
    lastRecognizedText,
    lastExecutedCommand,
    lastError,
    daemonHealth,
    connectIpc,
    enableIpc,
    disableIpc,
    disconnectIpc,
    sendAction,
    sendIpcMessage,
    sendTextCommand,
    stopJarvisApp,
    reloadCommands,
    switchDaemonLlm,
    reloadDaemonLlm,
    queryDaemonHealth,
} from "./lib/ipc"

export type { DaemonHealth } from "./lib/ipc"

// re-export i18n
export {
    translations,
    currentLanguage,
    translate,
    loadTranslations,
    setLanguage,
    loadLanguage,
    getSupportedLanguages
} from "./lib/i18n"

// ### RUNNING STATE
export const isJarvisRunning = writable(false)
export const jarvisRamUsage = writable(0)
export const jarvisCpuUsage = writable(0)

// ### ASSISTANT VOICE
export const assistantVoice = writable("")

// ### APP INFO
// Hardcoded fallbacks so the UI keeps working when the Rust side has not
// been rebuilt yet (the new get_upstream_link / get_issues_link / get_python_fork_link
// Tauri commands only exist after the next cargo build).
const BRANDING_FALLBACK = {
    repositoryLink: "https://github.com/DmitryBykov-ISPO/J.A.R.V.I.S-rust",
    upstreamLink: "https://github.com/Priler/jarvis",
    issuesLink: "https://github.com/DmitryBykov-ISPO/J.A.R.V.I.S-rust/issues",
    pythonForkLink: "https://github.com/DmitryBykov-ISPO/J.A.R.V.I.S-py",
}

export const appInfo = writable({
    repositoryLink: BRANDING_FALLBACK.repositoryLink,
    upstreamLink: BRANDING_FALLBACK.upstreamLink,
    issuesLink: BRANDING_FALLBACK.issuesLink,
    pythonForkLink: BRANDING_FALLBACK.pythonForkLink,
    logFilePath: ""
})

// ### INIT FUNCTIONS (call these from a component)
export async function loadVoiceSetting() {
    try {
        const voice = await invoke<string>("db_read", { key: "assistant_voice" })
        assistantVoice.set(voice)
    } catch (err) {
        console.error("failed to load voice setting:", err)
    }
}

export async function loadAppInfo() {
    const fetchOr = async (name: string, fallback: string): Promise<string> => {
        try {
            const v = await invoke<string>(name)
            return v && v !== "error" ? v : fallback
        } catch {
            return fallback
        }
    }

    // The old binary's get_repository_link returns Priler's upstream — override
    // so we never display the upstream repo as if it were the current fork.
    const fetchRepoOr = async (fallback: string): Promise<string> => {
        const v = await fetchOr("get_repository_link", fallback)
        if (/priler\/jarvis/i.test(v)) return fallback
        return v
    }

    const [repo, upstream, issues, pythonFork, logPath] = await Promise.all([
        fetchRepoOr(BRANDING_FALLBACK.repositoryLink),
        fetchOr("get_upstream_link", BRANDING_FALLBACK.upstreamLink),
        fetchOr("get_issues_link", BRANDING_FALLBACK.issuesLink),
        fetchOr("get_python_fork_link", BRANDING_FALLBACK.pythonForkLink),
        fetchOr("get_log_file_path", "")
    ])

    appInfo.set({
        repositoryLink: repo,
        upstreamLink: upstream,
        issuesLink: issues,
        pythonForkLink: pythonFork,
        logFilePath: logPath
    })
}

export async function updateJarvisStats() {
    try {
        const stats = await invoke<{running: boolean, ram_mb: number, cpu_usage: number}>("get_jarvis_app_stats")
        isJarvisRunning.set(stats.running)
        jarvisRamUsage.set(stats.ram_mb)
        jarvisCpuUsage.set(stats.cpu_usage)
    } catch (err) {
        console.error("failed to get jarvis stats:", err)
    }
}

// polling manager
let statsInterval: ReturnType<typeof setInterval> | null = null

export function startStatsPolling(intervalMs = 5000) {
    if (statsInterval) return // already running

    updateJarvisStats()
    statsInterval = setInterval(updateJarvisStats, intervalMs)
}

export function stopStatsPolling() {
    if (statsInterval) {
        clearInterval(statsInterval)
        statsInterval = null
    }
}
