import { AuditAction, AuditResourceType, recordAudit } from '@sim/audit'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import {
  createKnowledgeBaseContract,
  listKnowledgeBasesQuerySchema,
} from '@/lib/api/contracts/knowledge'
import { parseRequest } from '@/lib/api/server'
import { getSession } from '@/lib/auth'
import { PlatformEvents } from '@/lib/core/telemetry'
import { generateRequestId } from '@/lib/core/utils/request'
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
import { EMBEDDING_DIMENSIONS, getConfiguredEmbeddingModel } from '@/lib/knowledge/embeddings'
import {
  createKnowledgeBase,
  getKnowledgeBases,
  KnowledgeBaseConflictError,
  KnowledgeBasePermissionError,
  type KnowledgeBaseScope,
} from '@/lib/knowledge/service'
import { captureServerEvent } from '@/lib/posthog/server'

const logger = createLogger('KnowledgeBaseAPI')

export const GET = withRouteHandler(async (req: NextRequest) => {
  const requestId = generateRequestId()

  try {
    const session = await getSession()
    if (!session?.user?.id) {
      logger.warn(`[${requestId}] Unauthorized knowledge base access attempt`)
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
    }

    const { searchParams } = new URL(req.url)
    const query = listKnowledgeBasesQuerySchema.safeParse({
      workspaceId: searchParams.get('workspaceId') ?? undefined,
      scope: searchParams.get('scope') ?? undefined,
    })
    if (!query.success) {
      return NextResponse.json(
        { error: 'Invalid query parameters', details: query.error.issues },
        { status: 400 }
      )
    }
    const { workspaceId, scope } = query.data

    const knowledgeBasesWithCounts = await getKnowledgeBases(
      session.user.id,
      workspaceId,
      scope as KnowledgeBaseScope
    )

    return NextResponse.json({
      success: true,
      data: knowledgeBasesWithCounts,
    })
  } catch (error) {
    logger.error(`[${requestId}] Error fetching knowledge bases`, error)
    return NextResponse.json({ error: 'Failed to fetch knowledge bases' }, { status: 500 })
  }
})

export const POST = withRouteHandler(async (req: NextRequest) => {
  const requestId = generateRequestId()

  try {
    const session = await getSession()
    if (!session?.user?.id) {
      logger.warn(`[${requestId}] Unauthorized knowledge base creation attempt`)
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
    }

    const parsed = await parseRequest(
      createKnowledgeBaseContract,
      req,
      {},
      {
        validationErrorResponse: (error) => {
          logger.warn(`[${requestId}] Invalid knowledge base data`, { errors: error.issues })
          return NextResponse.json(
            { error: 'Invalid request data', details: error.issues },
            { status: 400 }
          )
        },
      }
    )
    if (!parsed.success) return parsed.response

    const validatedData = parsed.data.body

    try {
      const embeddingModel = getConfiguredEmbeddingModel()

      const createData = {
        ...validatedData,
        userId: session.user.id,
        embeddingModel,
        embeddingDimension: EMBEDDING_DIMENSIONS,
      }

      const newKnowledgeBase = await createKnowledgeBase(createData, requestId)

      try {
        PlatformEvents.knowledgeBaseCreated({
          knowledgeBaseId: newKnowledgeBase.id,
          name: validatedData.name,
          workspaceId: validatedData.workspaceId,
        })
      } catch {
        // Telemetry should not fail the operation
      }

      captureServerEvent(
        session.user.id,
        'knowledge_base_created',
        {
          knowledge_base_id: newKnowledgeBase.id,
          workspace_id: validatedData.workspaceId,
          name: validatedData.name,
        },
        {
          groups: { workspace: validatedData.workspaceId },
          setOnce: { first_kb_created_at: new Date().toISOString() },
        }
      )

      logger.info(
        `[${requestId}] Knowledge base created: ${newKnowledgeBase.id} for user ${session.user.id}`
      )

      recordAudit({
        workspaceId: validatedData.workspaceId,
        actorId: session.user.id,
        actorName: session.user.name,
        actorEmail: session.user.email,
        action: AuditAction.KNOWLEDGE_BASE_CREATED,
        resourceType: AuditResourceType.KNOWLEDGE_BASE,
        resourceId: newKnowledgeBase.id,
        resourceName: validatedData.name,
        description: `Created knowledge base "${validatedData.name}"`,
        metadata: {
          name: validatedData.name,
          description: validatedData.description,
          embeddingModel,
          embeddingDimension: EMBEDDING_DIMENSIONS,
          chunkingStrategy: validatedData.chunkingConfig.strategy,
          chunkMaxSize: validatedData.chunkingConfig.maxSize,
          chunkMinSize: validatedData.chunkingConfig.minSize,
          chunkOverlap: validatedData.chunkingConfig.overlap,
        },
        request: req,
      })

      return NextResponse.json({
        success: true,
        data: newKnowledgeBase,
      })
    } catch (createError) {
      if (createError instanceof KnowledgeBaseConflictError) {
        return NextResponse.json({ error: createError.message }, { status: 409 })
      }
      if (createError instanceof KnowledgeBasePermissionError) {
        logger.warn(`[${requestId}] Forbidden knowledge base creation: ${createError.message}`)
        return NextResponse.json({ error: createError.message }, { status: 403 })
      }
      throw createError
    }
  } catch (error) {
    logger.error(`[${requestId}] Error creating knowledge base`, error)
    return NextResponse.json({ error: 'Failed to create knowledge base' }, { status: 500 })
  }
})
