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

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

  async create(userId: string, knowledgeBaseId: string, dto: {
    fileId?: string;
    type?: string;
    title?: string;
    originalFilename?: string;
    mimeType?: string;
    sizeBytes?: number;
    originalObjectKey?: string;
  }) {
    return this.prisma.knowledgeSource.create({
      data: {
        userId,
        knowledgeBaseId,
        fileId: dto.fileId,
        type: dto.type ?? 'file',
        title: dto.title ?? dto.originalFilename,
        originalFilename: dto.originalFilename,
        mimeType: dto.mimeType,
        sizeBytes: dto.sizeBytes ?? 0,
        originalObjectKey: dto.originalObjectKey,
        parseStatus: 'pending',
        indexStatus: 'pending',
        learningStatus: 'pending',
      },
    });
  }

  async findByKnowledgeBase(knowledgeBaseId: string, pagination: {
    page?: number; limit?: number; sortBy?: string; order?: string;
  }) {
    const page = pagination.page ?? 1;
    const limit = pagination.limit ?? 20;
    // map iOS field names to DB columns
    const sortFieldMap: Record<string, string> = { fileSize: 'sizeBytes' };
    const effectiveField = sortFieldMap[pagination.sortBy ?? ''] ?? pagination.sortBy;
    const validFields = ['title', 'sizeBytes', 'createdAt', 'updatedAt'];
    const sortField = validFields.includes(effectiveField ?? '') ? effectiveField! : 'title';
    const sortOrder = pagination.order === 'desc' ? 'desc' : 'asc';

    return this.prisma.knowledgeSource.findMany({
      where: { knowledgeBaseId, deletedAt: null },
      skip: (page - 1) * limit,
      take: limit,
      orderBy: { [sortField]: sortOrder },
    });
  }

  async findById(id: string) {
    return this.prisma.knowledgeSource.findFirst({ where: { id, deletedAt: null } });
  }

  async findByIdIncludingDeleted(id: string) {
    return this.prisma.knowledgeSource.findUnique({ where: { id } });
  }

  async findFileSourcesByKnowledgeBase(knowledgeBaseId: string) {
    return this.prisma.knowledgeSource.findMany({
      where: {
        knowledgeBaseId,
        deletedAt: null,
        fileId: { not: null },
      },
      select: { id: true, fileId: true },
    });
  }

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

  async softDeleteMany(ids: string[]) {
    if (ids.length === 0) {
      return { count: 0 };
    }
    return this.prisma.knowledgeSource.updateMany({
      where: { id: { in: ids }, deletedAt: null },
      data: { deletedAt: new Date() },
    });
  }

  async updateParseStatus(id: string, parseStatus: string, data?: { textLength?: number; parsedObjectKey?: string; metadataObjectKey?: string; errorCode?: string; errorMessage?: string }) {
    return this.prisma.knowledgeSource.update({
      where: { id },
      data: { parseStatus, ...data },
    });
  }

  async updateIndexStatus(id: string, indexStatus: string, errorCode?: string, errorMessage?: string) {
    return this.prisma.knowledgeSource.update({
      where: { id },
      data: { indexStatus, errorCode, errorMessage },
    });
  }

  async countByKnowledgeBase(knowledgeBaseId: string) {
    return this.prisma.knowledgeSource.count({
      where: { knowledgeBaseId, deletedAt: null },
    });
  }
}
