import fs from "node:fs";
import path from "node:path";
import { settings } from "./config.js";

const DEFAULT_CLIENT_SETTINGS = {
  homeBypassEnabled: false,
  sharedProxyEnabled: false,
  sharedProxyControlUrl: "",
  sharedProxy: null,
};

function normalizeProxyPort(value, fallback = settings.proxyPort) {
  const parsed = Number.parseInt(value, 10);
  const min = Number.isInteger(settings.clientProxyPortStart)
    ? settings.clientProxyPortStart
    : settings.proxyPort;
  const max = Number.isInteger(settings.clientProxyPortEnd)
    ? settings.clientProxyPortEnd
    : min;
  const fallbackPort =
    Number.isInteger(fallback) && fallback >= min && fallback <= max
      ? fallback
      : min;
  if (!Number.isInteger(parsed) || parsed < min || parsed > max) {
    return fallbackPort;
  }
  return parsed;
}

function readJson(filePath, fallback) {
  try {
    if (!fs.existsSync(filePath)) return fallback;
    return JSON.parse(fs.readFileSync(filePath, "utf8"));
  } catch {
    return fallback;
  }
}

function writeJson(filePath, value) {
  fs.mkdirSync(path.dirname(filePath), { recursive: true });
  fs.writeFileSync(filePath, JSON.stringify(value, null, 2), "utf8");
}

function normalizeUrl(value) {
  const raw = String(value || "").trim();
  if (!raw) return "";
  try {
    const url = new URL(raw);
    if (!["http:", "https:"].includes(url.protocol)) return "";
    url.hash = "";
    url.search = "";
    return url.toString().replace(/\/$/, "");
  } catch {
    return "";
  }
}

function normalizeSharedProxy(value) {
  if (!value || typeof value !== "object") return null;
  const host = String(value.host || "").trim();
  const port = Number.parseInt(value.port, 10);
  const protocol = value.protocol === "http" ? "http" : "socks5";
  if (!host || !Number.isInteger(port) || port <= 0 || port > 65535) {
    return null;
  }
  return {
    host,
    port,
    protocol,
    checkedAt: value.checkedAt || null,
  };
}

export function normalizeClientSettings(input = {}) {
  const sharedProxy = normalizeSharedProxy(input.sharedProxy);
  const sharedProxyEnabled = Boolean(input.sharedProxyEnabled && sharedProxy);
  return {
    homeBypassEnabled: Boolean(input.homeBypassEnabled),
    proxyPort: normalizeProxyPort(input.proxyPort),
    sharedProxyEnabled,
    sharedProxyControlUrl: normalizeUrl(input.sharedProxyControlUrl),
    sharedProxy,
  };
}

export function readClientSettings() {
  return normalizeClientSettings({
    ...DEFAULT_CLIENT_SETTINGS,
    proxyPort: settings.proxyPort,
    ...readJson(settings.clientSettingsPath, {}),
  });
}

export function writeClientSettings(input) {
  const normalized = normalizeClientSettings({
    ...readClientSettings(),
    ...(input && typeof input === "object" ? input : {}),
  });
  writeJson(settings.clientSettingsPath, normalized);
  return normalized;
}
