import { categoryRepository } from '@/lib/repositories/categoryRepository';
import { Category, CreateCategoryInput, UpdateCategoryInput } from '@/types/category';

/**
 * Service para lógica de negocio de Categorías
 */
export class CategoryService {
  /**
   * Obtener todas las categorías
   */
  async getCategories(): Promise<Category[]> {
    return categoryRepository.findMany();
  }

  /**
   * Obtener una categoría por ID
   */
  async getCategoryById(id: string): Promise<Category | null> {
    return categoryRepository.findById(id);
  }

  /**
   * Crear una nueva categoría
   */
  async createCategory(
    data: CreateCategoryInput,
    userRole: 'USER' | 'ADMIN'
  ): Promise<{ id: string }> {
    // Verificar permisos
    if (userRole !== 'ADMIN') {
      throw new Error('No tienes permisos para crear categorías');
    }

    // Verificar que el nombre sea único
    const existing = await categoryRepository.findByName(data.name);
    if (existing) {
      throw new Error('Ya existe una categoría con ese nombre');
    }

    const category = await categoryRepository.create({
      name: data.name,
      description: data.description,
      color: data.color || '#3B82F6',
      icon: data.icon || '📄',
      expenseType: data.expenseType,
      paymentMethod: data.paymentMethod,
    });

    return { id: category.id };
  }

  /**
   * Actualizar una categoría
   */
  async updateCategory(
    id: string,
    data: UpdateCategoryInput,
    userRole: 'USER' | 'ADMIN'
  ): Promise<void> {
    // Verificar permisos
    if (userRole !== 'ADMIN') {
      throw new Error('No tienes permisos para actualizar categorías');
    }

    // Verificar que la categoría existe
    const existing = await categoryRepository.findById(id);
    if (!existing) {
      throw new Error('Categoría no encontrada');
    }

    // Si se está cambiando el nombre, verificar unicidad
    if (data.name) {
      const nameExists = await categoryRepository.findByName(data.name);
      if (nameExists && nameExists.id !== id) {
        throw new Error('Ya existe otra categoría con ese nombre');
      }
    }

    await categoryRepository.update(id, data);
  }

  /**
   * Eliminar una categoría
   */
  async deleteCategory(
    id: string,
    userRole: 'USER' | 'ADMIN'
  ): Promise<void> {
    // Verificar permisos
    if (userRole !== 'ADMIN') {
      throw new Error('No tienes permisos para eliminar categorías');
    }

    // Verificar que la categoría existe
    const category = await categoryRepository.findById(id);
    if (!category) {
      throw new Error('Categoría no encontrada');
    }

    // Verificar si tiene documentos asociados
    const documentCount = await categoryRepository.countDocuments(id);
    if (documentCount > 0) {
      throw new Error(`No se puede eliminar. Esta categoría tiene ${documentCount} documento(s) asociado(s)`);
    }

    await categoryRepository.delete(id);
  }
}

export const categoryService = new CategoryService();
