import { readFileSync } from "node:fs";
import { resolve } from "node:path";
import YAML from "yaml";
import { envString } from "../env.js";

export type WebhookMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";

export type WebhookDefinition = {
  id: string;
  label: string;
  description?: string;
  method: WebhookMethod;
  url: string;
  required_roles: string[];
  confirmation_required: boolean;
  payload_template?: unknown;
};

export type PublicWebhookDefinition = Omit<WebhookDefinition, "url" | "payload_template">;

const defaultConfigPath = () => resolve(process.cwd(), "../../config/webhooks.yml");

const expandEnv = (value: string) =>
  value.replace(/\$\{([A-Z0-9_]+)\}/g, (_match, name: string) => process.env[name] ?? "");

export const loadWebhookDefinitions = (
  configPath = process.env.WEBHOOKS_CONFIG_PATH && process.env.WEBHOOKS_CONFIG_PATH.length > 0
    ? process.env.WEBHOOKS_CONFIG_PATH
    : defaultConfigPath(),
): WebhookDefinition[] => {
  const raw = readFileSync(configPath, "utf8");
  const parsed = YAML.parse(raw) as { webhooks?: WebhookDefinition[] } | undefined;

  return (parsed?.webhooks ?? []).map((webhook) => ({
    ...webhook,
    method: webhook.method.toUpperCase() as WebhookMethod,
    url: expandEnv(webhook.url),
    required_roles: webhook.required_roles ?? [],
    confirmation_required: webhook.confirmation_required ?? true,
  }));
};

export const canUseWebhook = (userRoles: string[], webhook: WebhookDefinition) =>
  webhook.required_roles.every((role) => userRoles.includes(role));

export const toPublicWebhook = (webhook: WebhookDefinition): PublicWebhookDefinition => ({
  id: webhook.id,
  label: webhook.label,
  description: webhook.description,
  method: webhook.method,
  required_roles: webhook.required_roles,
  confirmation_required: webhook.confirmation_required,
});
