import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { NoteCategory } from './note-category.entity';
import { I18nService } from '../i18n/i18n.service';

@Injectable()
export class NoteCategoryService {
    constructor(
        @InjectRepository(NoteCategory)
        private readonly categoryRepository: Repository<NoteCategory>,
        private readonly i18nService: I18nService,
    ) { }

    async findAll(userId: string, tenantId: string): Promise<NoteCategory[]> {
        return this.categoryRepository.find({
            where: { userId, tenantId },
            order: { level: 'ASC', name: 'ASC' },
        });
    }

    async create(userId: string, tenantId: string, name: string, parentId?: string): Promise<NoteCategory> {
        let level = 1;
        if (parentId) {
            const parent = await this.categoryRepository.findOne({
                where: { id: parentId, userId, tenantId }
            });
            if (!parent) {
                throw new NotFoundException(this.i18nService.getMessage('parentCategoryNotFound'));
            }
            if (parent.level >= 3) {
                throw new Error(this.i18nService.getMessage('maxCategoryDepthExceeded'));
            }
            level = parent.level + 1;
        }

        const category = this.categoryRepository.create({
            name,
            userId,
            tenantId,
            parentId,
            level,
        });
        return this.categoryRepository.save(category);
    }

    async update(userId: string, tenantId: string, id: string, name?: string, parentId?: string): Promise<NoteCategory> {
        const category = await this.categoryRepository.findOne({
            where: { id, userId, tenantId },
        });
        if (!category) {
            throw new NotFoundException(this.i18nService.getMessage('categoryNotFound'));
        }

        if (name !== undefined) {
            category.name = name;
        }

        if (parentId !== undefined && parentId !== category.parentId) {
            if (parentId === null) {
                category.parentId = null as any;
                category.level = 1;
            } else {
                const parent = await this.categoryRepository.findOne({
                    where: { id: parentId, userId, tenantId }
                });
                if (!parent) throw new NotFoundException(this.i18nService.getMessage('parentCategoryNotFound'));
                if (parent.level >= 3) throw new Error(this.i18nService.getMessage('maxCategoryDepthExceeded'));

                category.parentId = parentId;
                category.level = parent.level + 1;
            }
        }

        return this.categoryRepository.save(category);
    }

    async remove(userId: string, tenantId: string, id: string): Promise<void> {
        const result = await this.categoryRepository.delete({ id, userId, tenantId });
        if (result.affected === 0) {
            throw new NotFoundException(this.i18nService.getMessage('categoryNotFound'));
        }
    }
}
