import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Tags } from './entities/tags.entity';

@Injectable()
export class TagsService {
  constructor(
    @InjectRepository(Tags)
    private readonly tagsRepository: Repository<Tags>,
  ) {}

  // Normalize tag name: trim and capitalize properly
  private normalizeTagName(name: string): string {
    return name
      .trim()
      .split(' ')
      .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
      .join(' ');
  }

  // Get all tags
  async findAll(): Promise<Tags[]> {
    return this.tagsRepository.find({
      where: { status: 1 },
      order: { name: 'ASC' },
    });
  }

  async findAllPaginated(page: number = 1, limit: number = 10) {
    const skip = (page - 1) * limit;
    const [data, total] = await this.tagsRepository.findAndCount({
      skip,
      take: limit,
      order: { name: 'ASC' },
    });

    return {
      success: true,
      data,
      meta: {
        totalItems: total,
        itemsPerPage: limit,
        currentPage: page,
        totalPages: Math.ceil(total / limit),
      },
    };
  }

  // Find tag by name (case-insensitive, trimmed)
  async findByName(name: string): Promise<Tags | null> {
    const trimmedName = name.trim();
    return this.tagsRepository
      .createQueryBuilder('tag')
      .where('LOWER(TRIM(tag.name)) = LOWER(:name)', { name: trimmedName })
      .getOne();
  }

  // Create a new tag
  async create(name: string): Promise<Tags> {
    const normalizedName = this.normalizeTagName(name);
    const tag = this.tagsRepository.create({ name: normalizedName });
    return this.tagsRepository.save(tag);
  }

  // Create tag if it doesn't exist, otherwise return existing
  async createIfNotExists(name: string): Promise<Tags> {
    const existingTag = await this.findByName(name);
    if (existingTag) {
      return existingTag;
    }
    return this.create(name);
  }

  // Get tags by IDs
  async findByIds(ids: number[]): Promise<Tags[]> {
    return this.tagsRepository.findByIds(ids);
  }
  async update(id: number, updateDto: any): Promise<any> {
    await this.tagsRepository.update(id, updateDto);
    return this.tagsRepository.findOne({ where: { id } });
  }

  async remove(id: number): Promise<void> {
    await this.tagsRepository.delete(id);
  }
}
