import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
import { PrismaService } from '@chatapp/database';

@Injectable()
export class BotUsersService {
  constructor(private readonly prisma: PrismaService) {}

  /**
   * Lista todos los bot users de un workspace.
   * Permite filtrar por appId y por estado activo/inactivo.
   */
  async listBots(workspaceId: string, opts: { appId?: string; isActive?: boolean } = {}) {
    const where: any = { workspaceId };
    if (opts.appId) where.appId = opts.appId;
    if (opts.isActive !== undefined) where.isActive = opts.isActive;

    return this.prisma.botUser.findMany({
      where,
      include: {
        app: { select: { id: true, appName: true, appSlug: true, iconUrl: true } },
      },
      orderBy: { createdAt: 'desc' },
    });
  }

  /**
   * Obtiene un bot user específico.
   */
  async getBot(workspaceId: string, botId: string) {
    const bot = await this.prisma.botUser.findUnique({
      where: { id: botId },
      include: {
        app: { select: { id: true, appName: true, appSlug: true, iconUrl: true } },
      },
    });
    if (!bot || bot.workspaceId !== workspaceId) {
      throw new NotFoundException('Bot user not found');
    }
    return bot;
  }

  /**
   * Crea un nuevo bot user.
   * Si se especifica appId, valida que la app exista y pertenezca al workspace.
   */
  async createBot(
    workspaceId: string,
    data: { name: string; display_name: string; app_id?: string; avatar_url?: string },
  ) {
    if (data.app_id) {
      const app = await this.prisma.app.findFirst({
        where: { id: data.app_id, workspaceId, isActive: true },
      });
      if (!app) throw new BadRequestException('App not found or not installed in this workspace');
    }

    // Validar que no exista ya un bot con el mismo name en el workspace
    const existing = await this.prisma.botUser.findFirst({
      where: { workspaceId, name: data.name },
    });
    if (existing) throw new BadRequestException('Bot with this name already exists');

    return this.prisma.botUser.create({
      data: {
        workspaceId,
        name: data.name,
        displayName: data.display_name,
        appId: data.app_id || null,
        avatarUrl: data.avatar_url || null,
        isActive: true,
      },
      include: {
        app: { select: { id: true, appName: true, appSlug: true, iconUrl: true } },
      },
    });
  }

  /**
   * Actualiza un bot user (nombre display, avatar).
   */
  async updateBot(
    workspaceId: string,
    botId: string,
    data: { display_name?: string; avatar_url?: string; name?: string },
  ) {
    const bot = await this.prisma.botUser.findFirst({
      where: { id: botId, workspaceId },
    });
    if (!bot) throw new NotFoundException('Bot user not found');

    const updateData: any = {};
    if (data.display_name !== undefined) updateData.displayName = data.display_name;
    if (data.avatar_url !== undefined) updateData.avatarUrl = data.avatar_url;
    if (data.name !== undefined) {
      // Validar unicidad del name si cambia
      if (data.name !== bot.name) {
        const conflict = await this.prisma.botUser.findFirst({
          where: { workspaceId, name: data.name, NOT: { id: botId } },
        });
        if (conflict) throw new BadRequestException('Bot with this name already exists');
      }
      updateData.name = data.name;
    }

    return this.prisma.botUser.update({
      where: { id: botId },
      data: updateData,
      include: {
        app: { select: { id: true, appName: true, appSlug: true, iconUrl: true } },
      },
    });
  }

  /**
   * Activa un bot user.
   */
  async activateBot(workspaceId: string, botId: string) {
    const bot = await this.prisma.botUser.findFirst({
      where: { id: botId, workspaceId },
    });
    if (!bot) throw new NotFoundException('Bot user not found');

    return this.prisma.botUser.update({
      where: { id: botId },
      data: { isActive: true },
      include: {
        app: { select: { id: true, appName: true, appSlug: true, iconUrl: true } },
      },
    });
  }

  /**
   * Desactiva un bot user.
   */
  async deactivateBot(workspaceId: string, botId: string) {
    const bot = await this.prisma.botUser.findFirst({
      where: { id: botId, workspaceId },
    });
    if (!bot) throw new NotFoundException('Bot user not found');

    return this.prisma.botUser.update({
      where: { id: botId },
      data: { isActive: false },
      include: {
        app: { select: { id: true, appName: true, appSlug: true, iconUrl: true } },
      },
    });
  }

  /**
   * Elimina un bot user permanentemente.
   */
  async deleteBot(workspaceId: string, botId: string) {
    const bot = await this.prisma.botUser.findFirst({
      where: { id: botId, workspaceId },
    });
    if (!bot) throw new NotFoundException('Bot user not found');

    await this.prisma.botUser.delete({ where: { id: botId } });
    return { deleted: true, id: botId };
  }
}