import { db } from '@sim/db'
import { workflow, workflowExecutionLogs } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { generateId } from '@sim/utils/id'
import { eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { v1GetLogContract } from '@/lib/api/contracts/v1/logs'
import { parseRequest } from '@/lib/api/server'
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
import { materializeExecutionData } from '@/lib/logs/execution/trace-store'
import { createApiResponse, getUserLimits } from '@/app/api/v1/logs/meta'
import {
  checkRateLimit,
  createRateLimitResponse,
  validateWorkspaceAccess,
} from '@/app/api/v1/middleware'

const logger = createLogger('V1LogDetailsAPI')

export const revalidate = 0

export const GET = withRouteHandler(
  async (request: NextRequest, context: { params: Promise<{ id: string }> }) => {
    const requestId = generateId().slice(0, 8)

    try {
      const rateLimit = await checkRateLimit(request, 'logs-detail')
      if (!rateLimit.allowed) {
        return createRateLimitResponse(rateLimit)
      }

      const userId = rateLimit.userId!
      const parsed = await parseRequest(v1GetLogContract, request, context, {
        validationErrorResponse: () =>
          NextResponse.json({ error: 'Invalid log ID' }, { status: 400 }),
      })
      if (!parsed.success) return parsed.response

      const { id } = parsed.data.params

      const rows = await db
        .select({
          id: workflowExecutionLogs.id,
          workflowId: workflowExecutionLogs.workflowId,
          workspaceId: workflowExecutionLogs.workspaceId,
          executionId: workflowExecutionLogs.executionId,
          stateSnapshotId: workflowExecutionLogs.stateSnapshotId,
          level: workflowExecutionLogs.level,
          trigger: workflowExecutionLogs.trigger,
          startedAt: workflowExecutionLogs.startedAt,
          endedAt: workflowExecutionLogs.endedAt,
          totalDurationMs: workflowExecutionLogs.totalDurationMs,
          executionData: workflowExecutionLogs.executionData,
          costTotal: workflowExecutionLogs.costTotal,
          files: workflowExecutionLogs.files,
          createdAt: workflowExecutionLogs.createdAt,
          workflowName: workflow.name,
          workflowDescription: workflow.description,
          workflowFolderId: workflow.folderId,
          workflowUserId: workflow.userId,
          workflowWorkspaceId: workflow.workspaceId,
          workflowCreatedAt: workflow.createdAt,
          workflowUpdatedAt: workflow.updatedAt,
        })
        .from(workflowExecutionLogs)
        .leftJoin(workflow, eq(workflowExecutionLogs.workflowId, workflow.id))
        .where(eq(workflowExecutionLogs.id, id))
        .limit(1)

      const log = rows[0]
      if (!log) {
        return NextResponse.json({ error: 'Log not found' }, { status: 404 })
      }

      const accessError = await validateWorkspaceAccess(rateLimit, userId, log.workspaceId)
      if (accessError) {
        return NextResponse.json({ error: 'Log not found' }, { status: 404 })
      }

      const workflowSummary = {
        id: log.workflowId,
        name: log.workflowName || 'Deleted Workflow',
        description: log.workflowDescription,
        folderId: log.workflowFolderId,
        userId: log.workflowUserId,
        workspaceId: log.workflowWorkspaceId,
        createdAt: log.workflowCreatedAt,
        updatedAt: log.workflowUpdatedAt,
        deleted: !log.workflowName,
      }

      const response = {
        id: log.id,
        workflowId: log.workflowId,
        executionId: log.executionId,
        level: log.level,
        trigger: log.trigger,
        startedAt: log.startedAt.toISOString(),
        endedAt: log.endedAt?.toISOString() || null,
        totalDurationMs: log.totalDurationMs,
        files: log.files || undefined,
        workflow: workflowSummary,
        executionData: (await materializeExecutionData(
          log.executionData as Record<string, unknown> | null,
          {
            workspaceId: log.workspaceId,
            workflowId: log.workflowId,
            executionId: log.executionId,
          }
        )) as any,
        cost: log.costTotal != null ? { total: Number(log.costTotal) } : null,
        createdAt: log.createdAt.toISOString(),
      }

      // Get user's workflow execution limits and usage
      const limits = await getUserLimits(userId)

      // Create response with limits information
      const apiResponse = createApiResponse({ data: response }, limits, rateLimit)

      return NextResponse.json(apiResponse.body, { headers: apiResponse.headers })
    } catch (error: any) {
      logger.error(`[${requestId}] Log details fetch error`, { error: error.message })
      return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
    }
  }
)
