/* global window */
(function (w) {
  'use strict';

  // Centralized registry for provider-specific defaults (base_url, endpoint, headers, template)
  // Exposes window.ProviderTemplates with:
  //   .register(name, { defaultConfig: () => ({ base_url, endpoint, headers, template }) })
  //   .defaults(provider)
  //   .ensureConfigs(nodeData)
  //   .getActiveProv(nodeData)
  //   .getActiveCfg(nodeData)
  //   .providers()

  const PT = {};
  const _registry = new Map();

  function norm(p) {
    return String(p == null ? 'openai' : p).toLowerCase().trim();
  }

  PT.register = function register(name, def) {
    const key = norm(name);
    if (!def || typeof def.defaultConfig !== 'function') {
      throw new Error('ProviderTemplates.register: def.defaultConfig() required');
    }
    _registry.set(key, { defaultConfig: def.defaultConfig });
  };

  PT.providers = function providers() {
    return Array.from(_registry.keys());
  };

  PT.defaults = function defaults(provider) {
    const key = norm(provider);
    const rec = _registry.get(key);
    if (rec && typeof rec.defaultConfig === 'function') {
      try { return rec.defaultConfig(); } catch (_) {}
    }
    return { base_url: '', endpoint: '', headers: `{}`, template: `{}` };
  };

  PT.ensureConfigs = function ensureConfigs(d) {
    if (!d) return;
    if (!d.provider) d.provider = 'openai';
    if (!d.provider_configs || typeof d.provider_configs !== 'object') d.provider_configs = {};
    for (const p of PT.providers()) {
      if (!d.provider_configs[p]) d.provider_configs[p] = PT.defaults(p);
    }
  };

  PT.getActiveProv = function getActiveProv(d) {
    return norm(d && d.provider);
  };

  PT.getActiveCfg = function getActiveCfg(d) {
    PT.ensureConfigs(d);
    const p = PT.getActiveProv(d);
    return d && d.provider_configs ? (d.provider_configs[p] || {}) : {};
  };

  // --- Built-in providers (default presets) ---
  // Templates mirror original editor.html logic; use macros [[...]] and {{ ... }} as-is.
  function T_OPENAI() { return `{
  "model": "{{ model }}",
  [[PROMPT]],
  "temperature": {{ incoming.json.temperature|default(params.temperature|default(0.7)) }},
  "top_p": {{ incoming.json.top_p|default(params.top_p|default(1)) }},
  "max_tokens": {{ incoming.json.max_tokens|default(params.max_tokens|default(256)) }},
  "max_completion_tokens": {{ incoming.json.max_completion_tokens|default(params.max_tokens|default(256)) }},
  "presence_penalty": {{ incoming.json.presence_penalty|default(0) }},
  "frequency_penalty": {{ incoming.json.frequency_penalty|default(0) }},
  "stop": {{ incoming.json.stop|default(params.stop|default([])) }},
  "stream": {{ incoming.json.stream|default(false) }}
}`; }

  function T_GEMINI() { return `{
  "model": "{{ model }}",
  [[PROMPT]],
  "safetySettings": {{ incoming.json.safetySettings|default([]) }},
  "generationConfig": {
    "temperature": {{ incoming.json.generationConfig.temperature|default(params.temperature|default(0.7)) }},
    "topP": {{ incoming.json.generationConfig.topP|default(params.top_p|default(1)) }},
    "maxOutputTokens": {{ incoming.json.generationConfig.maxOutputTokens|default(params.max_tokens|default(256)) }},
    "stopSequences": {{ incoming.json.generationConfig.stopSequences|default(params.stop|default([])) }},
    "candidateCount": {{ incoming.json.generationConfig.candidateCount|default(1) }},
    "thinkingConfig": {
      "includeThoughts": {{ incoming.json.generationConfig.thinkingConfig.includeThoughts|default(false) }},
      "thinkingBudget": {{ incoming.json.generationConfig.thinkingConfig.thinkingBudget|default(0) }}
    }
  }
}`; }

  function T_GEMINI_IMAGE() { return `{
  "model": "{{ model }}",
  [[PROMPT]]
}`; }

  function T_CLAUDE() { return `{
  "model": "{{ model }}",
  [[PROMPT]],
  "temperature": {{ incoming.json.temperature|default(params.temperature|default(0.7)) }},
  "top_p": {{ incoming.json.top_p|default(params.top_p|default(1)) }},
  "max_tokens": {{ incoming.json.max_tokens|default(params.max_tokens|default(256)) }},
  "stop_sequences": {{ incoming.json.stop_sequences|default(params.stop|default([])) }},
  "stream": {{ incoming.json.stream|default(false) }},
  "thinking": {
    "type": "{{ incoming.json.thinking.type|default('disabled') }}",
    "budget_tokens": {{ incoming.json.thinking.budget_tokens|default(0) }}
  },
  "anthropic_version": "{{ anthropic_version|default('2023-06-01') }}"
}`; }

  // Register built-ins
  PT.register('openai', {
    defaultConfig: () => ({
      base_url: 'https://api.openai.com',
      endpoint: '/v1/chat/completions',
      headers: `{"Authorization":"Bearer [[VAR:incoming.headers.authorization]]"}`,
      template: T_OPENAI()
    })
  });
  PT.register('gemini', {
    defaultConfig: () => ({
      base_url: 'https://generativelanguage.googleapis.com',
      endpoint: '/v1beta/models/{{ model }}:generateContent?key=[[VAR:incoming.api_keys.key]]',
      headers: `{}`,
      template: T_GEMINI()
    })
  });
  PT.register('gemini_image', {
    defaultConfig: () => ({
      base_url: 'https://generativelanguage.googleapis.com',
      endpoint: '/v1beta/models/{{ model }}:generateContent',
      headers: `{"x-goog-api-key":"[[VAR:incoming.api_keys.key]]"}`,
      template: T_GEMINI_IMAGE()
    })
  });
  PT.register('claude', {
    defaultConfig: () => ({
      base_url: 'https://api.anthropic.com',
      endpoint: '/v1/messages',
      headers: `{"x-api-key":"[[VAR:incoming.headers.x-api-key]]","anthropic-version":"2023-06-01","anthropic-beta":"[[VAR:incoming.headers.anthropic-beta]]"}`,
      template: T_CLAUDE()
    })
  });

  try { console.debug('[ProviderTemplates] providers:', PT.providers()); } catch (_) {}

  // Export globals and compatibility shims
  try {
    w.ProviderTemplates = PT;
    // Back-compat shims so existing code can call global helpers
    w.providerDefaults = PT.defaults;
    w.ensureProviderConfigs = PT.ensureConfigs;
    w.getActiveProv = PT.getActiveProv;
    w.getActiveCfg = PT.getActiveCfg;
  } catch (_) {}
})(window);