import { computed, onMounted, ref } from 'vue'
import { CheckCircle2, Database, FileText, Link2, ShieldCheck, Tags, UserRound } from '@lucide/vue'

import { getRiskMetricValue } from '../../lib/adminMetrics'
import { useAwardsStore } from '../../stores/awards'
import type { AdminSettingsCheckItem, AdminSettingsGateItem } from './adminSettingsTypes'

export function useAdminSettingsOverview() {
  const store = useAwardsStore()
  const healthLoading = ref(false)
  const healthError = ref('')
  const healthLoadedAt = ref<Date | null>(null)
  const seasonDetail = computed(() => store.adminSeasonDetail)
  const databaseHealth = computed(() => store.databaseHealth)
  const hasVotingPhase = computed(() => seasonDetail.value.currentPhase.toLowerCase().includes('voting'))
  const categoriesWithoutCandidates = computed(() =>
    seasonDetail.value.categories.filter((category) =>
      !seasonDetail.value.candidates.some((candidate) => candidate.categoryId === category.id),
    ),
  )
  const pendingClips = computed(() => seasonDetail.value.clipSubmissions.filter((clip) => clip.status === 'pending').length)
  const optionalFeatures = computed(() => store.adminOptionalFeatureSettings)
  const pendingMigrationCount = computed(() => databaseHealth.value.pendingMigrations.length)
  const openRiskCount = computed(() => getRiskMetricValue(store.admin.metrics))
  const healthLoadedLabel = computed(() =>
    healthLoadedAt.value ? healthLoadedAt.value.toLocaleString('de-DE', { dateStyle: 'short', timeStyle: 'short' }) : 'Noch nicht aktualisiert',
  )
  const siteSettings = computed(() => store.adminSiteSettings)
  const configuredFooterLinks = computed(() => [
    siteSettings.value.imprintUrl,
    siteSettings.value.contactUrl,
    siteSettings.value.sponsorsUrl,
    siteSettings.value.showactsUrl,
    siteSettings.value.newsletterUrl,
  ].filter((url) => url.trim()).length)
  const configuredFooterPages = computed(() => [
    siteSettings.value.imprintContent,
    siteSettings.value.contactContent,
    siteSettings.value.sponsorsContent,
    siteSettings.value.showactsContent,
  ].filter((content) => content.trim()).length)
  const contentChecks = computed<AdminSettingsCheckItem[]>(() => [
    {
      label: 'Host',
      value: Boolean(siteSettings.value.hostDisplayName.trim() && siteSettings.value.hostTagline.trim()),
      note: siteSettings.value.hostDisplayName.trim()
        ? siteSettings.value.hostTagline.trim() ? siteSettings.value.hostDisplayName.trim() : 'Host-Tagline fehlt'
        : 'Kein Host-Name hinterlegt',
      icon: UserRound,
      to: '/admin/content',
    },
    {
      label: 'Social Links',
      value: siteSettings.value.socialLinks.length > 0,
      note: `${siteSettings.value.socialLinks.length} Links gespeichert`,
      icon: Link2,
      to: '/admin/content',
    },
    {
      label: 'FAQ',
      value: siteSettings.value.faq.length > 0,
      note: `${siteSettings.value.faq.length} Fragen gespeichert`,
      icon: FileText,
      to: '/admin/content',
    },
    {
      label: 'Footer Links',
      value: configuredFooterLinks.value === 5 && configuredFooterPages.value === 4,
      note: `${configuredFooterLinks.value} von 5 Link-Zielen, ${configuredFooterPages.value} von 4 Footer-Seiten gepflegt`,
      icon: Link2,
      to: '/admin/content',
    },
    {
      label: 'Datenschutz',
      value: Boolean(siteSettings.value.privacyPolicyContent.trim() && siteSettings.value.privacyEmail.trim()),
      note: siteSettings.value.privacyPolicyUpdatedAt
        ? `Zuletzt aktualisiert: ${new Date(siteSettings.value.privacyPolicyUpdatedAt).toLocaleString('de-DE')}`
        : 'Datenschutztext oder Datenschutz-Mail fehlt',
      icon: ShieldCheck,
      to: '/admin/content',
    },
  ])
  const contentCompletion = computed(() => contentChecks.value.filter((check) => check.value).length)

  const checks = computed<AdminSettingsCheckItem[]>(() => [
    {
      label: 'Backend verbunden',
      value: store.apiMode === 'api',
      note: store.apiMode === 'api' ? 'Admin-Daten kommen aus der API.' : 'Fallback-Daten aktiv oder API nicht erreichbar.',
      icon: Database,
      to: null,
    },
    {
      label: 'Postgres verbunden',
      value: databaseHealth.value.canConnect,
      note: databaseHealth.value.canConnect
        ? `${databaseHealth.value.provider} erreichbar · Quelle: ${databaseHealth.value.configuredConnection.source}.`
        : databaseHealth.value.error || 'Datenbank ist nicht erreichbar.',
      icon: Database,
      to: null,
    },
    {
      label: 'Migrationen aktuell',
      value: databaseHealth.value.canConnect && pendingMigrationCount.value === 0,
      note: pendingMigrationCount.value === 0
        ? 'Keine ausstehenden Migrationen.'
        : `${pendingMigrationCount.value} Migrationen warten auf Anwendung.`,
      icon: CheckCircle2,
      to: null,
    },
    {
      label: 'Public-Jahr gesetzt',
      value: seasonDetail.value.isCurrent,
      note: seasonDetail.value.isCurrent ? `${seasonDetail.value.year} ist öffentlich markiert.` : 'Das gewählte Jahr ist aktuell intern.',
      icon: CheckCircle2,
      to: '/admin/years',
    },
    {
      label: 'Voting-Basis vollständig',
      value: categoriesWithoutCandidates.value.length === 0 && seasonDetail.value.categories.length > 0,
      note: categoriesWithoutCandidates.value.length === 0 ? 'Alle Kategorien haben Kandidaten.' : `${categoriesWithoutCandidates.value.length} Kategorien brauchen Kandidaten.`,
      icon: Tags,
      to: categoriesWithoutCandidates.value.length > 0
        ? `/admin/categories?group=${encodeURIComponent(categoriesWithoutCandidates.value[0]!.groupName)}`
        : '/admin/categories',
    },
    {
      label: 'Risiko-Queue leer',
      value: openRiskCount.value === 0,
      note: `${openRiskCount.value} offene Risikohinweise im Admin-Kontext.`,
      icon: ShieldCheck,
      to: '/admin/risk',
    },
  ])
  const gates = computed<AdminSettingsGateItem[]>(() => [
    {
      label: 'Nominierungsfenster',
      state: seasonDetail.value.currentPhase.toLowerCase().includes('nomin'),
      note: seasonDetail.value.currentPhase.toLowerCase().includes('nomin')
        ? 'Öffentliche Nominierung ist aktiv.'
        : 'Die aktuelle Phase erlaubt keine neuen Nominierungen.',
      to: '/admin/years',
    },
    {
      label: 'Voting freigeschaltet',
      state: hasVotingPhase.value && categoriesWithoutCandidates.value.length === 0,
      note: hasVotingPhase.value ? 'Phase ist Voting; Kategorie-Readiness entscheidet.' : 'Phase ist nicht Voting.',
      to: categoriesWithoutCandidates.value.length > 0
        ? `/admin/categories?group=${encodeURIComponent(categoriesWithoutCandidates.value[0]!.groupName)}`
        : '/admin/categories',
    },
    {
      label: 'Clip-Workflow',
      state: optionalFeatures.value.clipSubmissionsEnabled,
      note: optionalFeatures.value.clipSubmissionsEnabled
        ? 'Public-Clip-Einreichung ist aktiv.'
        : 'Public-Clip-Einreichung ist deaktiviert.',
      to: '/admin/settings',
    },
    {
      label: 'Clip-Inbox',
      state: pendingClips.value > 0,
      note: pendingClips.value > 0 ? `${pendingClips.value} Clip-Einreichungen offen.` : 'Keine offenen Clip-Einreichungen.',
      to: '/admin/clips?status=pending',
    },
    {
      label: 'Freitext-Reviews geklärt',
      state: seasonDetail.value.pendingNominations.length === 0,
      note: `${seasonDetail.value.pendingNominations.length} offene Freitext-Reviews.`,
      to: '/admin/nominations?review=1',
    },
  ])

  async function refreshDatabaseHealth() {
    healthLoading.value = true
    healthError.value = ''
    try {
      await store.loadDatabaseHealth()
      healthLoadedAt.value = new Date()
    } catch (error) {
      healthError.value = error instanceof Error ? error.message : 'Datenbank-Healthcheck konnte nicht geladen werden.'
    } finally {
      healthLoading.value = false
    }
  }

  onMounted(refreshDatabaseHealth)

  return {
    healthLoading,
    healthError,
    databaseHealth,
    pendingMigrationCount,
    healthLoadedLabel,
    contentChecks,
    contentCompletion,
    checks,
    gates,
    refreshDatabaseHealth,
  }
}
