import { db } from '@sim/db'
import { workflowBlocks } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { generateId } from '@sim/utils/id'
import { getActiveWorkflowRecord } from '@sim/workflow-authz'
import { eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { v1GetWorkflowContract } from '@/lib/api/contracts/v1/workflows'
import { parseRequest } from '@/lib/api/server'
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
import { extractInputFieldsFromBlocks } from '@/lib/workflows/input-format'
import { createApiResponse, getUserLimits } from '@/app/api/v1/logs/meta'
import {
  checkRateLimit,
  createRateLimitResponse,
  validateWorkspaceAccess,
} from '@/app/api/v1/middleware'

const logger = createLogger('V1WorkflowDetailsAPI')

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, 'workflow-detail')
      if (!rateLimit.allowed) {
        return createRateLimitResponse(rateLimit)
      }

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

      const { id } = parsed.data.params

      logger.info(`[${requestId}] Fetching workflow details for ${id}`, { userId })

      const workflowData = await getActiveWorkflowRecord(id)
      if (!workflowData) {
        return NextResponse.json({ error: 'Workflow not found' }, { status: 404 })
      }

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

      const blockRows = await db
        .select({
          id: workflowBlocks.id,
          type: workflowBlocks.type,
          subBlocks: workflowBlocks.subBlocks,
        })
        .from(workflowBlocks)
        .where(eq(workflowBlocks.workflowId, id))

      const blocksRecord = Object.fromEntries(
        blockRows.map((block) => [block.id, { type: block.type, subBlocks: block.subBlocks }])
      )
      const inputs = extractInputFieldsFromBlocks(blocksRecord)

      const response = {
        id: workflowData.id,
        name: workflowData.name,
        description: workflowData.description,
        color: workflowData.color,
        folderId: workflowData.folderId,
        workspaceId: workflowData.workspaceId,
        isDeployed: workflowData.isDeployed,
        deployedAt: workflowData.deployedAt?.toISOString() || null,
        runCount: workflowData.runCount,
        lastRunAt: workflowData.lastRunAt?.toISOString() || null,
        variables: workflowData.variables || {},
        inputs,
        createdAt: workflowData.createdAt.toISOString(),
        updatedAt: workflowData.updatedAt.toISOString(),
      }

      const limits = await getUserLimits(userId)

      const apiResponse = createApiResponse({ data: response }, limits, rateLimit)

      return NextResponse.json(apiResponse.body, { headers: apiResponse.headers })
    } catch (error: unknown) {
      const message = error instanceof Error ? error.message : 'Unknown error'
      logger.error(`[${requestId}] Workflow details fetch error`, { error: message })
      return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
    }
  }
)
