import { Client, GatewayIntentBits, Partials } from 'discord.js';
import { env } from './config/env';
import { CommandHandler } from './services/commandHandler';
import { EventHandlerService } from './services/eventHandler';
import { logger } from './utils/logger';
import { context } from './config/context';
import { createWebServer } from './web/server';
import { settingsStore } from './config/state';

async function bootstrap() {
  context.admin.setStartTime(Date.now());
  await settingsStore.init();

  const client = new Client({
    intents: [
      GatewayIntentBits.Guilds,
      GatewayIntentBits.GuildMembers,
      GatewayIntentBits.GuildMessages,
      GatewayIntentBits.MessageContent,
      GatewayIntentBits.GuildVoiceStates,
      GatewayIntentBits.GuildMessageReactions
    ],
    partials: [Partials.Channel, Partials.GuildMember, Partials.Message, Partials.Reaction, Partials.User]
  });

  const commandHandler = new CommandHandler(client, context.admin, context.statuspage);
  context.commandHandler = commandHandler;
  context.client = client;
  context.admin.setClient(client);
  context.statuspage.setClient(client);
  context.tickets.setClient(client);
  context.ticketAutomation.startLoop();
  context.birthdays.setClient(client);
  context.reactionRoles.setClient(client);
  context.events.setClient(client);
  context.events.startScheduler();
  context.register.setClient(client);
  context.stats.setClient(client);
  await context.reactionRoles.loadCache();
  logger.setSink((entry) => context.admin.pushLog(entry));
  for (const gid of settingsStore.all().keys()) {
    const cfg = await context.statuspage.getConfig(gid);
    await context.statuspage.saveConfig(gid, cfg);
  }

  await commandHandler.loadCommands();
  await commandHandler.registerSlashCommands();

  const eventHandler = new EventHandlerService(client);
  await eventHandler.loadEvents();

  client.login(env.token);

  const app = createWebServer();
  app.listen(env.port, () => logger.info(`Webserver läuft auf Port ${env.port}`));
}

bootstrap().catch((err) => logger.error('Bootstrap failed', err));
