import { readRuntimeConfig, setConfigValue, writeRuntimeConfig } from '../../../lib/config-store.mjs';
import { getSecret, hasSecret, setSecret } from '../../../lib/secret-store.mjs';
import { isMailerConfigured, reinitMailer } from '../../../lib/mailer.mjs';
import { PlatformError } from '../../kernel/errors.mjs';
import { readApplicationSettings, writeApplicationSettings } from './repository.mjs';

const SECRET_FIELDS = Object.freeze({
  anthropic_key: 'ANTHROPIC_API_KEY', openai_key: 'OPENAI_API_KEY', openrouter_key: 'OPENROUTER_API_KEY',
  etsy_key: 'ETSY_API_KEY', ebay_client_secret: 'EBAY_CLIENT_SECRET', ai_model_photo_local_token: 'LOCAL_IMAGE_TOKEN',
});
const RUNTIME_FIELDS = Object.freeze({
  ebay_client_id: 'EBAY_CLIENT_ID', ebay_ru_name: 'EBAY_RU_NAME', ebay_sandbox: 'EBAY_SANDBOX',
  ollama_url: 'OLLAMA_URL', public_base_url: 'PUBLIC_BASE_URL', ai_model_photo_local_url: 'LOCAL_IMAGE_URL',
  ai_model_photo_local_workflow_path: 'LOCAL_IMAGE_WORKFLOW_PATH', ai_model_photo_local_install_path: 'LOCAL_IMAGE_INSTALL_PATH',
});
const DB_FIELDS = new Set([
  'default_platform','default_ai','default_language','seller_notes','ai_model_photos_enabled','ai_model_photo_provider',
  'ai_model_photo_default_mode','ai_model_photo_default_variants','ai_model_photo_default_preset','ai_model_photo_openrouter_free_only',
  'ai_model_photo_block_underwear','ai_model_photo_block_kids','ai_model_photo_preserve_logos','ai_model_photo_openrouter_model',
  'ai_model_photo_openai_model','ai_model_photo_local_enabled','ai_model_photo_local_require_token','ai_model_photo_use_source_reference',
  'ai_model_photo_reference_strength','ai_model_photo_local_resolution','flux_runtime_profile','flux_default_profile',
  'flux_prompt_assistant','flux_default_style','flux_default_format','flux_default_variants','flux_seed_lock','flux_max_parallel_jobs',
  'smtp_host','smtp_port','smtp_user','smtp_from',
]);
const ALL_FIELDS = new Set([...Object.keys(SECRET_FIELDS), ...Object.keys(RUNTIME_FIELDS), ...DB_FIELDS]);

function fail(message, status = 400, code = 'SETTINGS_INVALID') {
  throw new PlatformError(message, { status, code, expose: true });
}

function cleanString(value, { max = 4096, multiline = false } = {}) {
  const result = String(value ?? '').trim();
  if (result.length > max) fail('Einstellungswert ist zu lang.');
  if (!multiline && /[\r\n\0]/.test(result)) fail('Einstellungswert enthält unzulässige Steuerzeichen.');
  return result;
}

export function createSettingsService({ etsyApi, ebayApi }) {
  function decorate(settings) {
    const result = { ...settings };
    result.has_anthropic_key = hasSecret('ANTHROPIC_API_KEY');
    result.has_openai_key = hasSecret('OPENAI_API_KEY');
    result.has_openrouter_key = hasSecret('OPENROUTER_API_KEY');
    result.has_etsy_key = hasSecret('ETSY_API_KEY');
    result.etsy_connected = Boolean(etsyApi?.isConnected?.());
    result.has_ebay_credentials = Boolean(ebayApi?.hasCredentials?.());
    result.ebay_connected = Boolean(ebayApi?.isConnected?.());
    result.ebay_sandbox = process.env.EBAY_SANDBOX === 'true';
    result.ollama_url = process.env.OLLAMA_URL || 'http://localhost:11434';
    result.public_base_url = process.env.PUBLIC_BASE_URL || '';
    result.ai_model_photo_local_url = process.env.LOCAL_IMAGE_URL || result.ai_model_photo_local_url || 'http://127.0.0.1:8188';
    result.ai_model_photo_local_workflow_path = process.env.LOCAL_IMAGE_WORKFLOW_PATH || result.ai_model_photo_local_workflow_path || 'local-ai/workflows/vendoo_flux_schnell_api.json';
    result.ai_model_photo_local_install_path = process.env.LOCAL_IMAGE_INSTALL_PATH || result.ai_model_photo_local_install_path || 'local-ai/comfyui';
    result.ai_model_photo_local_enabled = result.ai_model_photo_local_enabled || '1';
    result.ai_model_photo_local_require_token = result.ai_model_photo_local_require_token || '1';
    result.ai_model_photo_use_source_reference = result.ai_model_photo_use_source_reference || '1';
    result.ai_model_photo_reference_strength = result.ai_model_photo_reference_strength || '70';
    result.ai_model_photo_local_resolution = result.ai_model_photo_local_resolution || '768';
    result.ai_model_photo_preserve_logos = result.ai_model_photo_preserve_logos || '1';
    result.flux_runtime_profile = result.flux_runtime_profile || 'auto';
    result.flux_default_profile = result.flux_default_profile || 'balanced';
    result.flux_prompt_assistant = result.flux_prompt_assistant || '1';
    result.flux_default_style = result.flux_default_style || 'photorealistic';
    result.flux_default_format = result.flux_default_format || '768x768';
    result.flux_default_variants = result.flux_default_variants || '1';
    result.flux_seed_lock = result.flux_seed_lock || '0';
    result.flux_max_parallel_jobs = result.flux_max_parallel_jobs || '1';
    result.local_image_token_set = hasSecret('LOCAL_IMAGE_TOKEN');
    return result;
  }

  function validatePatch(input) {
    const source = input && typeof input === 'object' && !Array.isArray(input) ? input : {};
    for (const key of Object.keys(source)) if (!ALL_FIELDS.has(key)) fail(`Unbekanntes Einstellungsfeld: ${key}`);
    return source;
  }

  function smtpStatus() {
    const settings = readApplicationSettings();
    return {
      smtp_host: settings.smtp_host || process.env.SMTP_HOST || '', smtp_port: settings.smtp_port || process.env.SMTP_PORT || '587',
      smtp_user: settings.smtp_user || process.env.SMTP_USER || '', smtp_pass: hasSecret('SMTP_PASS') ? '••••••••' : '',
      smtp_from: settings.smtp_from || process.env.SMTP_FROM || '', configured: isMailerConfigured(),
      source: hasSecret('SMTP_PASS') ? 'encrypted-secret-store' : (process.env.SMTP_HOST ? 'environment' : 'none'),
    };
  }

  return Object.freeze({
    get() { return decorate(readApplicationSettings()); },
    update(input) {
      const source = validatePatch(input);
      let envContent = readRuntimeConfig();
      const dbPatch = {};
      for (const [field, secretName] of Object.entries(SECRET_FIELDS)) {
        if (source[field] !== undefined && source[field] !== '') setSecret(secretName, cleanString(source[field], { max: 16384 }), { source: 'settings-ui' });
      }
      for (const [field, envName] of Object.entries(RUNTIME_FIELDS)) {
        if (source[field] === undefined) continue;
        let value = cleanString(source[field], { max: 4096 });
        if (['public_base_url','ai_model_photo_local_url'].includes(field)) value = value.replace(/\/$/, '');
        envContent = setConfigValue(envContent, envName, value);
        process.env[envName] = value;
      }
      for (const field of DB_FIELDS) {
        if (source[field] === undefined) continue;
        dbPatch[field] = cleanString(source[field], { max: field === 'seller_notes' ? 16000 : 4096, multiline: field === 'seller_notes' });
      }
      if (dbPatch.ai_model_photo_local_enabled !== undefined) {
        const value = String(dbPatch.ai_model_photo_local_enabled) === '0' ? 'false' : 'true';
        envContent = setConfigValue(envContent, 'LOCAL_IMAGE_ENABLED', value); process.env.LOCAL_IMAGE_ENABLED = value;
      }
      if (dbPatch.ai_model_photo_local_require_token !== undefined) {
        const value = String(dbPatch.ai_model_photo_local_require_token) === '0' ? 'false' : 'true';
        envContent = setConfigValue(envContent, 'LOCAL_IMAGE_REQUIRE_TOKEN', value); process.env.LOCAL_IMAGE_REQUIRE_TOKEN = value;
      }
      writeRuntimeConfig(envContent);
      return decorate(writeApplicationSettings(dbPatch));
    },
    smtpStatus,

    updateSmtp(input) {
      const patch = {};
      for (const field of ['smtp_host','smtp_port','smtp_user','smtp_from']) if (input[field] !== undefined) patch[field] = cleanString(input[field], { max: 512 });
      if (input.smtp_pass !== undefined && input.smtp_pass !== '••••••••' && input.smtp_pass !== '') setSecret('SMTP_PASS', cleanString(input.smtp_pass, { max: 4096 }), { source: 'smtp-ui' });
      patch.smtp_pass = '';
      const settings = writeApplicationSettings(patch);
      const smtpSecret = getSecret('SMTP_PASS');
      if (settings.smtp_host && settings.smtp_user && smtpSecret) {
        reinitMailer({ host: settings.smtp_host, port: settings.smtp_port || '587', user: settings.smtp_user, pass: smtpSecret });
        if (settings.smtp_from) process.env.SMTP_FROM = settings.smtp_from;
      }
      return smtpStatus();
    },
    health() { return { ok: true, settings: Object.keys(readApplicationSettings()).length, smtp_configured: isMailerConfigured() }; },
  });
}
