/*
 * Copyright © 2025 Hexastack. All rights reserved.
 *
 * Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
 * 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
 * 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
 */

import { join } from 'path';

import { Config } from './types';

export const config: Config = {
  i18n: {
    translationFilename: process.env.I18N_TRANSLATION_FILENAME || 'messages',
  },
  appPath: process.cwd(),
  apiBaseUrl: process.env.API_ORIGIN || 'http://localhost:4000',
  uiBaseUrl: process.env.FRONTEND_BASE_URL
    ? process.env.FRONTEND_BASE_URL
    : 'http://localhost:8080', // default to local dev
  security: {
    httpsEnabled: process.env.HTTPS_ENABLED === 'true',
    trustProxy: process.env.HTTPS_ENABLED === 'true', // Nginx in use ?
    cors: {
      allRoutes: true,
      headers: 'content-type,x-xsrf-token,x-csrf-token',
      methods: ['GET', 'PATCH', 'POST', 'DELETE', 'OPTIONS', 'HEAD'],
      allowOrigins: process.env.FRONTEND_ORIGIN
        ? process.env.FRONTEND_ORIGIN.split(',').map((origin) => origin.trim())
        : ['*'],
      allowCredentials: true,
    },
    csrf: true,
  },
  sockets: {
    path: '/socket.io',
    // transports to allow connections to (e.g. ['polling', 'websocket'])
    transports: ['websocket'],
    beforeConnect(_handshake: any): boolean {
      // `true` allows the socket to connect.
      // (`false` would reject the connection)
      return true;
    },
    async afterDisconnect(_socket): Promise<void> {
      // By default: do nothing.
      // (but always trigger the callback)
      return;
    },
    serveClient: false,
    pingTimeout: 60000,
    pingInterval: 25000,
    maxHttpBufferSize: 10e7,
    allowUpgrades: true,
    cookie: false,
    // Whether to include response headers in the JWR originated for
    // each socket request (e.g. `io.socket.get()` in the browser)
    // This doesn't affect direct socket.io usage-- only if you're
    // communicating with Sails via the request interpreter
    // (e.g. the sails.io.js browser SDK)
    sendResponseHeaders: true,

    // Whether to include the status code in the JWR originated for
    // each socket request (e.g. `io.socket.get()` in the browser)
    // This doesn't affect direct socket.io usage-- only if you're
    // communicating with Sails via the request interpreter
    // (e.g. the sails.io.js browser SDK)
    sendStatusCode: true,

    // Whether to expose a 'get /__getcookie' route with CORS support
    // that sets a cookie (this is used by the sails.io.js socket client
    // to get access to a 3rd party cookie and to enable sessions).
    grant3rdPartyCookie: true,
    onlyAllowOrigins: process.env.FRONTEND_ORIGIN
      ? process.env.FRONTEND_ORIGIN.split(',').map((origin) => origin.trim())
      : [], // ['http://example.com', 'https://example.com'],
  },
  session: {
    secret: process.env.SESSION_SECRET || 'changeme',
    name: process.env.SESSION_NAME || 'hex.sid',
    adapter: 'connect-mongo',
    url: 'mongodb://localhost:27017/hexabot',
    collection: 'sessions',
    auto_reconnect: false,
    ssl: false,
    stringify: true,
    cookie: {
      maxAge: 24 * 60 * 60 * 1000,
    },
  },
  emails: {
    isEnabled: process.env.EMAIL_SMTP_ENABLED === 'true' || false,
    smtp: {
      port: process.env.EMAIL_SMTP_PORT
        ? parseInt(process.env.EMAIL_SMTP_PORT)
        : 25,
      host: process.env.EMAIL_SMTP_HOST || 'localhost',
      ignoreTLS: false,
      secure: process.env.EMAIL_SMTP_SECURE === 'true' || false,
      auth: {
        user: process.env.EMAIL_SMTP_USER || '',
        pass: process.env.EMAIL_SMTP_PASS || '',
      },
    },
    from: process.env.EMAIL_SMTP_FROM || 'noreply@example.com',
  },
  parameters: {
    uploadDir: join(process.cwd(), process.env.UPLOAD_DIR || '/uploads'),
    avatarDir: join(
      process.cwd(),
      process.env.UPLOAD_DIR || '/uploads',
      '/avatars',
    ),
    storageMode: 'disk',
    maxUploadSize: process.env.UPLOAD_MAX_SIZE_IN_BYTES
      ? Number(process.env.UPLOAD_MAX_SIZE_IN_BYTES)
      : 50 * 1024 * 1024, // 50 MB in bytes
    appName: 'Hexabot.ai',
    signedUrl: {
      salt: parseInt(process.env.SALT_LENGTH || '12'),
      secret: process.env.SIGNED_URL_SECRET || 'DEFAULT_SIGNED_URL_SECRET',
      expiresIn: process.env.SIGNED_URL_EXPIRES_IN || '24H',
    },
  },
  pagination: {
    limit: 10,
  },
  chatbot: {
    messages: {
      track_delivery: false,
      track_read: false,
    },
    logEvents: false,
  },
  log: {
    level: 'verbose',
  },
  cache: {
    type: process.env.REDIS_ENABLED === 'true' ? 'redis' : 'memory',
    ttl: 60 * 1000, // Milliseconds
    max: 100, // Maximum number of items in cache (defaults to 100)
    host: process.env.REDIS_HOST || 'redis',
    port: parseInt(process.env.REDIS_PORT || '6379'),
  },
  mongo: {
    user: process.env.MONGO_USER || 'dev_only',
    password: process.env.MONGO_PASSWORD || 'dev_only',
    uri:
      process.env.MONGO_URI || 'mongodb://dev_only:dev_only@localhost:27017/',
    dbName: process.env.MONGO_DB || 'hexabot',
    autoMigrate:
      // Either auto-migration is explicitly enabled and the node is primary (cluster case)
      (process.env.MONGO_AUTO_MIGRATE === 'true' &&
        (process.env.API_IS_PRIMARY_NODE || 'true') === 'true') ||
      // Otherwise, run only in dev mode
      !(process.env.NODE_ENV || 'development').toLowerCase().includes('prod'),
  },
  env: process.env.NODE_ENV || 'development',
  authentication: {
    jwtOptions: {
      salt: parseInt(process.env.SALT_LENGTH || '12'),
      secret: process.env.JWT_SECRET || 'DEFAULT_AUTH_SECRET',
      expiresIn: process.env.JWT_EXPIRES_IN || '24h',
    },
  },
  invitation: {
    jwtOptions: {
      salt: parseInt(process.env.SALT_LENGTH || '12'),
      secret: process.env.INVITATION_JWT_SECRET || 'DEFAULT_INVITATION_SECRET',
      expiresIn: process.env.INVITATION_EXPIRES_IN || '24h',
    },
  },
  password_reset: {
    jwtOptions: {
      salt: parseInt(process.env.SALT_LENGTH || '12'),
      secret:
        process.env.PASSWORD_RESET_SECRET || 'DEFAULT_PASSWORD_RESET_SECRET',
      expiresIn: process.env.PASSWORD_RESET_EXPIRES_IN || '1H',
    },
  },
  confirm_account: {
    jwtOptions: {
      salt: parseInt(process.env.SALT_LENGTH || '12'),
      secret:
        process.env.CONFIRM_ACCOUNT_SECRET || 'DEFAULT_CONFIRM_ACCOUNT_SECRET',
      expiresIn: process.env.CONFIRM_ACCOUNT_EXPIRES_IN || '1H',
    },
  },
  analytics: {
    thresholds: {
      loyalty: 5 * 24 * 60 * 60 * 1000, // 5 days
      returning: 20 * 60 * 60 * 1000, // 20 hours
      retention: 3 * 24 * 60 * 60 * 1000, // 3 days
      retentionReset: 24 * 60 * 60 * 1000, // 1 day
    },
  },
};
