import { prisma } from '../database';
import { context } from '../config/context';
import { TextChannel } from 'discord.js';

type AutomationCondition = {
  category?: string;
  status?: string;
  minHours?: number;
};

type AutomationAction = {
  type: 'pingRole' | 'reminder' | 'flag';
  roleId?: string;
  message?: string;
  status?: string;
};

export class TicketAutomationService {
  public async list(guildId: string) {
    return prisma.ticketAutomationRule.findMany({ where: { guildId }, orderBy: { createdAt: 'asc' } });
  }

  public async save(rule: {
    id?: string;
    guildId: string;
    name: string;
    condition: AutomationCondition;
    action: AutomationAction;
    active?: boolean;
  }) {
    if (rule.id) {
      return prisma.ticketAutomationRule.update({
        where: { id: rule.id },
        data: {
          name: rule.name,
          condition: rule.condition,
          action: rule.action,
          active: rule.active ?? true
        }
      });
    }
    return prisma.ticketAutomationRule.create({
      data: {
        guildId: rule.guildId,
        name: rule.name,
        condition: rule.condition,
        action: rule.action,
        active: rule.active ?? true
      }
    });
  }

  public async remove(guildId: string, id: string) {
    const found = await prisma.ticketAutomationRule.findFirst({ where: { id, guildId } });
    if (!found) return false;
    await prisma.ticketAutomationRule.delete({ where: { id } });
    return true;
  }

  public async checkTicket(ticket: any, isScheduled = false) {
    const rules = await prisma.ticketAutomationRule.findMany({ where: { guildId: ticket.guildId, active: true }, take: 50 });
    if (!rules.length) return;
    const guild = context.client?.guilds.cache.get(ticket.guildId) ?? (await context.client?.guilds.fetch(ticket.guildId).catch(() => null));
    if (!guild) return;
    const channel = ticket.channelId ? await guild.channels.fetch(ticket.channelId).catch(() => null) : null;
    for (const rule of rules) {
      const cond = (rule.condition as any) || {};
      const act = (rule.action as any) || {};
      const matchesCategory =
        !cond.category || (ticket.topic || '').toLowerCase().includes(String(cond.category).toLowerCase());
      const matchesStatus = !cond.status || ticket.status === cond.status;
      const matchesAge =
        !cond.minHours ||
        (ticket.createdAt &&
          Date.now() - new Date(ticket.createdAt).getTime() >= Number(cond.minHours) * 3600 * 1000);
      if (!matchesCategory || !matchesStatus || !matchesAge) continue;
      if (act.type === 'pingRole' && channel?.isTextBased() && act.roleId) {
        await (channel as TextChannel).send({ content: `<@&${act.roleId}> Bitte Ticket pruefen.` }).catch(() => undefined);
      }
      if (act.type === 'reminder' && channel?.isTextBased()) {
        await (channel as TextChannel)
          .send({ content: act.message || 'Reminder: Ticket ist noch offen.' })
          .catch(() => undefined);
      }
      if (act.type === 'flag' && act.status && ticket.status !== act.status) {
        await prisma.ticket.update({ where: { id: ticket.id }, data: { status: act.status } }).catch(() => undefined);
      }
    }
  }

  public startLoop() {
    setInterval(() => {
      const since = new Date(Date.now() - 24 * 60 * 60 * 1000);
      prisma.ticket
        .findMany({
          where: { status: { notIn: ['erledigt', 'closed'] }, createdAt: { lte: since } },
          take: 50
        })
        .then((tickets) => tickets.forEach((t) => this.checkTicket(t, true)))
        .catch(() => undefined);
    }, 60_000);
  }
}
