import { AuditAction, AuditResourceType, recordAudit } from '@sim/audit'
import { createLogger } from '@sim/logger'
import { FolderLockedError } from '@sim/platform-authz/workflow'
import { type NextRequest, NextResponse } from 'next/server'
import { duplicateWorkflowContract } from '@/lib/api/contracts/workflows'
import { parseRequest } from '@/lib/api/server'
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
import { PlatformEvents } from '@/lib/core/telemetry'
import { generateRequestId } from '@/lib/core/utils/request'
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
import { captureServerEvent } from '@/lib/posthog/server'
import { duplicateWorkflow } from '@/lib/workflows/persistence/duplicate'

const logger = createLogger('WorkflowDuplicateAPI')

// POST /api/workflows/[id]/duplicate - Duplicate a workflow with all its blocks, edges, and subflows
export const POST = withRouteHandler(
  async (req: NextRequest, context: { params: Promise<{ id: string }> }) => {
    const { id: sourceWorkflowId } = await context.params
    const requestId = generateRequestId()
    const startTime = Date.now()

    const auth = await checkSessionOrInternalAuth(req, { requireWorkflowId: false })
    if (!auth.success || !auth.userId) {
      logger.warn(
        `[${requestId}] Unauthorized workflow duplication attempt for ${sourceWorkflowId}`
      )
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
    }
    const userId = auth.userId

    try {
      const parsed = await parseRequest(duplicateWorkflowContract, req, context)
      if (!parsed.success) return parsed.response
      const { name, description, workspaceId, folderId, newId } = parsed.data.body

      logger.info(`[${requestId}] Duplicating workflow ${sourceWorkflowId} for user ${userId}`)

      const result = await duplicateWorkflow({
        sourceWorkflowId,
        userId,
        name,
        description,
        workspaceId,
        folderId,
        requestId,
        newWorkflowId: newId,
      })

      try {
        PlatformEvents.workflowDuplicated({
          sourceWorkflowId,
          newWorkflowId: result.id,
          workspaceId,
        })
      } catch {
        // Telemetry should not fail the operation
      }

      captureServerEvent(
        userId,
        'workflow_duplicated',
        {
          source_workflow_id: sourceWorkflowId,
          new_workflow_id: result.id,
          workspace_id: workspaceId ?? '',
        },
        workspaceId ? { groups: { workspace: workspaceId } } : undefined
      )

      const elapsed = Date.now() - startTime
      logger.info(
        `[${requestId}] Successfully duplicated workflow ${sourceWorkflowId} to ${result.id} in ${elapsed}ms`
      )

      recordAudit({
        workspaceId: workspaceId || null,
        actorId: userId,
        actorName: auth.userName,
        actorEmail: auth.userEmail,
        action: AuditAction.WORKFLOW_DUPLICATED,
        resourceType: AuditResourceType.WORKFLOW,
        resourceId: result.id,
        resourceName: result.name,
        description: `Duplicated workflow from ${sourceWorkflowId}`,
        metadata: {
          sourceWorkflowId,
          newWorkflowId: result.id,
          folderId: folderId || undefined,
        },
        request: req,
      })

      return NextResponse.json(result, { status: 201 })
    } catch (error) {
      if (error instanceof Error) {
        if (error instanceof FolderLockedError) {
          return NextResponse.json({ error: error.message }, { status: error.status })
        }

        if (error.message === 'Source workflow not found') {
          logger.warn(`[${requestId}] Source workflow ${sourceWorkflowId} not found`)
          return NextResponse.json({ error: 'Source workflow not found' }, { status: 404 })
        }

        if (error.message === 'Source workflow not found or access denied') {
          logger.warn(
            `[${requestId}] User ${userId} denied access to source workflow ${sourceWorkflowId}`
          )
          return NextResponse.json({ error: 'Access denied' }, { status: 403 })
        }

        if (error.message === 'Cross-workspace workflow duplication is not supported') {
          logger.warn(
            `[${requestId}] User ${userId} attempted cross-workspace workflow duplication for ${sourceWorkflowId}`
          )
          return NextResponse.json({ error: error.message }, { status: 400 })
        }

        if (error.message === 'Folder is locked') {
          return NextResponse.json({ error: error.message }, { status: 423 })
        }

        if (error.message === 'Target folder not found') {
          return NextResponse.json({ error: error.message }, { status: 400 })
        }
      }

      const elapsed = Date.now() - startTime
      logger.error(
        `[${requestId}] Error duplicating workflow ${sourceWorkflowId} after ${elapsed}ms:`,
        error
      )
      return NextResponse.json({ error: 'Failed to duplicate workflow' }, { status: 500 })
    }
  }
)
