<script setup lang="ts">
const { $i18n } = useNuxtApp()
const t = $i18n.t

const message = ref('')
const sending = ref(false)
const sent = ref(false)
const error = ref('')
const cooldown = ref(0)
const honeypot = ref('')
const mountTime = Date.now()
let cooldownTimer: ReturnType<typeof setInterval> | null = null

const {
  recaptchaSiteKey: siteKey,
  feedbackMaxPerHour: MAX_PER_HOUR,
  feedbackMaxPerSession: MAX_PER_SESSION,
  feedbackCooldownSec: COOLDOWN_SEC,
  feedbackMinSeconds: MIN_SECONDS
} = useRuntimeConfig().public
const RATE_LIMIT_KEY = 'feedback_ratelimit'
const SESSION_LIMIT_KEY = 'feedback_session'

function sanitize(text: string): string {
  let clean = text
  clean = clean.replace(/<[^>]*>/g, '')
  clean = clean.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
  clean = clean.replace(/https?:\/\/[^\s]+/gi, '')
  clean = clean.replace(/www\.[^\s]+/gi, '')
  clean = clean.replace(/javascript\s*:/gi, '')
  clean = clean.replace(/\beval\s*\(/gi, '')
  clean = clean.replace(/\bon\w+\s*=/gi, '')
  clean = clean.replace(/[A-Za-z0-9+/]{50,}={0,2}/g, '')
  clean = clean.replace(/'\s*OR\s+\d+\s*=\s*\d+/gi, '')
  clean = clean.replace(/'\s*--/g, "'")
  clean = clean.replace(/'\s*;\s*DROP\s+TABLE/gi, "'")
  clean = clean.replace(/UNION\s+SELECT/gi, '')
  clean = clean.replace(/xp_cmdshell/gi, '')
  clean = clean.replace(/EXEC\s*\(/gi, '')
  clean = clean.replace(/`[^`]*`/g, '')
  clean = clean.replace(/\$\(.*?\)/g, '')
  clean = clean.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, '')
  return clean.slice(0, 500)
}

function getRateLimitCount(): number {
  try {
    const raw = localStorage.getItem(RATE_LIMIT_KEY)
    if (!raw) return 0
    const data: { count: number; reset: number } = JSON.parse(raw)
    if (Date.now() > data.reset) {
      localStorage.removeItem(RATE_LIMIT_KEY)
      return 0
    }
    return data.count
  } catch {
    return 0
  }
}

function incrementRateLimit() {
  const raw = localStorage.getItem(RATE_LIMIT_KEY)
  const now = Date.now()
  let data = { count: 0, reset: now + 3600000 }
  if (raw) {
    try {
      const parsed = JSON.parse(raw)
      if (now <= parsed.reset) {
        data = parsed
      }
    } catch { /* usar default */ }
  }
  data.count++
  localStorage.setItem(RATE_LIMIT_KEY, JSON.stringify(data))
}

function getSessionCount(): number {
  try {
    const raw = sessionStorage.getItem(SESSION_LIMIT_KEY)
    return raw ? Number(raw) : 0
  } catch {
    return 0
  }
}

function incrementSession() {
  const count = getSessionCount() + 1
  sessionStorage.setItem(SESSION_LIMIT_KEY, String(count))
}

function checkBlocked(): string | null {
  const elapsed = (Date.now() - mountTime) / 1000
  if (elapsed < MIN_SECONDS) return t('feedback.error_cooldown')

  const rateCount = getRateLimitCount()
  if (rateCount >= MAX_PER_HOUR) return t('feedback.error_rate_limit')

  const sessionCount = getSessionCount()
  if (sessionCount >= MAX_PER_SESSION) return t('feedback.error_session_limit')

  return null
}

function startCooldown() {
  cooldown.value = COOLDOWN_SEC
  cooldownTimer = setInterval(() => {
    cooldown.value--
    if (cooldown.value <= 0) {
      if (cooldownTimer) clearInterval(cooldownTimer)
      cooldown.value = 0
    }
  }, 1000)
}

const { executeRecaptcha } = useRecaptcha(siteKey)

async function send() {
  const body = sanitize(message.value)
  if (!body.trim()) return

  if (honeypot.value.trim()) return

  const blocked = checkBlocked()
  if (blocked !== null) {
    error.value = blocked
    return
  }

  sending.value = true
  error.value = ''

  try {
    const token = siteKey ? await executeRecaptcha('submit_feedback') : null

    await $fetch('/api/feedback', {
      method: 'POST',
      body: { message: body, recaptchaToken: token }
    })

    sent.value = true
    message.value = ''
    incrementRateLimit()
    incrementSession()
    startCooldown()
  } catch (e) {
    error.value = t('feedback.error_generic')
  } finally {
    sending.value = false
  }
}
</script>

<template>
  <UDashboardPanel id="bugreport-panel" grow>
    <UDashboardNavbar :title="t('feedback.title')">
      <template #leading>
        <UDashboardSidebarCollapse />
      </template>
    </UDashboardNavbar>

    <div class="flex-1 flex items-center justify-center p-6">
      <div v-if="sent" class="text-center space-y-3">
        <UIcon name="i-lucide-circle-check" class="size-16 text-green-500" />
        <p class="text-sm text-muted">{{ t('feedback.success_message') }}</p>
        <UButton color="neutral" variant="outline" @click="sent = false">
          {{ t('feedback.send_another') }}
        </UButton>
      </div>

      <div v-else class="flex flex-col items-center gap-6 w-full max-w-xl">
        <BugReportInput v-model="message" />

        <input
          v-model="honeypot"
          type="text"
          tabindex="-1"
          autocomplete="off"
          class="absolute -left-[9999px] -top-[9999px] opacity-0 pointer-events-none size-0"
          aria-hidden="true"
        />

        <UButton
          :loading="sending"
          :disabled="!message.trim() || cooldown > 0"
          size="lg"
          class="max-w-xl"
          @click="send"
        >
          {{ sending ? t('feedback.sending') : cooldown > 0 ? t('feedback.wait_seconds', { seconds: cooldown }) : t('feedback.send') }}
        </UButton>

        <p v-if="error" class="text-sm text-red-500">{{ error }}</p>
      </div>
    </div>
  </UDashboardPanel>
</template>
