import type { RowDataPacket } from 'mysql2'
import { getSession } from '@/lib/session'
import { db, DB } from '@/lib/db'
import { getClassCss } from '@/lib/character-info'
import { verifyTurnstile } from '@/lib/turnstile'
import { QUEST_OPTIONS, questStatuses, cooldownRemainingMs, recordSearch, type QuestCategory } from '@/lib/quest-tracker'

export async function POST(request: Request) {
  const session = await getSession()
  if (!session.accountId || !session.username) {
    return Response.json({ success: false, error: 'notAuthenticated' }, { status: 401 })
  }

  let body: Record<string, unknown> = {}
  try {
    body = await request.json()
  } catch {
    return Response.json({ success: false, error: 'invalidRequest' }, { status: 400 })
  }

  const character = String(body.character ?? '').trim()
  const optionKey = String(body.option ?? '').trim()
  if (!character || !optionKey) return Response.json({ success: false, error: 'missingFields' })

  const ip = (request.headers.get('x-forwarded-for') || '').split(',')[0].trim() || undefined
  if (!(await verifyTurnstile(String(body.turnstile ?? ''), ip))) {
    return Response.json({ success: false, error: 'captcha' })
  }

  // Personaje: debe ser de la cuenta y estar desconectado.
  let guid = 0
  let level = 0
  let classCss = ''
  try {
    const [rows] = await db(DB.characters).query<RowDataPacket[]>(
      'SELECT guid, level, class, online FROM characters WHERE name = ? AND account = ? LIMIT 1',
      [character, session.accountId],
    )
    const c = rows[0]
    if (!c) return Response.json({ success: false, error: 'characterNotOwned' })
    if (c.online === 1) return Response.json({ success: false, error: 'characterOnline' })
    guid = Number(c.guid)
    level = Number(c.level)
    classCss = getClassCss(Number(c.class))
  } catch {
    return Response.json({ success: false, error: 'genericError' })
  }

  // Resuelve categoría + misiones a comprobar.
  let category: QuestCategory
  let quests: number[]
  let label: string
  if (optionKey === 'specific') {
    const qid = Number(body.questId)
    if (!Number.isInteger(qid) || qid <= 0) return Response.json({ success: false, error: 'invalidQuestId' })
    if (level < 10) return Response.json({ success: false, error: 'levelTooLow' })
    category = 'specific'
    quests = [qid]
    label = `Misión #${qid}`
  } else {
    const opt = QUEST_OPTIONS.find((o) => o.key === optionKey)
    if (!opt) return Response.json({ success: false, error: 'invalidOption' })
    if (opt.classCss && opt.classCss !== classCss) return Response.json({ success: false, error: 'wrongClass' })
    if (level < opt.minLevel) return Response.json({ success: false, error: 'levelTooLow' })
    if (opt.quests.length === 0) return Response.json({ success: false, error: 'noData' })
    category = opt.category
    quests = opt.quests
    label = opt.label
  }

  const remaining = await cooldownRemainingMs(character, category)
  if (remaining > 0) {
    return Response.json({ success: false, error: 'cooldown', minutes: Math.ceil(remaining / 60000) })
  }

  const statuses = await questStatuses(guid, quests)
  await recordSearch(character, category)
  return Response.json({ success: true, label, statuses })
}
