import {
  ActionRowBuilder,
  ButtonBuilder,
  ButtonInteraction,
  ButtonStyle,
  CategoryChannelResolvable,
  ChannelType,
  ChatInputCommandInteraction,
  EmbedBuilder,
  Guild,
  GuildMember,
  PermissionsBitField,
  TextChannel,
  Client,
  Message
} from 'discord.js';
import fs from 'fs';
import path from 'path';
import { prisma } from '../database';
import { TicketRecord, TicketStatus } from '../utils/types';
import { logger } from '../utils/logger';
import { settingsStore } from '../config/state';
import { env } from '../config/env';
import { context } from '../config/context';

const PIPELINE_STATUS: TicketStatus[] = ['neu', 'in_bearbeitung', 'warten_auf_user', 'erledigt'];

export class TicketService {
  private categoryName = 'Tickets';
  private client: Client | null = null;

  constructor(private transcriptRoot = './transcripts') {}

  public setClient(client: Client) {
    this.client = client;
  }

  private formatChannelName(customId: string, username: string, ticketTag: string) {
    const slug = (s: string) => s.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 20) || 'ticket';
    return `${slug(customId)}-${slug(username)}-${ticketTag}`.toLowerCase();
  }

  private formatTicketTag(n: number) {
    return `#${String(n).padStart(4, '0')}`;
  }

  private normalizeStatus(status: string): TicketStatus {
    if (PIPELINE_STATUS.includes(status as TicketStatus)) return status as TicketStatus;
    if (status === 'open') return 'neu';
    if (status === 'in-progress') return 'in_bearbeitung';
    if (status === 'closed') return 'erledigt';
    return 'neu';
  }

  public async createTicket(interaction: ChatInputCommandInteraction): Promise<TicketRecord | null> {
    if (!interaction.guildId || !interaction.guild) return null;
    if (!this.isEnabled(interaction.guildId)) {
      await interaction.reply({ content: 'Tickets sind für diese Guild deaktiviert.', ephemeral: true });
      return null;
    }
    const existing = await prisma.ticket.findFirst({
      where: { userId: interaction.user.id, guildId: interaction.guild.id, status: { notIn: ['closed', 'erledigt'] } }
    });
    if (existing) {
      await interaction.reply({ content: 'Du hast bereits ein offenes Ticket.', ephemeral: true });
      return null;
    }
    return this.openTicket(interaction.guild, interaction.member as GuildMember, 'support');
  }

  public async handleButton(interaction: ButtonInteraction) {
    if (!interaction.guild) return;
    if (interaction.customId === 'support:toggle') {
      await this.toggleSupport(interaction);
      return;
    }
    if (interaction.customId.startsWith('ticket:create:')) {
      if (!this.isEnabled(interaction.guild.id)) {
        await interaction.reply({ content: 'Tickets sind für diese Guild deaktiviert.', ephemeral: true });
        return;
      }
      const topic = interaction.customId.split(':')[2] || 'allgemein';
      const existing = await prisma.ticket.findFirst({
        where: { userId: interaction.user.id, guildId: interaction.guild.id, status: { notIn: ['closed', 'erledigt'] } }
      });
      if (existing) {
        await interaction.reply({ content: 'Du hast bereits ein offenes Ticket. Bitte schließe es zuerst.', ephemeral: true });
        return;
      }

      const record = await this.openTicket(interaction.guild, interaction.member as GuildMember, topic);
      await interaction.reply({
        content: record ? 'Ticket erstellt! Schau im neuen Kanal nach.' : 'Ticket konnte nicht erstellt werden.',
        ephemeral: true
      });
      return;
    }

    if (interaction.customId === 'ticket:claim') {
      const ticket = await this.getTicketByChannel(interaction);
      if (!ticket) {
        await interaction.reply({ content: 'Kein Ticket gefunden.', ephemeral: true });
        return;
      }
      if (ticket.userId === interaction.user.id) {
        await interaction.reply({ content: 'Du kannst dein eigenes Ticket nicht claimen.', ephemeral: true });
        return;
      }
      await prisma.ticket.update({
        where: { id: ticket.id },
        data: { claimedBy: interaction.user.id, status: 'in_bearbeitung', firstClaimAt: ticket.firstClaimAt ?? new Date() }
      });
      await interaction.reply({ content: `${interaction.user} hat das Ticket übernommen.` });
      await this.runAutomations({ ...ticket, status: 'in_bearbeitung', guildId: interaction.guild.id });
      return;
    }

    if (interaction.customId === 'ticket:close') {
      const ok = await this.closeTicketButton(interaction);
      if (!ok) await interaction.reply({ content: 'Ticket konnte nicht geschlossen werden.', ephemeral: true });
      return;
    }

    if (interaction.customId === 'ticket:transcript') {
      const ticket = await this.getTicketByChannel(interaction);
      if (!ticket) {
        await interaction.reply({ content: 'Kein Ticket gefunden.', ephemeral: true });
        return;
      }
      const transcriptPath = await this.exportTranscript(interaction.channel as TextChannel, ticket.id);
      await interaction.reply({ content: `Transcript erstellt: ${transcriptPath}`, ephemeral: true });
      return;
    }

    if (interaction.customId.startsWith('ticket:status:')) {
      const targetStatus = interaction.customId.split(':')[2];
      const ticket = await this.getTicketByChannel(interaction);
      if (!ticket) {
        await interaction.reply({ content: 'Kein Ticket gefunden.', ephemeral: true });
        return;
      }
      const member = interaction.member as GuildMember;
      const cfg = settingsStore.get(interaction.guild.id);
      const supportRoleId = cfg?.supportRoleId || env.supportRoleId;
      const canManage =
        ticket.claimedBy === interaction.user.id ||
        (supportRoleId && member?.roles.cache.has(supportRoleId)) ||
        member?.permissions.has(PermissionsBitField.Flags.ManageMessages);
      if (!canManage) {
        await interaction.reply({ content: 'Keine Berechtigung, Status zu ändern.', ephemeral: true });
        return;
      }
      await this.updateStatus(ticket.id, targetStatus as TicketStatus);
      await interaction.reply({ content: `Status gesetzt auf ${targetStatus}.`, ephemeral: true });
      return;
    }
  }

  public async claimTicket(interaction: ChatInputCommandInteraction) {
    const channel = interaction.channel as TextChannel;
    const ticket = await prisma.ticket.findFirst({ where: { channelId: channel.id } });
    if (!ticket) return false;
    if (ticket.userId === interaction.user.id) {
      await interaction.reply({ content: 'Du kannst dein eigenes Ticket nicht claimen.', ephemeral: true });
      return true;
    }
    await prisma.ticket.update({
      where: { id: ticket.id },
      data: { claimedBy: interaction.user.id, status: 'in_bearbeitung', firstClaimAt: ticket.firstClaimAt ?? new Date() }
    });
    await channel.send({ content: `${interaction.user} hat das Ticket übernommen.` });
    await this.runAutomations({ ...ticket, status: 'in_bearbeitung', guildId: channel.guildId });
    return true;
  }

  public async closeTicket(interaction: ChatInputCommandInteraction, reason?: string) {
    const channel = interaction.channel as TextChannel;
    const ticket = await prisma.ticket.findFirst({ where: { channelId: channel.id } });
    if (!ticket) return false;
    const transcriptPath = await this.exportTranscript(channel, ticket.id);
    await prisma.ticket.update({ where: { id: ticket.id }, data: { status: 'erledigt', transcript: transcriptPath } });
    await channel.send({ content: `Ticket geschlossen. Grund: ${reason ?? 'Kein Grund angegeben'}` }).catch(() => undefined);
    await this.sendTranscriptToLog(channel.guild, transcriptPath, ticket);
    await channel.delete('Ticket geschlossen');
    return true;
  }

  public buildPanelEmbed() {
    const embed = new EmbedBuilder()
      .setTitle('Ticket Support')
      .setDescription('Klicke auf eine Kategorie, um ein Ticket zu eröffnen.')
      .setColor(0xf97316)
      .addFields(
        { name: 'Ban Einspruch', value: 'Du bist gebannt worden und möchtest eine faire Klärung?' },
        { name: 'Discord-Hilfe', value: 'Dir fehlen Rollen oder du hast Probleme mit Nachrichten?' },
        { name: 'Feedback / Beschwerde', value: 'Du willst Lob, Kritik oder Vorschläge loswerden?' },
        { name: 'Allgemeine Frage', value: 'Alles andere, was nicht in die Kategorien passt.' }
      );

    const buttons = new ActionRowBuilder<ButtonBuilder>().addComponents(
      new ButtonBuilder().setCustomId('ticket:create:ban').setLabel('Ban Einspruch').setEmoji('🚫').setStyle(ButtonStyle.Primary),
      new ButtonBuilder().setCustomId('ticket:create:help').setLabel('Discord-Hilfe').setEmoji('💬').setStyle(ButtonStyle.Secondary),
      new ButtonBuilder().setCustomId('ticket:create:feedback').setLabel('Feedback').setEmoji('📝').setStyle(ButtonStyle.Secondary),
      new ButtonBuilder().setCustomId('ticket:create:other').setLabel('Allgemeine Frage').setEmoji('❔').setStyle(ButtonStyle.Secondary)
    );

    return { embed, buttons };
  }

  public buildCustomPanel(config: {
    title?: string;
    description?: string;
    categories: { label: string; emoji?: string; customId: string }[];
  }) {
    const embed = new EmbedBuilder()
      .setTitle(config.title || 'Ticket Support')
      .setDescription(
        config.description ||
          'Bitte wähle eine Kategorie, um ein Ticket zu erstellen. Sei respektvoll & sachlich. Missbrauch führt zu Konsequenzen.'
      )
      .setColor(0xf97316);

    const buttons = new ActionRowBuilder<ButtonBuilder>();
    config.categories.slice(0, 5).forEach((cat) => {
      const btn = new ButtonBuilder().setCustomId(`ticket:create:${cat.customId}`).setLabel(cat.label).setStyle(ButtonStyle.Secondary);
      if (cat.emoji) btn.setEmoji(cat.emoji);
      buttons.addComponents(btn);
    });
    return { embed, buttons };
  }

  public async exportTranscript(channel: TextChannel, ticketId: string) {
    const messages = await channel.messages.fetch({ limit: 100 });
    const lines = messages
      .sort((a, b) => a.createdTimestamp - b.createdTimestamp)
      .map((m) => `[${new Date(m.createdTimestamp).toISOString()}] ${m.author.tag}: ${m.content}`)
      .join('\n');

    const dir = path.resolve(this.transcriptRoot);
    if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
    const file = path.join(dir, `${ticketId}.txt`);
    fs.writeFileSync(file, lines, 'utf8');
    logger.info(`Transcript geschrieben: ${file}`);
    return file;
  }

  private async openTicket(guild: Guild, member: GuildMember, topic: string): Promise<TicketRecord | null> {
    if (!this.isEnabled(guild.id)) return null;
    const category = await this.ensureCategory(guild);
    const supportRoleId = settingsStore.get(guild.id)?.supportRoleId || env.supportRoleId || null;
    const overwrites: any[] = [
      {
        id: guild.id,
        deny: [
          PermissionsBitField.Flags.ViewChannel,
          PermissionsBitField.Flags.SendMessages,
          PermissionsBitField.Flags.AttachFiles,
          PermissionsBitField.Flags.ReadMessageHistory
        ]
      },
      {
        id: member.id,
        allow: [
          PermissionsBitField.Flags.ViewChannel,
          PermissionsBitField.Flags.SendMessages,
          PermissionsBitField.Flags.AttachFiles,
          PermissionsBitField.Flags.ReadMessageHistory
        ]
      }
    ];
    if (supportRoleId) {
      overwrites.push({
        id: supportRoleId,
        allow: [
          PermissionsBitField.Flags.ViewChannel,
          PermissionsBitField.Flags.SendMessages,
          PermissionsBitField.Flags.AttachFiles,
          PermissionsBitField.Flags.ReadMessageHistory
        ]
      });
    }
    const nextNumber = (await prisma.ticket.count({ where: { guildId: guild.id } })) + 1;
    const ticketTag = this.formatTicketTag(nextNumber);
    const channelName = this.formatChannelName(topic, member.user.username, ticketTag);
    const channel = await guild.channels.create({
      name: channelName,
      type: ChannelType.GuildText,
      parent: category as any,
      permissionOverwrites: overwrites
    });

    const record = await prisma.ticket.create({
      data: {
        userId: member.id,
        channelId: channel.id,
        guildId: guild.id,
        topic,
        priority: 'normal',
        status: 'neu',
        ticketNumber: nextNumber,
        createdAt: new Date()
      }
    });

    const embed = new EmbedBuilder()
      .setTitle(`Ticket: ${topic}`)
      .setDescription('Ein Teammitglied wird sich gleich kümmern. Nutze `/claim`, um den Fall zu übernehmen.')
      .setColor(0x7289da);

    const controls = new ActionRowBuilder<ButtonBuilder>().addComponents(
      new ButtonBuilder().setCustomId('ticket:claim').setLabel('Claim').setStyle(ButtonStyle.Primary),
      new ButtonBuilder().setCustomId('ticket:close').setLabel('Schliessen').setStyle(ButtonStyle.Danger),
      new ButtonBuilder().setCustomId('ticket:transcript').setLabel('Transcript').setStyle(ButtonStyle.Secondary)
    );
    const statusRow = this.buildStatusButtons();

    const supportMention = supportRoleId ? `<@&${supportRoleId}>` : null;
    await channel.send({
      content: supportMention ? `${member} ${supportMention}` : `${member}`,
      embeds: [embed],
      components: [controls, statusRow],
      allowedMentions: supportMention ? { roles: [supportRoleId as string], users: [member.id] } : { users: [member.id] }
    });
    await this.sendTicketCreatedLog(guild, channel, member, topic, nextNumber, supportRoleId);
    await this.runAutomations({ ...record });
    return record as TicketRecord;
  }

  private async getTicketByChannel(interaction: ButtonInteraction) {
    const channel = interaction.channel as TextChannel | null;
    if (!channel) return null;
    return prisma.ticket.findFirst({ where: { channelId: channel.id } });
  }

  private async closeTicketButton(interaction: ButtonInteraction) {
    const channel = interaction.channel as TextChannel | null;
    if (!channel) return false;
    const ticket = await prisma.ticket.findFirst({ where: { channelId: channel.id } });
    if (!ticket) return false;
    const transcriptPath = await this.exportTranscript(channel, ticket.id);
    await prisma.ticket.update({ where: { id: ticket.id }, data: { status: 'erledigt', transcript: transcriptPath } });
    await interaction.reply({ content: 'Ticket geschlossen.', ephemeral: true }).catch(() => undefined);
    await this.sendTranscriptToLog(channel.guild, transcriptPath, ticket);
    await channel.delete('Ticket geschlossen');
    return true;
  }

  private async sendTranscriptToLog(guild: Guild, transcriptPath: string, ticket: { id: string; channelId: string }) {
    const { logChannelId, categories } = this.getLoggingConfig(guild.id);
    if (!logChannelId || categories.ticketActions === false) return;
    const logChannel = await guild.channels.fetch(logChannelId).catch(() => null);
    if (!logChannel || !logChannel.isTextBased()) return;
    try {
      await (logChannel as any).send({
        content: `Transcript für Ticket ${ticket.id} (${ticket.channelId})`,
        files: [transcriptPath]
      });
    } catch (err) {
      logger.warn('Transcript konnte nicht im Log-Kanal gesendet werden', err);
    }
  }

  private async sendTicketCreatedLog(
    guild: Guild,
    ticketChannel: TextChannel,
    member: GuildMember,
    topic: string,
    ticketNumber: number,
    supportRoleId: string | null
  ) {
    const { logChannelId, categories } = this.getLoggingConfig(guild.id);
    if (!logChannelId || categories.ticketActions === false) return;
    const logChannel = await guild.channels.fetch(logChannelId).catch(() => null);
    if (!logChannel || !logChannel.isTextBased()) return;
    const roleMention = supportRoleId ? `<@&${supportRoleId}>` : '';
    const content = `${roleMention ? roleMention + ' ' : ''}Neues Ticket ${this.formatTicketTag(ticketNumber)} von ${member} | Thema: ${topic} | Kanal: ${ticketChannel}`;
    try {
      await (logChannel as any).send({
        content,
        allowedMentions: roleMention && supportRoleId ? { roles: [supportRoleId], users: [member.id] } : { users: [member.id] }
      });
    } catch (err) {
      logger.warn('Ticket-Log konnte nicht gesendet werden', err);
    }
  }

  private getLoggingConfig(guildId: string) {
    const cfg = settingsStore.get(guildId) || {};
    const logging = (cfg as any).loggingConfig || (cfg as any).automodConfig?.loggingConfig || {};
    const categories = typeof logging.categories === 'object' && logging.categories ? logging.categories : {};
    return {
      logChannelId: logging.logChannelId || cfg.logChannelId,
      categories
    };
  }

  private async ensureCategory(guild: Guild): Promise<CategoryChannelResolvable> {
    let category = guild.channels.cache.find(
      (c) => c.type === ChannelType.GuildCategory && c.name.toLowerCase().includes(this.categoryName.toLowerCase())
    );
    if (!category) {
      category = await guild.channels.create({ name: this.categoryName, type: ChannelType.GuildCategory });
    }
    return category as CategoryChannelResolvable;
  }

  public async publishSupportPanel(guildId: string, cfg?: any) {
    if (!this.client) return null;
    const guild = this.client.guilds.cache.get(guildId) ?? (await this.client.guilds.fetch(guildId).catch(() => null));
    if (!guild) return null;
    const settings = settingsStore.get(guildId) || {};
    const config = { ...(settings.supportLoginConfig ?? {}), ...(cfg ?? {}) };
    if (!config.panelChannelId) return null;
    const channel = await guild.channels.fetch(config.panelChannelId).catch(() => null);
    if (!channel || !channel.isTextBased()) return null;
    const embed = new EmbedBuilder()
      .setTitle(config.title || 'Support Login')
      .setDescription(config.description || 'Melde dich an/ab, um die Support-Rolle zu erhalten.')
      .setColor(0xf97316);
    const btn = new ButtonBuilder()
      .setCustomId('support:toggle')
      .setLabel(config.loginLabel || 'Ich bin jetzt im Support')
      .setStyle(ButtonStyle.Success);
    const row = new ActionRowBuilder<ButtonBuilder>().addComponents(btn);
    let messageId = config.panelMessageId;
    try {
      if (messageId) {
        const msg = await (channel as TextChannel).messages.fetch(messageId);
        await msg.edit({ embeds: [embed], components: [row] });
      } else {
        const sent = await (channel as TextChannel).send({ embeds: [embed], components: [row] });
        messageId = sent.id;
      }
    } catch {
      const sent = await (channel as TextChannel).send({ embeds: [embed], components: [row] });
      messageId = sent.id;
    }
    await settingsStore.set(guildId, { supportLoginConfig: { ...config, panelMessageId: messageId } } as any);
    return messageId;
  }

  public async getSupportStatus(guildId: string) {
    const repo: any = (prisma as any).ticketSupportSession;
    if (!repo?.findMany) return { active: [], recent: [] };
    const active = await repo.findMany({ where: { guildId, endedAt: null }, orderBy: { startedAt: 'desc' }, take: 25 });
    const recent = await repo.findMany({
      where: { guildId, endedAt: { not: null } },
      orderBy: { endedAt: 'desc' },
      take: 25
    });
    return { active, recent };
  }

  private async toggleSupport(interaction: ButtonInteraction) {
    const guildId = interaction.guildId;
    if (!guildId || !interaction.guild) return;
    const cfg = settingsStore.get(guildId) || {};
    const roleId = cfg.supportRoleId;
    if (!roleId) {
      await interaction.reply({ content: 'Keine Support-Rolle konfiguriert.', ephemeral: true });
      return;
    }
    const member = interaction.member as GuildMember;
    const hasRole = member.roles.cache.has(roleId);
    if (!hasRole) {
      try {
        await member.roles.add(roleId, 'Support Login');
      } catch {
        await interaction.reply({ content: 'Rolle konnte nicht vergeben werden.', ephemeral: true });
        return;
      }
      await this.closeOpenSession(guildId, member.id, roleId);
      const repo: any = (prisma as any).ticketSupportSession;
      if (repo?.create) await repo.create({ data: { guildId, userId: member.id, roleId } });
      await interaction.reply({ content: 'Du bist jetzt im Support.', ephemeral: true });
      await this.logSupportStatus(interaction.guild, `${member.user.tag} ist jetzt im Support.`);
    } else {
      try {
        await member.roles.remove(roleId, 'Support Logout');
      } catch {
        /* ignore */
      }
      const duration = await this.closeOpenSession(guildId, member.id, roleId);
      await interaction.reply({ content: `Support beendet. Dauer: ${duration ? Math.round(duration / 60) + 'm' : '-'}.`, ephemeral: true });
      await this.logSupportStatus(interaction.guild, `${member.user.tag} hat den Support verlassen.`);
    }
  }

  private async closeOpenSession(guildId: string, userId: string, roleId: string) {
    const repo: any = (prisma as any).ticketSupportSession;
    if (!repo?.findFirst) return null;
    const open = await repo.findFirst({
      where: { guildId, userId, roleId, endedAt: null },
      orderBy: { startedAt: 'desc' }
    });
    if (!open) return null;
    const endedAt = new Date();
    const durationSeconds = Math.max(0, Math.round((endedAt.getTime() - open.startedAt.getTime()) / 1000));
    await repo.update({ where: { id: open.id }, data: { endedAt, durationSeconds } });
    return durationSeconds;
  }

  private async logSupportStatus(guild: Guild, message: string) {
    const { logChannelId, categories } = this.getLoggingConfig(guild.id);
    if (!logChannelId || categories.ticketActions === false) return;
    const logChannel = await guild.channels.fetch(logChannelId).catch(() => null);
    if (!logChannel || !logChannel.isTextBased()) return;
    await (logChannel as any).send({ content: `[Support] ${message}` }).catch(() => undefined);
  }

  public async trackFirstResponse(message: Message) {
    if (!message.guildId || !message.channelId || message.author?.bot) return;
    const ticket = await prisma.ticket.findFirst({ where: { channelId: message.channelId } });
    if (!ticket || ticket.firstResponseAt) return;
    const cfg = settingsStore.get(message.guildId);
    const supportRoleId = cfg?.supportRoleId || env.supportRoleId;
    const member = message.member as GuildMember | null;
    const isSupport =
      (supportRoleId && member?.roles.cache.has(supportRoleId)) ||
      member?.permissions.has(PermissionsBitField.Flags.ManageMessages) ||
      ticket.userId !== message.author.id;
    if (!isSupport) return;
    await prisma.ticket.update({ where: { id: ticket.id }, data: { firstResponseAt: new Date() } });
  }

  public async suggestKnowledgeBase(message: Message) {
    if (!message.guildId || !message.channelId || message.author?.bot) return;
    const ticket = await prisma.ticket.findFirst({ where: { channelId: message.channelId } });
    if (!ticket || ticket.kbSuggestionSentAt) return;
    if (ticket.userId !== message.author.id) return;
    const matches = await context.knowledgeBase.match(message.guildId, message.content || '');
    if (!matches.length) return;
    const channel = message.channel as TextChannel | null;
    if (!channel || !channel.isTextBased()) return;
    const lines = matches.map((m: any) => `• **${m.title}** – ${m.content}`).join('\n');
    await channel.send({ content: `Ich habe vielleicht passende Lösungen gefunden:\n${lines}` }).catch(() => undefined);
    await prisma.ticket.update({ where: { id: ticket.id }, data: { kbSuggestionSentAt: new Date() } });
  }

  public async updateStatus(ticketId: string, status: TicketStatus) {
    const normalized = this.normalizeStatus(status);
    const ticket = await prisma.ticket.findFirst({ where: { id: ticketId } });
    if (!ticket) return null;
    const updated = await prisma.ticket.update({ where: { id: ticketId }, data: { status: normalized } });
    await this.runAutomations(updated);
    return updated;
  }

  private async runAutomations(ticket: any) {
    try {
      await context.ticketAutomation.checkTicket(ticket);
    } catch (err) {
      logger.warn('Automation check failed', err);
    }
  }

  private isEnabled(guildId: string) {
    const cfg = settingsStore.get(guildId);
    return cfg?.ticketsEnabled === true;
  }

  private buildStatusButtons() {
    return new ActionRowBuilder<ButtonBuilder>().addComponents(
      new ButtonBuilder().setCustomId('ticket:status:neu').setLabel('Neu').setStyle(ButtonStyle.Secondary),
      new ButtonBuilder().setCustomId('ticket:status:in_bearbeitung').setLabel('In Bearbeitung').setStyle(ButtonStyle.Primary),
      new ButtonBuilder().setCustomId('ticket:status:warten_auf_user').setLabel('Warten auf User').setStyle(ButtonStyle.Secondary),
      new ButtonBuilder().setCustomId('ticket:status:erledigt').setLabel('Erledigt').setStyle(ButtonStyle.Success)
    );
  }
}
