import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { quiverImageToSvgContract } from '@/lib/api/contracts/tools/quiver'
import { getValidationErrorMessage, parseRequest } from '@/lib/api/server'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateRequestId } from '@/lib/core/utils/request'
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
import type { RawFileInput } from '@/lib/uploads/utils/file-schemas'
import { processFilesToUserFiles } from '@/lib/uploads/utils/file-utils'
import { downloadFileFromStorage } from '@/lib/uploads/utils/file-utils.server'
import { assertToolFileAccess } from '@/app/api/files/authorization'

const logger = createLogger('QuiverImageToSvgAPI')

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

  const authResult = await checkInternalAuth(request, { requireWorkflowId: false })
  if (!authResult.success || !authResult.userId) {
    return NextResponse.json({ success: false, error: 'Unauthorized' }, { status: 401 })
  }

  try {
    const parsed = await parseRequest(
      quiverImageToSvgContract,
      request,
      {},
      {
        validationErrorResponse: (error) =>
          NextResponse.json(
            {
              success: false,
              error: getValidationErrorMessage(error, 'Invalid request data'),
              details: error.issues,
            },
            { status: 400 }
          ),
      }
    )
    if (!parsed.success) return parsed.response
    const data = parsed.data.body

    let apiImage: { url: string } | { base64: string }

    if (typeof data.image === 'string') {
      try {
        const parsed = JSON.parse(data.image)
        if (parsed && typeof parsed === 'object') {
          const userFiles = processFilesToUserFiles([parsed as RawFileInput], requestId, logger)
          if (userFiles.length > 0) {
            const denied = await assertToolFileAccess(
              userFiles[0].key,
              authResult.userId,
              requestId,
              logger
            )
            if (denied) return denied
            const buffer = await downloadFileFromStorage(userFiles[0], requestId, logger)
            apiImage = { base64: buffer.toString('base64') }
          } else {
            return NextResponse.json(
              { success: false, error: 'Invalid file input' },
              { status: 400 }
            )
          }
        } else {
          apiImage = { url: data.image }
        }
      } catch {
        apiImage = { url: data.image }
      }
    } else if (typeof data.image === 'object' && data.image !== null) {
      const userFiles = processFilesToUserFiles([data.image as RawFileInput], requestId, logger)
      if (userFiles.length > 0) {
        const denied = await assertToolFileAccess(
          userFiles[0].key,
          authResult.userId,
          requestId,
          logger
        )
        if (denied) return denied
        const buffer = await downloadFileFromStorage(userFiles[0], requestId, logger)
        apiImage = { base64: buffer.toString('base64') }
      } else {
        return NextResponse.json({ success: false, error: 'Invalid file input' }, { status: 400 })
      }
    } else {
      return NextResponse.json({ success: false, error: 'Image is required' }, { status: 400 })
    }

    const apiBody: Record<string, unknown> = {
      model: data.model,
      image: apiImage,
    }

    if (data.temperature != null) apiBody.temperature = data.temperature
    if (data.top_p != null) apiBody.top_p = data.top_p
    if (data.max_output_tokens != null) apiBody.max_output_tokens = data.max_output_tokens
    if (data.presence_penalty != null) apiBody.presence_penalty = data.presence_penalty
    if (data.auto_crop != null) apiBody.auto_crop = data.auto_crop
    if (data.target_size != null) apiBody.target_size = data.target_size

    logger.info(`[${requestId}] Calling Quiver vectorization API with model: ${data.model}`)

    const response = await fetch('https://api.quiver.ai/v1/svgs/vectorizations', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${data.apiKey}`,
      },
      body: JSON.stringify(apiBody),
    })

    if (!response.ok) {
      const errorText = await response.text()
      logger.error(`[${requestId}] Quiver API error: ${response.status} - ${errorText}`)
      return NextResponse.json(
        { success: false, error: `Quiver API error: ${response.status} - ${errorText}` },
        { status: response.status }
      )
    }

    const result = await response.json()

    if (!result.data || result.data.length === 0) {
      return NextResponse.json(
        { success: false, error: 'No SVG data returned from Quiver API' },
        { status: 500 }
      )
    }

    const svgContent = result.data[0].svg
    const svgBuffer = Buffer.from(svgContent, 'utf-8')
    const file = {
      name: 'vectorized.svg',
      mimeType: 'image/svg+xml',
      data: svgBuffer.toString('base64'),
      size: svgBuffer.length,
    }

    return NextResponse.json({
      success: true,
      output: {
        file,
        files: [file],
        svgContent,
        id: result.id ?? null,
        usage: result.usage
          ? {
              totalTokens: result.usage.total_tokens ?? 0,
              inputTokens: result.usage.input_tokens ?? 0,
              outputTokens: result.usage.output_tokens ?? 0,
            }
          : null,
      },
    })
  } catch (error) {
    logger.error(`[${requestId}] Error in Quiver image-to-svg:`, error)
    const message = getErrorMessage(error, 'Unknown error')
    return NextResponse.json({ success: false, error: message }, { status: 500 })
  }
})
