import { NextResponse } from 'next/server'
import { getAdminSession } from '@/lib/auth'
import { checkAgentAuth } from '@/lib/agent-auth'
import { db } from '@/lib/db'
import { triggerAgent } from '@/lib/agent-trigger'

export const runtime = 'nodejs'

// The capture-upload trigger is fire-and-forget SSH to the Mac, so a network
// blip between the VPS and the house loses the job and the capture sits
// "Queued" forever. This sweep (piggybacked on the 15-min sync cron) re-fires
// the trigger for anything still queued, and surfaces a hard FAILED once it
// has been stuck long enough that the retries clearly aren't landing.
const RETRY_PENDING_AFTER_MS = 5 * 60_000 // the Mac claims a job within seconds; 5 min still PENDING = trigger lost
const RETRY_PROCESSING_AFTER_MS = 20 * 60_000 // claimed jobs finish in ~30s; 20 min = the Mac-side run died
const FAIL_AFTER_MS = 6 * 60 * 60_000

async function sweepStuckCaptures(): Promise<void> {
  const now = Date.now()
  const stuck = await db.capture.findMany({
    where: {
      OR: [
        { status: 'PENDING', queuedAt: { lt: new Date(now - RETRY_PENDING_AFTER_MS) } },
        { status: 'PROCESSING', queuedAt: { lt: new Date(now - RETRY_PROCESSING_AFTER_MS) } },
      ],
    },
    select: { id: true, queuedAt: true },
  })
  for (const c of stuck) {
    const stuckMin = Math.round((now - c.queuedAt.getTime()) / 60_000)
    if (now - c.queuedAt.getTime() >= FAIL_AFTER_MS) {
      await db.capture.update({
        where: { id: c.id },
        data: { status: 'FAILED', error: `processing timed out (stuck ${Math.round(stuckMin / 60)}h) — the Mac agent never completed it; Re-process to retry` },
      })
      console.error(`[sweep] capture ${c.id} stuck ${stuckMin} min — marked FAILED`)
    } else {
      console.log(`[sweep] capture ${c.id} stuck ${stuckMin} min — re-triggering agent`)
      triggerAgent(c.id).catch(err =>
        console.error(`[sweep] capture ${c.id} re-trigger failed:`, err?.message || err))
    }
  }
}

// POST /api/sync — trigger an Apple→app mirror pass on the Mac, and re-drive
// any captures whose agent hand-off was lost.
// Auth: a logged-in session (the "Sync" button) OR the agent bearer (the cron).
export async function POST(req: Request) {
  const session = await getAdminSession()
  if (!session && !checkAgentAuth(req)) {
    return NextResponse.json({ error: 'unauthorized' }, { status: 401 })
  }

  triggerAgent('mirror').catch(err => {
    console.error('[sync] mirror trigger failed:', err?.message || err)
  })
  await sweepStuckCaptures().catch(err =>
    console.error('[sweep] stuck-capture sweep failed:', err?.message || err))
  return NextResponse.json({ ok: true })
}
