import type { Database } from 'sql.js';
import { TagRepository } from '../repositories/TagRepository.js';
import type { Tag, CreateTagInput, UpdateTagInput } from '../types/tag.js';

/**
 * TagService contains business logic for tag management
 */
export class TagService {
  private repository: TagRepository;

  constructor(db: Database) {
    this.repository = new TagRepository(db);
  }

  list(): Tag[] {
    return this.repository.findAll();
  }

  get(id: number): Tag | null {
    return this.repository.findById(id);
  }

  getByRecipeId(recipeId: number): Tag[] {
    return this.repository.findByRecipeId(recipeId);
  }

  create(input: CreateTagInput): Tag {
    if (!input.name.trim()) {
      throw new Error('Tag name cannot be empty');
    }
    const existing = this.repository.findByName(input.name);
    if (existing) {
      throw new Error(`Tag "${input.name}" already exists`);
    }
    return this.repository.create(input);
  }

  update(id: number, input: UpdateTagInput): Tag | null {
    if (input.name !== undefined && !input.name.trim()) {
      throw new Error('Tag name cannot be empty');
    }
    if (input.name !== undefined) {
      const existing = this.repository.findByName(input.name);
      if (existing && existing.id !== id) {
        throw new Error(`Tag "${input.name}" already exists`);
      }
    }
    return this.repository.update(id, input);
  }

  delete(id: number): boolean {
    return this.repository.delete(id);
  }

  assignToRecipe(recipeId: number, tagId: number): boolean {
    const tag = this.repository.findById(tagId);
    if (!tag) {
      throw new Error('Tag not found');
    }
    return this.repository.assignToRecipe(recipeId, tagId);
  }

  removeFromRecipe(recipeId: number, tagId: number): boolean {
    return this.repository.removeFromRecipe(recipeId, tagId);
  }
}
