import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import {
  submitAlertFeedback,
  fetchQualityMetricsSummary,
  fetchQualityMetrics,
  fetchQualityFeedback,
} from '@/api/alertQuality'

function csvEscape(value) {
  if (value == null) return ''
  const s = String(value)
  if (/[",\n\r]/.test(s)) return `"${s.replace(/"/g, '""')}"`
  return s
}

export const useAlertQualityStore = defineStore('alertQuality', () => {
  const summary = ref(null)
  const snapshots = ref([])
  const feedbackRows = ref([])
  const availableScenarioIds = ref([])
  const periodDays = ref(7)
  const selectedAlertType = ref(null)
  const selectedScenarioId = ref(null)
  const loading = ref(false)
  const error = ref(null)

  // Per-alert feedback cache: alertId → { rating, comment, submittedAt }
  const feedbackByAlert = ref({})

  const summaryStats = computed(() => {
    const s = summary.value
    if (!s) {
      return {
        totalAlerts: 0,
        totalFeedback: 0,
        acknowledgementRate: 0,
        usefulRate: 0,
        falsePositiveRate: 0,
        wouldActRate: 0,
        avgAckMinutes: 0,
        avgResolveMinutes: 0,
      }
    }
    return {
      totalAlerts: s.totalAlerts,
      totalFeedback: s.totalFeedback,
      acknowledgementRate: Math.round(s.acknowledgementRate * 100),
      usefulRate: Math.round(s.usefulRate * 100),
      falsePositiveRate: Math.round(s.falsePositiveRate * 100),
      wouldActRate: Math.round(s.wouldActRate * 100),
      avgAckMinutes: Math.round(s.avgSecondsToAcknowledge / 60),
      avgResolveMinutes: Math.round(s.avgSecondsToResolution / 60),
    }
  })

  const byAlertType = computed(() => {
    const map = {}
    for (const snap of snapshots.value) {
      if (!map[snap.alertType]) map[snap.alertType] = []
      map[snap.alertType].push(snap)
    }
    return map
  })

  const scenarioOptions = computed(() => availableScenarioIds.value)

  const byScenario = computed(() => {
    const map = {}
    for (const row of feedbackRows.value) {
      const key = row.scenarioId || '(non-simulated)'
      if (!map[key]) {
        map[key] = {
          scenarioId: row.scenarioId || null,
          totalFeedback: 0,
          useful: 0,
          falsePositive: 0,
          wouldAct: 0,
        }
      }
      const bucket = map[key]
      bucket.totalFeedback += 1
      if (row.feedbackType === 'USEFUL') bucket.useful += 1
      if (row.feedbackType === 'FALSE_POSITIVE') bucket.falsePositive += 1
      if (row.feedbackType === 'WOULD_ACT') bucket.wouldAct += 1
    }
    return Object.values(map).map((b) => ({
      ...b,
      usefulRate: b.totalFeedback ? b.useful / b.totalFeedback : 0,
      falsePositiveRate: b.totalFeedback ? b.falsePositive / b.totalFeedback : 0,
      wouldActRate: b.totalFeedback ? b.wouldAct / b.totalFeedback : 0,
    })).sort((a, b) => (a.scenarioId || '').localeCompare(b.scenarioId || ''))
  })

  function periodRange() {
    const to = new Date().toISOString()
    const from = new Date(Date.now() - periodDays.value * 86_400_000).toISOString()
    return { from, to }
  }

  async function loadDashboard() {
    loading.value = true
    error.value = null
    try {
      const { from, to } = periodRange()
      const [sum, list, feedback] = await Promise.all([
        fetchQualityMetricsSummary(from, to),
        fetchQualityMetrics({
          alertType: selectedAlertType.value,
          from,
          to,
        }),
        fetchQualityFeedback({
          scenarioId: selectedScenarioId.value,
          from,
          to,
        }),
      ])
      summary.value = sum
      snapshots.value = list.items ?? []
      feedbackRows.value = feedback.items ?? []
      if (!selectedScenarioId.value) {
        availableScenarioIds.value = [...new Set(
          feedbackRows.value.map(r => r.scenarioId).filter(Boolean),
        )].sort()
      }
    } catch (e) {
      error.value = e.message
    } finally {
      loading.value = false
    }
  }

  async function submitFeedback(alertId, rating, comment = '') {
    const result = await submitAlertFeedback(alertId, rating, comment)
    feedbackByAlert.value[alertId] = {
      rating,
      comment,
      submittedAt: result.createdAt,
      feedbackType: result.feedbackType,
    }
    return result
  }

  function getFeedback(alertId) {
    return feedbackByAlert.value[alertId] ?? null
  }

  function setPeriodDays(days) {
    periodDays.value = days
  }

  function setAlertTypeFilter(type) {
    selectedAlertType.value = type
  }

  function setScenarioFilter(scenarioId) {
    selectedScenarioId.value = scenarioId || null
  }

  function buildCsv() {
    const includeScenario = feedbackRows.value.some(
      r => Object.prototype.hasOwnProperty.call(r, 'scenarioId'),
    )
    const headers = [
      'feedbackId',
      'alertId',
      'alertType',
      'feedbackType',
      'comment',
      'createdAt',
    ]
    if (includeScenario) {
      headers.push('scenarioId', 'sessionId')
    }

    const lines = [headers.join(',')]
    for (const row of feedbackRows.value) {
      const cols = [
        row.id,
        row.alertId,
        row.alertType,
        row.feedbackType,
        row.comment,
        row.createdAt,
      ]
      if (includeScenario) {
        cols.push(row.scenarioId ?? '', row.sessionId ?? '')
      }
      lines.push(cols.map(csvEscape).join(','))
    }
    return lines.join('\n')
  }

  function exportCsv() {
    const csv = buildCsv()
    const blob = new Blob([csv], { type: 'text/csv;charset=utf-8' })
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = `alert-quality-feedback-${periodDays.value}d.csv`
    a.click()
    URL.revokeObjectURL(url)
  }

  return {
    summary,
    snapshots,
    feedbackRows,
    periodDays,
    selectedAlertType,
    selectedScenarioId,
    loading,
    error,
    summaryStats,
    byAlertType,
    byScenario,
    scenarioOptions,
    loadDashboard,
    submitFeedback,
    getFeedback,
    setPeriodDays,
    setAlertTypeFilter,
    setScenarioFilter,
    buildCsv,
    exportCsv,
  }
})
