import path from "node:path"
import os from "node:os"
import { existsSync } from "node:fs"
import { fileURLToPath } from "node:url"
import { AgentConfig } from "./types.js"
import { loadDotEnv } from "./env.js"

const currentFile = fileURLToPath(import.meta.url)
const agentRoot = path.resolve(path.dirname(currentFile), "..")

const optional = (value: string | undefined) => {
    const trimmed = value?.trim()
    return trimmed ? trimmed : undefined
}

const numberFromEnv = (value: string | undefined, fallback: number) => {
    if (!value) return fallback

    const parsed = Number(value)
    return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback
}

const scanFormatFromEnv = (value: string | undefined): AgentConfig["scanFormat"] => {
    if (value === "png" || value === "tiff" || value === "pdf") return value
    return "pdf"
}

const booleanFromEnv = (value: string | undefined, fallback: boolean) => {
    if (!value) return fallback
    return ["1", "true", "yes", "ja", "on"].includes(value.trim().toLowerCase())
}

const postprocessProfileFromEnv = (value: string | undefined): AgentConfig["postprocessProfile"] => {
    if (value === "document" || value === "receipt" || value === "raw") return value
    return "document"
}

const defaultPostprocessPython = () => {
    const localVenvPython = path.join(agentRoot, ".venv-opencv", "bin", "python")
    return existsSync(localVenvPython) ? localVenvPython : "python3"
}

export const loadConfig = (): AgentConfig => {
    loadDotEnv(process.env.FEDEO_AGENT_ENV || ".env")

    const fedeoUrl = optional(process.env.FEDEO_URL)
    const agentToken = optional(process.env.FEDEO_AGENT_TOKEN)

    if (!fedeoUrl) throw new Error("FEDEO_URL fehlt")
    if (!agentToken) throw new Error("FEDEO_AGENT_TOKEN fehlt")

    return {
        fedeoUrl: fedeoUrl.replace(/\/+$/, ""),
        agentToken,
        pollSeconds: numberFromEnv(process.env.FEDEO_POLL_SECONDS, 5),
        workDir: optional(process.env.FEDEO_WORK_DIR) || path.join(os.tmpdir(), "fedeo-device-agent"),
        scannerName: optional(process.env.FEDEO_SCANNER_NAME),
        printerName: optional(process.env.FEDEO_PRINTER_NAME),
        scanFormat: scanFormatFromEnv(process.env.FEDEO_SCAN_FORMAT),
        scanResolution: numberFromEnv(process.env.FEDEO_SCAN_RESOLUTION, 300),
        scanMode: optional(process.env.FEDEO_SCAN_MODE) || "Color",
        scanSource: optional(process.env.FEDEO_SCAN_SOURCE),
        scanPostprocess: booleanFromEnv(process.env.FEDEO_SCAN_POSTPROCESS, false),
        postprocessProfile: postprocessProfileFromEnv(process.env.FEDEO_SCAN_POSTPROCESS_PROFILE),
        postprocessPython: optional(process.env.FEDEO_SCAN_POSTPROCESS_PYTHON) || defaultPostprocessPython(),
        postprocessStrict: booleanFromEnv(process.env.FEDEO_SCAN_POSTPROCESS_STRICT, false),
    }
}
