import { prisma } from '../plugins/prisma';
import { CreateGameInput, UpdateGameInput } from '../validators/gameValidator';
import { Prisma } from '@prisma/client';

export class GamesController {
  /**
   * Listar todos los juegos con sus plataformas y compras
   */
  static async listGames() {
    return await prisma.game.findMany({
      include: {
        gamePlatforms: {
          include: {
            platform: true,
          },
        },
        purchases: true,
      },
      orderBy: {
        title: 'asc',
      },
    });
  }

  /**
   * Crear un juego nuevo
   */
  static async createGame(input: CreateGameInput) {
    const { title, platformId, description, priceCents, currency, store, date, condition } = input;

    // Generar slug basado en el título
    const slug = title
      .toLowerCase()
      .replace(/\s+/g, '-')
      .replace(/[^\w-]/g, '');

    const gameData: Prisma.GameCreateInput = {
      title,
      slug: `${slug}-${Date.now()}`, // Hacer slug único agregando timestamp
      description: description || null,
    };

    // Si se proporciona una plataforma, crearla en gamePlatforms
    if (platformId) {
      gameData.gamePlatforms = {
        create: {
          platformId,
        },
      };
    }

    // Si se proporciona precio, crear en purchases
    if (priceCents) {
      gameData.purchases = {
        create: {
          priceCents,
          currency: currency || 'USD',
          store: store || null,
          date: date ? new Date(date) : new Date(),
        },
      };
    }

    return await prisma.game.create({
      data: gameData,
      include: {
        gamePlatforms: {
          include: {
            platform: true,
          },
        },
        purchases: true,
      },
    });
  }

  /**
   * Actualizar un juego existente
   */
  static async updateGame(id: string, input: UpdateGameInput) {
    const { title, platformId, description, priceCents, currency, store, date } = input;

    const updateData: Prisma.GameUpdateInput = {};

    if (title !== undefined) {
      updateData.title = title;
      // Regenerar slug si cambia el título
      const slug = title
        .toLowerCase()
        .replace(/\s+/g, '-')
        .replace(/[^\w-]/g, '');
      updateData.slug = `${slug}-${Date.now()}`;
    }

    if (description !== undefined) {
      updateData.description = description;
    }

    const game = await prisma.game.update({
      where: { id },
      data: updateData,
      include: {
        gamePlatforms: {
          include: {
            platform: true,
          },
        },
        purchases: true,
      },
    });

    // Si se actualiza plataforma, sincronizar
    if (platformId !== undefined) {
      // Eliminar relaciones antiguas
      await prisma.gamePlatform.deleteMany({
        where: { gameId: id },
      });

      // Crear nueva relación si se proporcionó platformId
      if (platformId) {
        await prisma.gamePlatform.create({
          data: {
            gameId: id,
            platformId,
          },
        });
      }
    }

    // Si se actualiza precio, agregar nueva compra (crear histórico)
    if (priceCents !== undefined) {
      await prisma.purchase.create({
        data: {
          gameId: id,
          priceCents,
          currency: currency || 'USD',
          store: store || null,
          date: date ? new Date(date) : new Date(),
        },
      });
    }

    // Retornar el juego actualizado
    return await prisma.game.findUniqueOrThrow({
      where: { id },
      include: {
        gamePlatforms: {
          include: {
            platform: true,
          },
        },
        purchases: true,
      },
    });
  }

  /**
   * Eliminar un juego (y sus relaciones en cascada)
   */
  static async deleteGame(id: string) {
    // Validar que el juego existe
    const game = await prisma.game.findUnique({ where: { id } });
    if (!game) {
      throw new Error('Juego no encontrado');
    }

    // Eliminar todas las relaciones (Prisma maneja cascada según schema)
    await prisma.game.delete({
      where: { id },
    });

    return { message: 'Juego eliminado correctamente' };
  }
}

/**
 * Metadatos:
 * Autor: GitHub Copilot
 * Última actualización: 2026-02-11
 */
