import { Injectable } from '@nestjs/common';
import { PrismaService } from '../../prisma/prisma.service';

@Injectable()
export class SearchService {
  constructor(private prisma: PrismaService) {}

  async search(params: { q: string; type?: string; page?: number; pageSize?: number }) {
    const q = params.q?.trim();
    if (!q) return { results: [], total: 0 };

    const page = Number(params.page ?? 1);
    const pageSize = Math.min(Number(params.pageSize ?? 10), 50);
    const skip = (page - 1) * pageSize;
    const type = params.type || 'all';

    const results: any[] = [];
    let total = 0;

    const where: any = {
      AND: [
        { deletedAt: null },
        { status: 'PUBLISHED' },
        {
          OR: [
            { title: { contains: q } },
            { description: { contains: q } },
          ],
        },
      ],
    };

    if (type === 'all' || type === 'courses') {
      const [items, count] = await Promise.all([
        this.prisma.course.findMany({
          where: {
            AND: [
              { deletedAt: null },
              { status: 'PUBLISHED' },
              {
                OR: [
                  { title: { contains: q } },
                  { description: { contains: q } },
                ],
              },
            ],
          },
          select: { id: true, title: true, description: true, cover: true, isFree: true },
          skip: type === 'courses' ? skip : 0,
          take: type === 'courses' ? pageSize : 5,
        }),
        this.prisma.course.count({ where }),
      ]);
      results.push(...items.map(i => ({ ...i, _type: 'course' })));
      total += count;
    }

    if (type === 'all' || type === 'prompts') {
      const promptWhere: any = {
        AND: [
          { deletedAt: null },
          { status: 'PUBLISHED' },
          {
            OR: [
              { title: { contains: q } },
              { description: { contains: q } },
              { content: { contains: q } },
            ],
          },
        ],
      };
      const [items, count] = await Promise.all([
        this.prisma.prompt.findMany({
          where: promptWhere,
          select: { id: true, title: true, description: true, model: true },
          skip: type === 'prompts' ? skip : 0,
          take: type === 'prompts' ? pageSize : 5,
        }),
        this.prisma.prompt.count({ where: promptWhere }),
      ]);
      results.push(...items.map(i => ({ ...i, _type: 'prompt' })));
      total += count;
    }

    if (type === 'all' || type === 'tools') {
      const toolWhere: any = {
        AND: [
          { deletedAt: null },
          { status: 'PUBLISHED' },
          {
            OR: [
              { name: { contains: q } },
              { description: { contains: q } },
            ],
          },
        ],
      };
      const [items, count] = await Promise.all([
        this.prisma.tool.findMany({
          where: toolWhere,
          select: { id: true, name: true, description: true, url: true, icon: true },
          skip: type === 'tools' ? skip : 0,
          take: type === 'tools' ? pageSize : 5,
        }),
        this.prisma.tool.count({ where: toolWhere }),
      ]);
      results.push(...items.map(i => ({ ...i, _type: 'tool' })));
      total += count;
    }

    if (type === 'all' || type === 'contents') {
      const contentWhere: any = {
        AND: [
          { deletedAt: null },
          { status: 'PUBLISHED' },
          {
            OR: [
              { title: { contains: q } },
              { summary: { contains: q } },
            ],
          },
        ],
      };
      const [items, count] = await Promise.all([
        this.prisma.content.findMany({
          where: contentWhere,
          select: { id: true, title: true, summary: true, cover: true, publishedAt: true },
          skip: type === 'contents' ? skip : 0,
          take: type === 'contents' ? pageSize : 5,
        }),
        this.prisma.content.count({ where: contentWhere }),
      ]);
      results.push(...items.map(i => ({ ...i, _type: 'content' })));
      total += count;
    }

    return { results, total, page, pageSize };
  }
}
