import { BadRequestException, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { In, Like, Repository } from 'typeorm';
import { Menu } from '@/modules/menu/menu.entity';
import { SharedService } from '@/shared/shared.service';
import { Article } from '@/modules/article/article.entity';
import { Category } from '@/modules/category/category.entity';
import { getTopMenuFragment } from '@/common/utils';

@Injectable()
export class WebService {
  constructor(
    @InjectRepository(Menu)
    private menuRepo: Repository<Menu>,
    @InjectRepository(Article)
    private articleRepo: Repository<Article>,
    @InjectRepository(Category)
    private categoryRepo: Repository<Category>,
    private readonly sharedService: SharedService,
  ) {}

  async findMenuTree(locale?: string): Promise<Menu[]> {
    const menus = await this.menuRepo.find({
      where: {
        enable: true,
      },
      order: {
        order: 'ASC',
        children: {
          order: 'ASC',
        },
      },
      relations: {
        children: true,
        category: true,
      },
      select: {
        category: {
          id: true,
          title: true,
        },
      },
    });
    return this.sharedService.handleTree(menus);
  }

  async findArticleDetail(id: number, locale?: string) {
    const lang = this.sharedService.handleValidLang(locale);
    const article = await this.articleRepo.findOne({
      where: { id },
      relations: { user: true, translations: true, category: true },
      select: {
        user: {
          id: true,
          username: true,
        },
        category: {
          id: true,
          title: true,
        },
      },
    });
    return article.translate(lang);
  }

  async setArticleCount(id: number) {
    const article = await this.articleRepo.findOne({
      where: { id },
    });
    if (!article) throw new BadRequestException('不存在或者已删除');
    article.readCount = article.readCount + 1;
    // console.log('article', article);
    await this.articleRepo.save(article);
    return true;
  }

  async getTopCategory1(id: number) {
    let currentCategory = await this.categoryRepo.findOne({
      where: { id },
      relations: { parent: true },
    });

    if (!currentCategory) {
      return null; // 如果分类不存在，返回 null
    }
    // 递归查找顶层父分类
    while (currentCategory.parent) {
      currentCategory = await this.categoryRepo.findOne({
        where: { id: currentCategory.parent.id },
        relations: { parent: true },
      });
    }
    console.log('currentCategory', currentCategory);
    return currentCategory.id
      ? this.categoryRepo.findOne({
          where: { id: currentCategory.id },
          relations: { children: true },
        })
      : null;
  }

  async getCategoryTreeAndPath(id: number) {
    const categories = await this.categoryRepo.find({
      relations: { children: true },
    });
    const data = this.sharedService.handleTree(categories);
    return getTopMenuFragment(data, id);
  }

  async searchArticles(key: string, locale?: string) {
    const lang = this.sharedService.handleValidLang(locale);
    const articles = await this.articleRepo.find({
      where: [
        {
          translations: {
            locale: lang,
            title: Like(`%${key || ''}%`),
          },
        },
        {
          translations: {
            locale: lang,
            content: Like(`%${key || ''}%`),
          },
        },
      ],
      relations: { translations: true },
    });
    return articles.map((article) => article.translate(lang));
  }

  async findCateAllChildIds(parentId: number) {
    const childIds: number[] = [];
    // 递归查找所有子菜单的 id
    const findChildren = async (id: number) => {
      const children = await this.categoryRepo.find({ where: { parentId: id } });
      for (const child of children) {
        childIds.push(child.id);
        await findChildren(child.id); // 递归查找子菜单的子菜单
      }
    };
    await findChildren(parentId);
    return childIds;
  }

  async getArticlesByCate(id: number, locale?: string) {
    const lang = this.sharedService.handleValidLang(locale);

    // 保留
    // const category = await this.categoryRepo.findOne({
    //   where: { id: id },
    //   relations: { children: true },
    // });
    // const ids = await this.findCateAllChildIds(category.id);
    // ids.push(category.id);

    const articles = await this.articleRepo.find({
      where: {
        categoryId: id,
      },
      relations: { translations: true },
    });
    return articles.map((article) => article.translate(lang));
  }
}
