import { NextRequest, NextResponse } from 'next/server'
import { auth } from '@/lib/auth'
import { prisma } from '@/lib/prisma'
import { testServerConnection } from '@/lib/ansible'
import { SSH_PORT_BEFORE_PROVISION } from '@/lib/ssh/constants'
import { decryptPassword } from '@/lib/services/config-generator'

interface RouteContext {
  params: Promise<{ id: string }>
}

/**
 * POST /api/v1/admin/orders/[id]/test-ssh
 * Test SSH connection to the server
 *
 * Accepts optional body with credentials to test before saving:
 * { serverIp?: string, password?: string, sshPort?: number }
 *
 * If body credentials provided, uses those (for testing before save)
 * Otherwise uses saved order credentials
 */
export async function POST(request: NextRequest, context: RouteContext) {
  try {
    const session = await auth()

    if (!session || session.user.userType !== 'staff') {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
    }

    const { id: orderId } = await context.params

    // Parse optional body for testing unsaved credentials
    let body: { serverIp?: string; password?: string; sshPort?: number } = {}
    try {
      body = await request.json()
    } catch {
      // No body provided, will use saved credentials
    }

    // Get order
    const order = await prisma.order.findUnique({
      where: { id: orderId },
    })

    if (!order) {
      return NextResponse.json({ error: 'Order not found' }, { status: 404 })
    }

    // Determine which credentials to use
    // Priority: body params > saved order data
    const serverIp = body.serverIp || order.serverIp
    const sshPort = body.sshPort || order.sshPort || SSH_PORT_BEFORE_PROVISION

    // For password: use body.password directly, or decrypt saved password
    let password: string | null = null
    if (body.password) {
      password = body.password
    } else if (order.serverPasswordEncrypted) {
      password = decryptPassword(order.serverPasswordEncrypted)
    }

    // Validate we have required credentials
    if (!serverIp) {
      return NextResponse.json(
        { error: 'Server IP not configured' },
        { status: 400 }
      )
    }

    if (!password) {
      return NextResponse.json(
        { error: 'Server password not configured' },
        { status: 400 }
      )
    }

    // Test SSH connection
    const result = await testServerConnection(
      serverIp,
      password,
      sshPort
    )

    if (result.success) {
      // Log successful test
      await prisma.provisioningLog.create({
        data: {
          orderId,
          level: 'INFO',
          message: `SSH connection test successful to ${serverIp}:${sshPort} (latency: ${result.latency}ms)`,
          step: 'ssh-test',
        },
      })

      return NextResponse.json({
        success: true,
        latency: result.latency,
        message: 'SSH connection successful',
        serverIp,
        sshPort,
      })
    } else {
      // Log failed test
      await prisma.provisioningLog.create({
        data: {
          orderId,
          level: 'ERROR',
          message: `SSH connection test failed to ${serverIp}:${sshPort}: ${result.error}`,
          step: 'ssh-test',
        },
      })

      return NextResponse.json(
        {
          success: false,
          error: result.error,
          message: 'SSH connection failed',
          serverIp,
          sshPort,
        },
        { status: 400 }
      )
    }
  } catch (error) {
    console.error('SSH test error:', error)
    return NextResponse.json(
      { error: 'Failed to test SSH connection' },
      { status: 500 }
    )
  }
}
