import { AppServices } from "./app-services";
import { NoopAnalyticsService } from "./analytics/noop-analytics-service";
import { UmamiAnalyticsService } from "./analytics/umami-analytics-service";
import { MemoryCacheService } from "./cache/memory-cache-service";
import { GlitchtipErrorReportingService } from "./errors/glitchtip-error-reporting-service";
import { NoopErrorReportingService } from "./errors/noop-error-reporting-service";
import {
  GotifyNotificationService,
  NoopNotificationService,
} from "./notifications/gotify-notification-service";
import { PinoLoggerService } from "./logging/pino-logger-service";
import { config, getMaskedConfig } from "../config";

let singleton: AppServices | undefined;
export function getServerAppServices(): AppServices {
  if (singleton) return singleton;

  // Create logger first to log initialization
  const logger = new PinoLoggerService("server");

  logger.info("Initializing server application services", {
    environment: getMaskedConfig(),
    timestamp: new Date().toISOString(),
  });

  logger.info("Service configuration", {
    umamiEnabled: config.analytics.umami.enabled,
    sentryEnabled: config.errors.glitchtip.enabled,
    mailEnabled: Boolean(config.mail.host && config.mail.user),
    gotifyEnabled: config.notifications.gotify.enabled,
  });

  const analytics = config.analytics.umami.enabled
    ? new UmamiAnalyticsService({ enabled: true })
    : new NoopAnalyticsService();

  if (config.analytics.umami.enabled) {
    logger.info("Umami analytics service initialized");
  } else {
    logger.info("Noop analytics service initialized (analytics disabled)");
  }

  const notifications = config.notifications.gotify.enabled
    ? new GotifyNotificationService({
        url: config.notifications.gotify.url!,
        token: config.notifications.gotify.token!,
        enabled: true,
      })
    : new NoopNotificationService();

  if (config.notifications.gotify.enabled) {
    logger.info("Gotify notification service initialized");
  } else {
    logger.info(
      "Noop notification service initialized (notifications disabled)",
    );
  }

  const errors = config.errors.glitchtip.enabled
    ? new GlitchtipErrorReportingService({ enabled: true }, notifications)
    : new NoopErrorReportingService();

  if (config.errors.glitchtip.enabled) {
    logger.info("GlitchTip error reporting service initialized", {
      dsnPresent: Boolean(config.errors.glitchtip.dsn),
    });
  } else {
    logger.info(
      "Noop error reporting service initialized (error reporting disabled)",
    );
  }

  const cache = new MemoryCacheService();
  logger.info("Memory cache service initialized");

  logger.info("Pino logger service initialized", {
    name: "server",
    level: config.logging.level,
  });

  singleton = new AppServices(analytics, errors, cache, logger, notifications);

  logger.info("All application services initialized successfully");

  return singleton;
}
