import { computed } from 'vue'
import { AlertTriangle, CheckCircle2, Clock3, Sparkles, Tags, Trophy, Users, Vote } from '@lucide/vue'

import { getVoteMetricValue } from '../../lib/adminMetrics'
import { useAwardsStore } from '../../stores/awards'
import { buildAdminReadinessScope } from './adminReadinessPhase'

export function useAdminAnalyticsManager() {
  const store = useAwardsStore()

  const seasonDetail = computed(() => store.adminSeasonDetail)
  const topCategories = computed(() => store.admin.topCategories)
  const totalVotes = computed(() => getVoteMetricValue(store.admin.metrics))
  const totalNominations = computed(() => store.admin.metrics.find((metric) => metric.label === 'Nominierungen')?.value ?? 0)
  const maxVotes = computed(() => Math.max(...topCategories.value.map((category) => category.value), 1))
  const resultMap = computed(() => new Map(seasonDetail.value.results.map((result) => [result.categoryId, result])))
  const voteMap = computed(() => new Map(topCategories.value.map((category) => [category.category, category.value])))
  const readinessScope = computed(() => buildAdminReadinessScope(seasonDetail.value))

  const categoryHealth = computed(() =>
    seasonDetail.value.categories
      .map((category) => {
        const candidates = seasonDetail.value.candidates.filter((candidate) => candidate.categoryId === category.id).length
        const reviews = seasonDetail.value.pendingNominations.filter((nomination) => nomination.categoryId === category.id).length
        const hasWinner = resultMap.value.has(category.id)
        const votes = voteMap.value.get(category.name) ?? 0
        const status = candidates === 0 ? 'Leer' : reviews > 0 ? 'Review offen' : hasWinner ? 'Gewinner gesetzt' : 'Bereit'
        const emptyIsWarning = candidates === 0 && readinessScope.value.candidateWarningsActive
        const reviewIsWarning = reviews > 0 && readinessScope.value.reviewWarningsActive

        return {
          id: category.id,
          name: category.name,
          groupName: category.groupName,
          candidates,
          reviews,
          hasWinner,
          votes,
          votePct: totalVotes.value > 0 ? Math.round((votes / totalVotes.value) * 100) : 0,
          status,
          statusClass: emptyIsWarning
            ? 'border-rose-100 bg-rose-50 text-rose-700'
            : reviewIsWarning
              ? 'border-amber-100 bg-amber-50 text-amber-700'
              : hasWinner
                ? 'border-emerald-100 bg-emerald-50 text-emerald-700'
                : candidates === 0 || reviews > 0
                  ? 'border-violet-100 bg-violet-50 text-violet-700'
                  : 'border-sky-100 bg-sky-50 text-sky-700',
          statusDot: emptyIsWarning ? 'bg-rose-400' : reviewIsWarning ? 'bg-amber-400' : hasWinner ? 'bg-emerald-400' : candidates === 0 || reviews > 0 ? 'bg-violet-400' : 'bg-sky-400',
          cardClass: emptyIsWarning
            ? 'border-rose-100 bg-rose-50/55'
            : reviewIsWarning
              ? 'border-amber-100 bg-amber-50/55'
              : hasWinner
                ? 'border-emerald-100 bg-emerald-50/55'
                : candidates === 0 || reviews > 0
                  ? 'border-violet-100 bg-violet-50/55'
                  : 'border-sky-100 bg-sky-50/55',
        }
      })
      .sort((a, b) => b.reviews - a.reviews || a.candidates - b.candidates || b.votes - a.votes),
  )

  const categoryGroups = computed(() => {
    const groups = new Map<string, typeof categoryHealth.value>()
    for (const cat of categoryHealth.value) {
      const key = cat.groupName || 'Ohne Gruppe'
      if (!groups.has(key)) groups.set(key, [])
      groups.get(key)!.push(cat)
    }
    return [...groups.entries()].map(([name, cats]) => ({ name, cats }))
  })

  const emptyCategories = computed(() => categoryHealth.value.filter((category) => category.candidates === 0))
  const categoriesWithReviews = computed(() => categoryHealth.value.filter((category) => category.reviews > 0))
  const categoriesWithoutWinner = computed(() => categoryHealth.value.filter((category) => !category.hasWinner))
  const categoriesReady = computed(() => categoryHealth.value.filter((c) => c.status === 'Bereit' || c.status === 'Gewinner gesetzt'))
  const pendingClipCount = computed(() => seasonDetail.value.clipSubmissions.filter((clip) => clip.status === 'pending').length)
  const winnerCoveragePct = computed(() => {
    const categoryCount = seasonDetail.value.categories.length
    if (categoryCount === 0) return 0
    return Math.round((seasonDetail.value.results.length / categoryCount) * 100)
  })
  const readinessPct = computed(() => {
    const total = categoryHealth.value.length
    if (total === 0) return 0
    return Math.round((categoriesReady.value.length / total) * 100)
  })

  const metricCards = computed(() => [
    { label: 'Nominierungen', value: totalNominations.value, note: 'eingereicht im Jahr', icon: Sparkles, tone: 'text-fuchsia-700 bg-fuchsia-50 border-fuchsia-100' },
    { label: 'Stimmen', value: totalVotes.value, note: 'gezählte Votes', icon: Vote, tone: 'text-violet-700 bg-violet-50 border-violet-100' },
    { label: 'Kandidaten', value: seasonDetail.value.candidates.length, note: 'freigegeben in Kategorien', icon: Users, tone: 'text-cyan-700 bg-cyan-50 border-cyan-100' },
    { label: 'Review-Backlog', value: seasonDetail.value.pendingNominations.length, note: 'offene Entscheidungen', icon: Clock3, tone: 'text-amber-700 bg-amber-50 border-amber-100' },
  ])

  const readinessCards = computed(() => [
    {
      label: 'Kategorie-Abdeckung',
      value: `${seasonDetail.value.categories.length - emptyCategories.value.length}/${seasonDetail.value.categories.length}`,
      note: emptyCategories.value.length === 0 ? 'Alle Kategorien haben Kandidaten.' : `${emptyCategories.value.length} Kategorien sind noch leer.`,
      icon: Tags,
      to: emptyCategories.value.length > 0
        ? `/admin/categories?group=${encodeURIComponent(emptyCategories.value[0]!.groupName)}`
        : '/admin/categories',
    },
    {
      label: 'Gewinnerstatus',
      value: `${winnerCoveragePct.value}%`,
      note: readinessScope.value.winnerWarningsActive
        ? `${seasonDetail.value.results.length} von ${seasonDetail.value.categories.length} Kategorien final gesetzt.`
        : 'Gewinner werden erst in Auswertung oder Show relevant.',
      icon: Trophy,
      to: categoriesWithoutWinner.value.length > 0
        ? `/admin/voting?status=issues&categoryId=${categoriesWithoutWinner.value[0]!.id}`
        : '/admin/winners?status=set',
    },
    {
      label: 'Freigabe-Risiko',
      value: String(categoriesWithReviews.value.length + pendingClipCount.value),
      note: readinessScope.value.reviewWarningsActive
        ? `${categoriesWithReviews.value.length} Kategorien mit Reviews, ${pendingClipCount.value} Clips offen.`
        : 'Noch Vorbereitungsstand, keine Freigabe-Warnung.',
      icon: AlertTriangle,
      to: categoriesWithReviews.value.length > 0
        ? `/admin/nominations?review=1&categoryId=${categoriesWithReviews.value[0]!.id}&status=heavy`
        : '/admin/clips?status=pending',
    },
  ])

  const insightCards = computed(() => {
    const votesPerCandidate = seasonDetail.value.candidates.length === 0 ? 0 : Math.round(totalVotes.value / seasonDetail.value.candidates.length)
    const busiestReviewCategory = categoriesWithReviews.value[0]
    const strongestCategory = topCategories.value[0]

    return [
      {
        label: 'Votes pro Kandidat',
        value: votesPerCandidate.toLocaleString('de-DE'),
        note: 'Zeigt, ob die Kandidatenbasis breit genug für die aktuelle Vote-Menge ist.',
        icon: Vote,
      },
      {
        label: 'Staerkste Kategorie',
        value: strongestCategory?.value.toLocaleString('de-DE') ?? '0',
        note: strongestCategory ? strongestCategory.category : 'Noch keine Vote-Verteilung vorhanden.',
        icon: CheckCircle2,
      },
      {
        label: 'Review-Hotspot',
        value: String(busiestReviewCategory?.reviews ?? 0),
        note: busiestReviewCategory ? busiestReviewCategory.name : 'Keine offenen Review-Hotspots.',
        icon: Clock3,
        to: busiestReviewCategory
          ? `/admin/nominations?review=1&categoryId=${busiestReviewCategory.id}&status=heavy`
          : '/admin/nominations?review=1',
      },
    ]
  })

  const attentionItems = computed(() => [
    {
      key: 'empty-categories',
      label: 'Leere Kategorien',
      value: emptyCategories.value.length,
      note: emptyCategories.value.length === 0 ? 'Keine Luecke in der Kandidatenbasis.' : emptyCategories.value.slice(0, 3).map((category) => category.name).join(', '),
      to: emptyCategories.value.length > 0
        ? `/admin/categories?group=${encodeURIComponent(emptyCategories.value[0]!.groupName)}`
        : '/admin/categories',
      tone: emptyCategories.value.length > 0 ? 'border-rose-100 bg-rose-50 text-rose-800' : 'border-emerald-100 bg-emerald-50 text-emerald-800',
    },
    {
      key: 'pending-reviews',
      label: 'Offene Reviews',
      value: seasonDetail.value.pendingNominations.length,
      note: categoriesWithReviews.value.length === 0
        ? 'Review-Queue ist leer.'
        : readinessScope.value.reviewWarningsActive
          ? `${categoriesWithReviews.value.length} Kategorien betroffen.`
          : 'Nominierungen laufen noch; Review ist eingeplant.',
      to: categoriesWithReviews.value.length > 0
        ? `/admin/nominations?review=1&categoryId=${categoriesWithReviews.value[0]!.id}&status=heavy`
        : '/admin/nominations?review=1',
      tone: seasonDetail.value.pendingNominations.length > 0 && readinessScope.value.reviewWarningsActive
        ? 'border-amber-100 bg-amber-50 text-amber-800'
        : seasonDetail.value.pendingNominations.length > 0
          ? 'border-violet-100 bg-violet-50 text-violet-800'
          : 'border-emerald-100 bg-emerald-50 text-emerald-800',
    },
    {
      key: 'missing-winners',
      label: readinessScope.value.winnerWarningsActive ? 'Gewinner fehlen' : 'Gewinner später',
      value: categoriesWithoutWinner.value.length,
      note: categoriesWithoutWinner.value.length === 0
        ? 'Alle Gewinner sind gesetzt.'
        : readinessScope.value.winnerWarningsActive
          ? 'Voting-Vorbereitung prüfen und danach final setzen.'
          : 'Für diese Phase noch kein Problem.',
      to: categoriesWithoutWinner.value.length > 0
        ? `/admin/voting?status=issues&categoryId=${categoriesWithoutWinner.value[0]!.id}`
        : '/admin/winners?status=set',
      tone: categoriesWithoutWinner.value.length > 0 && readinessScope.value.winnerWarningsActive
        ? 'border-sky-100 bg-sky-50 text-sky-800'
        : categoriesWithoutWinner.value.length > 0
          ? 'border-violet-100 bg-violet-50 text-violet-800'
          : 'border-emerald-100 bg-emerald-50 text-emerald-800',
    },
  ])

  // Top categories enriched with vote share %
  const topCategoriesEnriched = computed(() =>
    topCategories.value.map((cat) => ({
      ...cat,
      votes: cat.value,
      pct: totalVotes.value > 0 ? Math.round((cat.value / totalVotes.value) * 100) : 0,
      barWidth: totalVotes.value > 0 ? Math.max(2, Math.round((cat.value / maxVotes.value) * 100)) : 2,
    })),
  )

  // Health counts for status summary
  const healthSummary = computed(() => ({
    leer: emptyCategories.value.length,
    reviewOffen: categoriesWithReviews.value.length,
    bereit: categoryHealth.value.filter((c) => c.status === 'Bereit').length,
    gewinner: categoryHealth.value.filter((c) => c.status === 'Gewinner gesetzt').length,
    total: categoryHealth.value.length,
  }))

  return {
    categoryHealth,
    categoryGroups,
    metricCards,
    readinessCards,
    readinessScope,
    insightCards,
    attentionItems,
    topCategories,
    topCategoriesEnriched,
    maxVotes,
    winnerCoveragePct,
    readinessPct,
    healthSummary,
    totalVotes,
  }
}
