import streamDeck from "@elgato/streamdeck";
import type { JsonObject } from "@elgato/utils";
import type { FilyxSettings } from "../types";

type StoredObsConnection = {
  obsHost: string;
  obsPort: number;
  obsPassword: string;
  savedAt: string;
};

type PluginSettings = JsonObject & { obsConnection?: StoredObsConnection };

const normalise = (settings: FilyxSettings): StoredObsConnection => {
  const rawHost = String(settings.obsHost || "127.0.0.1").trim() || "127.0.0.1";
  let obsHost = rawHost;
  let rawPort = Number(settings.obsPort || 4455);
  try {
    const endpoint = new URL(/^wss?:\/\//i.test(rawHost) ? rawHost : `ws://${rawHost}`);
    obsHost = endpoint.hostname || rawHost;
    if (endpoint.port) rawPort = Number(endpoint.port);
  } catch (_) { /* L’auto-connecteur donnera une erreur précise si l’hôte est invalide. */ }
  const obsPort = Number.isInteger(rawPort) && rawPort > 0 && rawPort < 65536 ? rawPort : 4455;
  return {
    obsHost,
    obsPort,
    obsPassword: String(settings.obsPassword || ""),
    savedAt: new Date().toISOString(),
  };
};

export const getSavedObsConnection = async (): Promise<StoredObsConnection | null> => {
  const global = await streamDeck.settings.getGlobalSettings<PluginSettings>();
  const saved = global?.obsConnection;
  if (!saved || !String(saved.obsHost || "").trim()) return null;
  return normalise(saved as FilyxSettings);
};

/** New OBS actions share one local connection by default, so no password has to be entered per key. */
export const resolveObsConnection = async (settings: FilyxSettings): Promise<FilyxSettings> => {
  if (String(settings.obsConnectionMode || "shared") !== "shared") return settings;
  const saved = await getSavedObsConnection();
  return saved ? { ...settings, ...saved } : settings;
};

export const saveObsConnection = async (settings: FilyxSettings): Promise<StoredObsConnection> => {
  const global = await streamDeck.settings.getGlobalSettings<PluginSettings>();
  const connection = normalise(settings);
  await streamDeck.settings.setGlobalSettings<PluginSettings>({ ...global, obsConnection: connection });
  return connection;
};
