import { Injectable, NotFoundException, ForbiddenException, BadRequestException, Logger } from '@nestjs/common';
import { KnowledgeItemsRepository } from './knowledge-items.repository';
import { StorageService } from '../../infrastructure/storage/storage.service';
import { CosStorageProvider } from '../../infrastructure/storage/cos-storage.provider';

@Injectable()
export class KnowledgeItemsService {
  private readonly logger = new Logger(KnowledgeItemsService.name);

  constructor(
    private readonly repository: KnowledgeItemsRepository,
    private readonly storage: StorageService,
    private readonly cos: CosStorageProvider,
  ) {}

  async create(userId: string, knowledgeBaseId: string, dto: any) {
    return this.repository.create(userId, knowledgeBaseId, dto);
  }

  async findById(id: string) {
    const item = await this.repository.findById(id);
    if (!item) throw new NotFoundException('知识点不存在');
    return this.enrichItem(item);
  }

  async findByKnowledgeBaseId(knowledgeBaseId: string, opts?: { sortBy?: string; order?: string }) {
    // List queries: return raw items (no URL refresh to avoid N COS API calls)
    return this.repository.findByKnowledgeBaseId(knowledgeBaseId, opts);
  }

  /**
   * If the item's content is a COS pre-signed URL, refresh it with a new signature.
   * COS objectKey format: https://<bucket>.cos.<region>.myqcloud.com/<objectKey>?...
   */
  private async enrichItem(item: any) {
    if (!item?.content || !item.content.includes('.cos.') || !item.content.includes('myqcloud.com')) {
      return item;
    }
    try {
      const url = new URL(item.content);
      const objectKey = url.pathname.slice(1); // remove leading '/'
      if (!objectKey) return item;

      const [freshUrl, headInfo] = await Promise.all([
        this.storage.getDownloadUrl(objectKey, 7 * 86400),
        this.cos.headObject(objectKey).catch(() => null),
      ]);

      const enriched = { ...item, content: freshUrl };
      if (headInfo) {
        enriched.fileSize = Number(headInfo.size);
      }
      return enriched;
    } catch (err) {
      this.logger.warn(`enrichItem failed for item, returning original: ${(err as Error)?.message}`);
    }
    return item;
  }

  async update(id: string, dto: any) {
    const item = await this.repository.findById(id);
    if (!item) throw new NotFoundException('知识点不存在');

    // Validate parentId if provided
    if (dto.parentId !== undefined) {
      if (dto.parentId !== null) {
        const parent = await this.repository.findById(dto.parentId);
        if (!parent || parent.knowledgeBaseId !== item.knowledgeBaseId) {
          throw new BadRequestException('目标父节点不存在或不属于同一知识库');
        }
      }
    }

    return this.repository.update(id, dto);
  }

  async softDelete(id: string, userId: string) {
    const item = await this.repository.findById(id);
    if (!item) throw new NotFoundException('知识点不存在');
    if (item.userId !== userId) throw new ForbiddenException('无权操作');
    return this.repository.softDelete(id);
  }

  async batchSoftDelete(ids: string[], userId: string) {
    if (!ids.length) return 0;
    let count = 0;
    for (const id of ids) {
      try {
        await this.softDelete(id, userId);
        count++;
      } catch {
        // 跳过不存在的或无权操作的
      }
    }
    return count;
  }
}
