// @ts-nocheck
import fs from "node:fs";
import path from "node:path";

export function loadConfig({ configPath = "config/local.json", dryRun } = {}) {
  const localConfig = readJsonFile(configPath);
  const exampleConfig = readJsonFile("config/local.example.json");
  const config = mergeConfig(exampleConfig, localConfig);
  const env = readEnvFile(".env");

  const appMode = String(config.appMode || "dry-run").toLowerCase();
  const resolvedDryRun = dryRun === undefined ? appMode !== "live" : Boolean(dryRun);

  return {
    appMode,
    dryRun: resolvedDryRun,
    sourceWorkbook: path.resolve(config.sourceWorkbook || "./xxx_endpoint_bo_2026-08-04_v1.xlsm"),
    outputDir: path.resolve(config.outputDir || "./outputs"),
    server: {
      host: config.server?.host || "127.0.0.1",
      port: Number(config.server?.port || 3400),
    },
    endpoint: {
      url: config.endpoint?.url || "https://www.9b-plus.com/apiv1/endpoint/query",
      loginUrl: config.endpoint?.loginUrl || "https://www.9b-plus.com/apiv1/auth/login",
      token: config.endpoint?.token || "",
      username: config.endpoint?.username || "",
      password: config.endpoint?.password || "",
    },
    database: {
      driver: String(env.DB_DRIVER || config.database?.driver || "endpoint").toLowerCase(),
      mode: String(env.DB_MODE || config.database?.mode || "local").toLowerCase(),
      allowLocalWrites: parseBoolean(
        env.DB_LOCAL_ALLOW_WRITES,
        config.database?.allowLocalWrites ?? config.database?.allowWrites,
      ),
      host: env.DB_HOST || config.database?.host || "127.0.0.1",
      port: Number(env.DB_PORT || config.database?.port || 3306),
      name: env.DB_NAME || config.database?.name || "catalog_maker_test",
      user: env.DB_USER || config.database?.user || "catalog_maker",
      password: env.DB_PASSWORD || config.database?.password || "",
      scrapeName: env.SCRAPE_DB_NAME || config.database?.scrapeName || "catalog_scrape",
      connectionLimit: Number(env.DB_CONNECTION_LIMIT || config.database?.connectionLimit || 5),
    },
    databaseTool: {
      url: env.ADMINER_URL || config.databaseTool?.url || config.databaseGate?.url || "http://127.0.0.1:8080",
      browserEngine: String(
        env.ADMINER_BROWSER_ENGINE
          || config.databaseTool?.browserEngine
          || config.databaseGate?.browserEngine
          || "chromium",
      ).toLowerCase(),
    },
    dbGate: {
      url: env.DBGATE_URL || config.dbGate?.url || "http://127.0.0.1:3000",
      browserEngine: String(
        env.DBGATE_BROWSER_ENGINE
          || config.dbGate?.browserEngine
          || "chromium",
      ).toLowerCase(),
    },
  };
}

function readJsonFile(filePath) {
  if (!fs.existsSync(filePath)) {
    return {};
  }

  return JSON.parse(fs.readFileSync(filePath, "utf8"));
}

function readEnvFile(filePath) {
  if (!fs.existsSync(filePath)) return {};

  return Object.fromEntries(
    fs.readFileSync(filePath, "utf8")
      .split(/\r?\n/)
      .map((line) => line.trim())
      .filter((line) => line && !line.startsWith("#") && line.includes("="))
      .map((line) => {
        const separator = line.indexOf("=");
        return [line.slice(0, separator).trim(), line.slice(separator + 1).trim()];
      }),
  );
}

function parseBoolean(value, fallback = false) {
  if (value === undefined) return Boolean(fallback);
  return ["1", "true", "yes", "on"].includes(String(value).toLowerCase());
}

function mergeConfig(base, override) {
  return {
    ...base,
    ...override,
    server: {
      ...base.server,
      ...override.server,
    },
    endpoint: {
      ...base.endpoint,
      ...override.endpoint,
    },
    database: {
      ...base.database,
      ...override.database,
    },
    databaseTool: {
      ...base.databaseTool,
      ...base.databaseGate,
      ...override.databaseTool,
      ...override.databaseGate,
    },
    dbGate: {
      ...base.dbGate,
      ...override.dbGate,
    },
  };
}
