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

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

  async create(userId: string, dto: {
    title: string;
    description?: string;
    coverKey?: string;
    coverType?: string;
    coverIcon?: string;
    coverColor?: string;
    visibility?: string;
  }) {
    return this.prisma.knowledgeBase.create({
      data: {
        userId,
        title: dto.title,
        description: dto.description ?? '',
        coverKey: dto.coverKey ?? null,
        coverType: dto.coverType ?? 'custom',
        coverIcon: dto.coverIcon ?? null,
        coverColor: dto.coverColor ?? null,
        visibility: dto.visibility ?? 'private',
        status: 'active',
        itemCount: 0,
      },
    });
  }

  async findById(id: string) {
    return this.prisma.knowledgeBase.findUnique({ where: { id } });
  }

  async findAllByUserId(
    userId: string,
    opts?: {
      page?: number;
      limit?: number;
      visibility?: string;
      ownerType?: string;
    },
  ) {
    const page = opts?.page ?? 1;
    const limit = opts?.limit ?? 20;
    const where: any = { userId, deletedAt: null };
    if (opts?.visibility) where.visibility = opts.visibility;
    if (opts?.ownerType) where.ownerType = opts.ownerType;
    return this.prisma.knowledgeBase.findMany({
      where,
      orderBy: [{ isPinned: 'desc' }, { updatedAt: 'desc' }],
      skip: (page - 1) * limit,
      take: limit,
    });
  }

  async findAllPublic(opts?: { page?: number; limit?: number; search?: string }) {
    const page = opts?.page ?? 1;
    const limit = opts?.limit ?? 20;
    const where: any = { visibility: 'public', deletedAt: null };
    if (opts?.search) {
      where.OR = [
        { title: { contains: opts.search } },
        { description: { contains: opts.search } },
      ];
    }
    return this.prisma.knowledgeBase.findMany({
      where,
      orderBy: [{ isPinned: 'desc' }, { updatedAt: 'desc' }],
      skip: (page - 1) * limit,
      take: limit,
    });
  }

  async countByUserId(userId: string) {
    return this.prisma.knowledgeBase.count({
      where: { userId, deletedAt: null },
    });
  }

  async update(id: string, dto: {
    title?: string;
    description?: string;
    coverKey?: string;
    coverType?: string;
    coverIcon?: string;
    coverColor?: string;
    visibility?: string;
    isPinned?: boolean;
  }) {
    return this.prisma.knowledgeBase.update({
      where: { id },
      data: dto,
    });
  }

  async togglePin(id: string, isPinned: boolean) {
    return this.prisma.knowledgeBase.update({
      where: { id },
      data: { isPinned },
    });
  }

  async setVisibility(id: string, visibility: string) {
    return this.prisma.knowledgeBase.update({
      where: { id },
      data: { visibility },
    });
  }

  async softDelete(id: string) {
    await this.prisma.knowledgeBase.update({
      where: { id },
      data: { deletedAt: new Date() },
    });
    return true;
  }

  // ── Subscription ──

  async subscribe(userId: string, knowledgeBaseId: string) {
    return this.prisma.knowledgeBaseSubscription.create({
      data: { userId, knowledgeBaseId },
    });
  }

  async unsubscribe(userId: string, knowledgeBaseId: string) {
    await this.prisma.knowledgeBaseSubscription.deleteMany({
      where: { userId, knowledgeBaseId },
    });
    return true;
  }

  async findSubscribed(userId: string, opts?: { page?: number; limit?: number }) {
    const page = opts?.page ?? 1;
    const limit = opts?.limit ?? 20;
    return this.prisma.knowledgeBase.findMany({
      where: {
        subscriptions: { some: { userId } },
        deletedAt: null,
      },
      orderBy: { updatedAt: 'desc' },
      skip: (page - 1) * limit,
      take: limit,
    });
  }

  async isSubscribed(userId: string, knowledgeBaseId: string): Promise<boolean> {
    const sub = await this.prisma.knowledgeBaseSubscription.findUnique({
      where: { userId_knowledgeBaseId: { userId, knowledgeBaseId } },
    });
    return !!sub;
  }
}
