import { prisma } from '@/lib/prisma';
import { Prisma } from '@/generated/prisma/client';

/**
 * Filtros para búsqueda de documentos
 */
export interface DocumentFilters {
  query?: string;
  ownerId?: string;
  categoryId?: string;
  userId?: string;
  role?: 'USER' | 'ADMIN';
}

/**
 * Repository para acceso a datos de Documentos
 * 
 * Encapsula todo el acceso a Prisma para documentos.
 */
export class DocumentRepository {
  /**
   * Buscar múltiples documentos con filtros
   */
  async findMany(filters: DocumentFilters) {
    const whereClause: Prisma.DocumentWhereInput = {};

    // Si NO es admin, solo mostrar sus propios documentos
    if (filters.role !== 'ADMIN' && filters.userId) {
      whereClause.ownerId = filters.userId;
    }

    // Filtro por búsqueda de texto
    if (filters.query) {
      whereClause.fileName = { contains: filters.query };
    }

    // Filtro por categoría
    if (filters.categoryId) {
      whereClause.categoryId = filters.categoryId;
    }

    return prisma.document.findMany({
      where: whereClause,
      include: {
        owner: {
          select: {
            id: true,
            name: true,
            username: true,
          },
        },
        category: {
          select: {
            id: true,
            name: true,
            icon: true,
            color: true,
            expenseType: true,
            paymentMethod: true,
          },
        },
      },
      orderBy: { createdAt: 'desc' },
    });
  }

  /**
   * Buscar un documento por ID
   */
  async findById(id: string) {
    return prisma.document.findUnique({
      where: { id },
      include: {
        owner: {
          select: {
            id: true,
            name: true,
            username: true,
          },
        },
        category: true,
      },
    });
  }

  /**
   * Buscar todos los documentos (solo admin)
   */
  async findAll() {
    return prisma.document.findMany({
      include: {
        owner: {
          select: {
            id: true,
            name: true,
            username: true,
          },
        },
        category: true,
      },
      orderBy: { createdAt: 'desc' },
    });
  }

  /**
   * Crear un nuevo documento
   */
  async create(data: Prisma.DocumentCreateInput) {
    return prisma.document.create({
      data,
      include: {
        owner: {
          select: {
            id: true,
            name: true,
            username: true,
          },
        },
        category: true,
      },
    });
  }

  /**
   * Actualizar un documento
   */
  async update(id: string, data: Prisma.DocumentUpdateInput) {
    return prisma.document.update({
      where: { id },
      data,
      include: {
        owner: {
          select: {
            id: true,
            name: true,
            username: true,
          },
        },
        category: true,
      },
    });
  }

  /**
   * Eliminar un documento
   */
  async delete(id: string) {
    return prisma.document.delete({
      where: { id },
    });
  }

  /**
   * Eliminar todos los documentos
   */
  async deleteMany() {
    return prisma.document.deleteMany();
  }

  /**
   * Contar documentos por usuario
   */
  async countByOwner(ownerId: string) {
    return prisma.document.count({
      where: { ownerId },
    });
  }

  /**
   * Verificar si un documento existe
   */
  async exists(id: string) {
    const doc = await prisma.document.findUnique({
      where: { id },
      select: { id: true },
    });
    return doc !== null;
  }
}

export const documentRepository = new DocumentRepository();
