import { auth } from '@/auth'
import { db } from '@/lib/db'
import { machines } from '@/lib/db/schema'
import { and, eq } from 'drizzle-orm'
import { NextRequest, NextResponse } from 'next/server'
import { createSocket } from 'dgram'

function buildMagicPacket(mac: string): Buffer {
  // Normalise: strip separators, expect 12 hex chars
  const hex = mac.replace(/[:\-]/g, '').toLowerCase()
  if (hex.length !== 12 || !/^[0-9a-f]+$/.test(hex)) {
    throw new Error('Invalid MAC address')
  }
  const macBytes = Buffer.from(hex, 'hex')
  // Magic packet: 6x 0xFF + 16x MAC
  const packet = Buffer.alloc(6 + 16 * 6)
  packet.fill(0xff, 0, 6)
  for (let i = 0; i < 16; i++) macBytes.copy(packet, 6 + i * 6)
  return packet
}

async function sendMagicPacket(mac: string): Promise<void> {
  const packet = buildMagicPacket(mac)
  return new Promise((resolve, reject) => {
    const sock = createSocket('udp4')
    sock.once('error', reject)
    sock.bind(() => {
      sock.setBroadcast(true)
      sock.send(packet, 0, packet.length, 9, '255.255.255.255', () => {
        sock.close()
        resolve()
      })
    })
  })
}

export async function POST(request: NextRequest) {
  const session = await auth()
  if (!session?.user?.id) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })

  const { machineId } = await request.json()
  if (!machineId) return NextResponse.json({ error: 'machineId required' }, { status: 400 })

  const result = await db
    .select({ macAddress: machines.macAddress, name: machines.name })
    .from(machines)
    .where(and(eq(machines.id, machineId), eq(machines.userId, session.user.id)))
    .limit(1)

  const machine = result[0]
  if (!machine) return NextResponse.json({ error: 'Machine not found' }, { status: 404 })
  if (!machine.macAddress) return NextResponse.json({ error: 'No MAC address recorded for this machine. Agent must reconnect at least once.' }, { status: 422 })

  try {
    await sendMagicPacket(machine.macAddress)
    return NextResponse.json({ success: true, message: `Magic packet sent to ${machine.macAddress}` })
  } catch (e) {
    return NextResponse.json({ error: String(e) }, { status: 500 })
  }
}
