<script setup>
import * as echarts from 'echarts'
import { ElMessage } from 'element-plus'
import { computed, nextTick, onBeforeUnmount, onMounted, ref } from 'vue'

import MetricTile from '../components/MetricTile.vue'
import PageHero from '../components/PageHero.vue'
import { fetchDashboard, humanizeError } from '../api'
import { usePolling } from '../composables/usePolling'
import { formatCompactNumber, formatDateTime, formatPercent } from '../utils/formatters'

const loading = ref(false)
const dashboard = ref({
  today: { total: 0, allowed: 0, intercepted: 0 },
  bindings: { active: 0, banned: 0 },
  trend: [],
  recent_intercepts: [],
})
const chartElement = ref(null)
let chart

const interceptRate = computed(() => {
  const total = dashboard.value.today.total || 0
  if (!total) {
    return 0
  }
  return dashboard.value.today.intercepted / total
})

const bindingCoverage = computed(() => {
  const active = dashboard.value.bindings.active || 0
  const banned = dashboard.value.bindings.banned || 0
  const total = active + banned
  if (!total) {
    return 0
  }
  return active / total
})

async function renderChart() {
  await nextTick()
  if (!chartElement.value) {
    return
  }

  chart ||= echarts.init(chartElement.value)
  chart.setOption({
    animationDuration: 500,
    color: ['#0b9e88', '#ef7f41'],
    grid: {
      left: 24,
      right: 24,
      top: 40,
      bottom: 28,
      containLabel: true,
    },
    legend: {
      top: 0,
      textStyle: {
        color: '#516a75',
        fontWeight: 600,
      },
    },
    tooltip: {
      trigger: 'axis',
      backgroundColor: 'rgba(8, 24, 34, 0.9)',
      borderWidth: 0,
      textStyle: {
        color: '#f7fffe',
      },
    },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: dashboard.value.trend.map((item) => item.date.slice(5)),
      axisLine: { lineStyle: { color: 'rgba(9, 22, 30, 0.18)' } },
      axisLabel: { color: '#516a75', fontWeight: 600 },
    },
    yAxis: {
      type: 'value',
      splitLine: { lineStyle: { color: 'rgba(9, 22, 30, 0.08)' } },
      axisLabel: { color: '#516a75' },
    },
    series: [
      {
        name: 'Allowed',
        type: 'line',
        smooth: true,
        showSymbol: false,
        areaStyle: { color: 'rgba(11, 158, 136, 0.14)' },
        lineStyle: { width: 3 },
        data: dashboard.value.trend.map((item) => item.allowed),
      },
      {
        name: 'Intercepted',
        type: 'line',
        smooth: true,
        showSymbol: false,
        areaStyle: { color: 'rgba(239, 127, 65, 0.12)' },
        lineStyle: { width: 3 },
        data: dashboard.value.trend.map((item) => item.intercepted),
      },
    ],
  })
}

async function loadDashboard() {
  loading.value = true
  try {
    dashboard.value = await fetchDashboard()
    await renderChart()
  } catch (error) {
    ElMessage.error(humanizeError(error, 'Failed to load dashboard.'))
  } finally {
    loading.value = false
  }
}

function resizeChart() {
  chart?.resize()
}

const { start: startPolling, stop: stopPolling } = usePolling(loadDashboard, 30000)

onMounted(async () => {
  await loadDashboard()
  startPolling()
  window.addEventListener('resize', resizeChart)
})

onBeforeUnmount(() => {
  stopPolling()
  window.removeEventListener('resize', resizeChart)
  chart?.dispose()
})
</script>

<template>
  <div class="page-grid">
    <PageHero
      eyebrow="Traffic pulse"
      title="Edge decisions and security drift in one pass"
      description="The dashboard combines live proxy metrics with persisted intercept records so security events remain visible even if Redis rolls over."
    >
      <template #aside>
        <div class="hero-stat-pair">
          <div class="hero-stat">
            <span class="eyebrow">Intercept rate</span>
            <strong>{{ formatPercent(interceptRate) }}</strong>
          </div>
          <div class="hero-stat">
            <span class="eyebrow">Active share</span>
            <strong>{{ formatPercent(bindingCoverage) }}</strong>
          </div>
        </div>
      </template>

      <template #actions>
        <el-button :loading="loading" type="primary" plain @click="loadDashboard">Refresh dashboard</el-button>
      </template>
    </PageHero>

    <section class="metric-grid">
      <MetricTile
        eyebrow="Today"
        :value="formatCompactNumber(dashboard.today.total)"
        note="Total edge decisions recorded today."
        accent="slate"
      />
      <MetricTile
        eyebrow="Allowed"
        :value="formatCompactNumber(dashboard.today.allowed)"
        note="Requests that passed binding enforcement."
        accent="mint"
      />
      <MetricTile
        eyebrow="Intercepted"
        :value="formatCompactNumber(dashboard.today.intercepted)"
        note="Requests blocked for CIDR mismatch or banned keys."
        accent="amber"
      />
      <MetricTile
        eyebrow="Bindings"
        :value="formatCompactNumber(dashboard.bindings.active)"
        :note="`Active bindings, with ${formatCompactNumber(dashboard.bindings.banned)} banned keys in reserve.`"
        accent="slate"
      />
    </section>

    <section class="content-grid">
      <article class="chart-card panel">
        <div class="toolbar">
          <div>
            <p class="eyebrow">7-day trend</p>
            <h3 class="section-title">Allowed vs intercepted flow</h3>
          </div>
          <div class="inline-meta">
            <el-tag round effect="plain" type="success">30s auto refresh</el-tag>
            <span class="muted">Redis metrics with PostgreSQL intercept backfill.</span>
          </div>
        </div>
        <div ref="chartElement" class="chart-surface" />
      </article>

      <article class="table-card panel">
        <div class="table-toolbar-block">
          <p class="eyebrow">Recent blocks</p>
          <h3 class="section-title">Latest intercepted requests</h3>
          <p class="muted">Operators can triage repeated misuse and verify whether alert escalation has already fired.</p>
        </div>

        <div v-if="!dashboard.recent_intercepts.length" class="empty-state">No intercepts recorded yet.</div>

        <div v-else class="table-stack" style="margin-top: 18px;">
          <div
            v-for="item in dashboard.recent_intercepts"
            :key="item.id"
            class="insight-card"
            style="padding: 16px; border-radius: 20px;"
          >
            <div class="toolbar">
              <strong>{{ item.token_display }}</strong>
              <el-tag :type="item.alerted ? 'danger' : 'warning'" round>
                {{ item.alerted ? 'Alerted' : 'Pending' }}
              </el-tag>
            </div>
            <p class="insight-note">Bound CIDR: {{ item.bound_ip }}</p>
            <p class="insight-note">Attempt IP: {{ item.attempt_ip }}</p>
            <p class="insight-note">{{ formatDateTime(item.intercepted_at) }}</p>
          </div>
        </div>
      </article>
    </section>
  </div>
</template>
