/**
 * Document Service
 * Handles document CRUD operations
 */

import { prisma } from '../lib/prisma';
import { Prisma } from '@prisma/client';

export interface CreateDocumentInput {
  user_id: string;
  content: string;
  title?: string | null;
  category_id?: string | null;
}

export interface UpdateDocumentInput {
  content?: string;
  title?: string | null;
  category_id?: string | null;
}

export interface FindDocumentOptions {
  category_id?: string;
  page?: number;
  limit?: number;
}

export class DocumentService {
  /**
   * Create a new document
   */
  static async create(input: CreateDocumentInput) {
    // Validate content is not empty
    if (!input.content || input.content.trim().length === 0) {
      throw new Error('Document content cannot be empty');
    }

    return prisma.document.create({
      data: {
        user_id: input.user_id,
        content: input.content,
        title: input.title ?? null,
        category_id: input.category_id ?? null,
      },
    });
  }

  /**
   * Find document by ID (ensuring user owns it)
   */
  static async findById(id: string, userId: string) {
    return prisma.document.findFirst({
      where: {
        id,
        user_id: userId,
      },
    });
  }

  /**
   * Update document
   */
  static async update(id: string, userId: string, input: UpdateDocumentInput) {
    // Verify document exists and user owns it
    const existing = await this.findById(id, userId);
    if (!existing) {
      throw new Error('Document not found or access denied');
    }

    const updateData: Prisma.DocumentUpdateInput = {};
    if (input.content !== undefined) {
      updateData.content = input.content;
    }
    if (input.title !== undefined) {
      updateData.title = input.title;
    }
    if (input.category_id !== undefined) {
      updateData.category = input.category_id ? { connect: { id: input.category_id } } : { disconnect: true };
    }

    return prisma.document.update({
      where: { id },
      data: updateData,
    });
  }

  /**
   * Delete document
   */
  static async delete(id: string, userId: string) {
    // Verify document exists and user owns it
    const existing = await this.findById(id, userId);
    if (!existing) {
      throw new Error('Document not found or access denied');
    }

    await prisma.document.delete({
      where: { id },
    });
  }

  /**
   * Find all documents for a user
   */
  static async findByUser(userId: string, options: FindDocumentOptions = {}) {
    const where: Prisma.DocumentWhereInput = {
      user_id: userId,
    };

    if (options.category_id) {
      where.category_id = options.category_id;
    }

    const page = options.page ?? 1;
    const limit = options.limit ?? 50;
    const skip = (page - 1) * limit;

    return prisma.document.findMany({
      where,
      orderBy: { created_at: 'desc' },
      skip,
      take: limit,
    });
  }

  /**
   * Search documents by content or title
   */
  static async search(userId: string, searchTerm: string) {
    const where: Prisma.DocumentWhereInput = {
      user_id: userId,
    };

    if (searchTerm && searchTerm.trim().length > 0) {
      where.OR = [
        { content: { contains: searchTerm } },
        { title: { contains: searchTerm } },
      ];
    }

    return prisma.document.findMany({
      where,
      orderBy: { created_at: 'desc' },
    });
  }
}
