<template>
  <div class="min-h-full">
    <div
      v-if="canCustomizeHome"
      class="fixed right-4 bottom-14 z-[60]"
    >
      <button
        type="button"
        class="w-9 h-9 rounded-full bg-white border border-gray-200 shadow-sm hover:shadow-md hover:bg-gray-50 flex items-center justify-center text-gray-700"
        :title="editorOpen ? 'Startseiteneditor schließen' : 'Startseiteneditor öffnen'"
        @click="editorOpen ? closeEditor() : openEditor()"
      >
        <X
          v-if="editorOpen"
          :size="15"
        />
        <SlidersHorizontal
          v-else
          :size="15"
        />
      </button>
    </div>

    <div
      v-if="editorOpen"
      class="fixed right-4 bottom-28 z-[60] w-[min(92vw,30rem)] bg-white border border-gray-200 rounded-xl shadow-xl p-4"
    >
      <div class="flex items-center justify-between gap-3 mb-3">
        <h2 class="text-base font-semibold text-gray-900">
          Startseiteneditor
        </h2>
      </div>

      <p class="text-xs text-gray-500 mb-3">
        {{ isLoggedIn ? 'Einstellungen werden serverseitig für deinen Nutzer gespeichert.' : 'Einstellungen werden nur im Browser-Cookie gespeichert.' }}
      </p>

      <div
        v-if="editorSections.length === 0"
        class="text-sm text-gray-600"
      >
        Keine Elemente zur Konfiguration gefunden.
      </div>

      <div
        v-else
        class="space-y-2 max-h-[50vh] overflow-auto pr-1"
      >
        <div
          v-for="(section, index) in editorSections"
          :key="section.key"
          class="p-3 border border-gray-200 rounded-lg bg-gray-50"
        >
          <div class="flex items-start gap-3">
            <div class="flex-1 min-w-0">
              <div class="font-medium text-gray-900 truncate">
                {{ getSectionLabel(section) }}
              </div>
              <div class="text-xs text-gray-500 truncate">
                {{ section.id }}
              </div>
            </div>

            <div class="flex items-center gap-1">
              <button
                type="button"
                class="px-2 py-1 text-xs rounded border border-gray-300 bg-white disabled:opacity-50"
                :disabled="index === 0 || isSavingSettings"
                @click="moveEditorSectionUp(index)"
              >
                Hoch
              </button>
              <button
                type="button"
                class="px-2 py-1 text-xs rounded border border-gray-300 bg-white disabled:opacity-50"
                :disabled="index === editorSections.length - 1 || isSavingSettings"
                @click="moveEditorSectionDown(index)"
              >
                Runter
              </button>
            </div>

            <label class="flex items-center gap-2 text-sm text-gray-700">
              <input
                v-model="section.enabled"
                type="checkbox"
                :disabled="isSavingSettings"
              >
              Anzeigen
            </label>
          </div>

          <div
            v-if="section.id === 'spielplan_team'"
            class="mt-3 grid grid-cols-1 gap-2"
          >
            <div>
              <label class="text-xs text-gray-500">Saison</label>
              <select
                :value="section.config?.season || ''"
                class="mt-1 w-full px-2 py-1.5 text-sm border border-gray-300 rounded bg-white"
                :disabled="isSavingSettings || widgetOptionsLoading"
                @change="onWidgetSeasonChanged(section, $event.target.value)"
              >
                <option
                  v-for="season in spielplanSeasons"
                  :key="season.slug"
                  :value="season.slug"
                >
                  {{ season.label }}
                </option>
              </select>
            </div>

            <div>
              <label class="text-xs text-gray-500">Mannschaft</label>
              <select
                :value="teamKeyFromConfig(section.config)"
                class="mt-1 w-full px-2 py-1.5 text-sm border border-gray-300 rounded bg-white"
                :disabled="isSavingSettings || widgetOptionsLoading"
                @change="onWidgetTeamChanged(section, $event.target.value)"
              >
                <option
                  v-for="team in getTeamsForSeason(section.config?.season)"
                  :key="team.key"
                  :value="team.key"
                >
                  {{ team.label }}
                </option>
              </select>
            </div>
          </div>
        </div>
      </div>

      <div class="mt-4 pt-4 border-t border-gray-200">
        <p class="text-sm font-semibold text-gray-900 mb-2">
          Widget hinzufügen
        </p>
        <p class="text-xs text-gray-500 mb-3">
          Spielplan-Widget für eine konkrete Mannschaft und Saison.
        </p>

        <div class="grid grid-cols-1 gap-2">
          <div>
            <label class="text-xs text-gray-500">Saison</label>
            <select
              v-model="newWidgetSeason"
              class="mt-1 w-full px-2 py-1.5 text-sm border border-gray-300 rounded bg-white"
              :disabled="widgetOptionsLoading"
              @change="onNewWidgetSeasonChanged"
            >
              <option
                v-for="season in spielplanSeasons"
                :key="season.slug"
                :value="season.slug"
              >
                {{ season.label }}
              </option>
            </select>
          </div>

          <div>
            <label class="text-xs text-gray-500">Mannschaft</label>
            <select
              v-model="newWidgetTeamKey"
              class="mt-1 w-full px-2 py-1.5 text-sm border border-gray-300 rounded bg-white"
              :disabled="widgetOptionsLoading"
            >
              <option
                v-for="team in newWidgetTeams"
                :key="team.key"
                :value="team.key"
              >
                {{ team.label }}
              </option>
            </select>
          </div>
        </div>

        <button
          type="button"
          class="mt-3 px-3 py-2 text-sm rounded-lg border border-primary-300 text-primary-700 hover:bg-primary-50 disabled:opacity-50"
          :disabled="!canAddSpielplanWidget || isSavingSettings"
          @click="addSpielplanWidget"
        >
          Spielplan-Widget hinzufügen
        </button>
      </div>

      <div class="mt-4 flex items-center gap-3">
        <button
          type="button"
          class="px-3 py-2 text-sm rounded-lg bg-primary-600 hover:bg-primary-700 text-white disabled:opacity-50"
          :disabled="isSavingSettings || editorSections.length === 0"
          @click="saveEditor"
        >
          {{ isSavingSettings ? 'Speichert...' : 'Speichern' }}
        </button>
        <p
          v-if="editorMessage"
          class="text-sm"
          :class="editorMessageType === 'error' ? 'text-red-700' : 'text-green-700'"
        >
          {{ editorMessage }}
        </p>
      </div>
    </div>

    <template
      v-for="section in enabledSections"
      :key="section.key"
    >
      <HomeSpielplanTeamWidget
        v-if="section.id === 'spielplan_team'"
        :season="section.config?.season"
        :team-name="section.config?.teamName"
        :team-age-group="section.config?.teamAgeGroup"
      />
      <component
        :is="getComponentForSection(section.id)"
        v-else
      />
    </template>
  </div>
</template>

<script setup>
import { computed, defineAsyncComponent, ref } from 'vue'
import { SlidersHorizontal, X } from 'lucide-vue-next'
import Hero from '~/components/Hero.vue'
const HomeTermine = defineAsyncComponent(() => import('~/components/HomeTermine.vue'))
const Spielplan = defineAsyncComponent(() => import('~/components/Spielplan.vue'))
const PublicNews = defineAsyncComponent(() => import('~/components/PublicNews.vue'))
const HomeActions = defineAsyncComponent(() => import('~/components/HomeActions.vue'))
const HomeTrainingTeaser = defineAsyncComponent(() => import('~/components/HomeTrainingTeaser.vue'))
const HomeLinksTeaser = defineAsyncComponent(() => import('~/components/HomeLinksTeaser.vue'))
const HomeVereinsmeisterschaftenTeaser = defineAsyncComponent(() => import('~/components/HomeVereinsmeisterschaftenTeaser.vue'))
const HomeSpielplanTeamWidget = defineAsyncComponent(() => import('~/components/HomeSpielplanTeamWidget.vue'))

const { data: config } = await useFetch('/api/config')
const { data: authStatus } = await useFetch('/api/auth/status')
const { data: homepageSettings, refresh: refreshHomepageSettings } = await useFetch('/api/homepage/settings')

const editorOpen = ref(false)
const editorSections = ref([])
const isSavingSettings = ref(false)
const editorMessage = ref('')
const editorMessageType = ref('success')
const widgetOptionsLoading = ref(false)
const spielplanSeasons = ref([])
const teamOptionsBySeason = ref({})
const newWidgetSeason = ref('')
const newWidgetTeamKey = ref('')

const baseSectionDefinitions = [
  { id: 'banner', enabled: true },
  { id: 'termine', enabled: true },
  { id: 'spiele', enabled: true },
  { id: 'aktuelles', enabled: true },
  { id: 'kontakt', enabled: true },
  { id: 'training', enabled: false },
  { id: 'links', enabled: false },
  { id: 'vereinsmeisterschaften', enabled: false }
]
const baseSectionIds = new Set(baseSectionDefinitions.map(section => section.id))

function createEntryKey(id) {
  return `${id}_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
}

function normalizeConfig(config) {
  if (!config || typeof config !== 'object') return undefined
  const normalized = {
    season: config.season ? String(config.season) : '',
    teamName: config.teamName ? String(config.teamName) : '',
    teamAgeGroup: config.teamAgeGroup ? String(config.teamAgeGroup) : ''
  }
  if (!normalized.season && !normalized.teamName && !normalized.teamAgeGroup) {
    return undefined
  }
  return normalized
}

function normalizeEntry(entry, index, fallbackId = '') {
  const id = String(entry?.id || fallbackId || '').trim()
  if (!id) return null
  return {
    key: entry?.key ? String(entry.key) : `${id}-${index}`,
    id,
    enabled: entry?.enabled !== false,
    config: normalizeConfig(entry?.config)
  }
}

function normalizeSectionList(rawSections) {
  const incoming = Array.isArray(rawSections) ? rawSections : []
  const sanitized = incoming
    .map((section, index) => normalizeEntry(section, index))
    .filter(Boolean)

  if (sanitized.length === 0) {
    return baseSectionDefinitions.map((section, index) => normalizeEntry(
      { ...section, key: `base-${section.id}` },
      index,
      section.id
    ))
  }

  const knownIds = new Set(sanitized.map(section => section.id))
  const merged = [...sanitized]
  for (const defaultSection of baseSectionDefinitions) {
    if (!knownIds.has(defaultSection.id)) {
      merged.push(normalizeEntry(
        { ...defaultSection, key: `base-${defaultSection.id}` },
        merged.length,
        defaultSection.id
      ))
    }
  }

  return merged
}

const sections = computed(() => normalizeSectionList(config.value?.homepage?.sections))
const personalizedSections = computed(() => {
  const raw = homepageSettings.value?.sections
  const list = Array.isArray(raw) ? raw : []
  return list.map((section, index) => normalizeEntry(section, index)).filter(Boolean)
})

const isLoggedIn = computed(() => authStatus.value?.isLoggedIn === true)
const canCustomizeHome = computed(() => sections.value.length > 0)

function applyPersonalization(baseSections, settingsSections) {
  if (!settingsSections.length) return baseSections

  const presentBaseIds = new Set(
    settingsSections.filter(section => baseSectionIds.has(section.id)).map(section => section.id)
  )
  const missingBaseSections = baseSections.filter(section => !presentBaseIds.has(section.id))
  return [...settingsSections, ...missingBaseSections]
}

const resolvedSections = computed(() => applyPersonalization([...sections.value], personalizedSections.value))
const enabledSections = computed(() => resolvedSections.value.filter(section => section.enabled !== false))

const componentMap = {
  banner: Hero,
  termine: HomeTermine,
  spiele: Spielplan,
  aktuelles: PublicNews,
  kontakt: HomeActions,
  training: HomeTrainingTeaser,
  links: HomeLinksTeaser,
  vereinsmeisterschaften: HomeVereinsmeisterschaftenTeaser
}

function getComponentForSection(sectionId) {
  return componentMap[sectionId] || null
}

function getSectionLabel(section) {
  if (section.id === 'spielplan_team') {
    if (!section.config?.teamName) return 'Spielplan-Widget'
    return `Spielplan: ${section.config.teamName}`
  }

  const labels = {
    banner: 'Banner (Willkommen)',
    termine: 'Kommende Termine',
    spiele: 'Nächste Spiele',
    aktuelles: 'Aktuelles',
    kontakt: 'Kontakt-Boxen',
    training: 'Training-Teaser',
    links: 'Links-Teaser',
    vereinsmeisterschaften: 'Vereinsmeisterschaften-Teaser'
  }
  return labels[section.id] || section.id
}

function getTeamsForSeason(seasonSlug) {
  if (!seasonSlug) return []
  return teamOptionsBySeason.value[seasonSlug] || []
}

function teamKeyFromConfig(config) {
  if (!config?.teamName) return ''
  return `${config.teamName}||${config.teamAgeGroup || ''}`
}

function applyTeamToSectionConfig(section, teamKey) {
  const season = section.config?.season || ''
  const teams = getTeamsForSeason(season)
  const team = teams.find(item => item.key === teamKey)
  if (!team) return
  section.config = {
    ...section.config,
    season,
    teamName: team.teamName,
    teamAgeGroup: team.teamAgeGroup || ''
  }
}

async function ensureTeamOptions(seasonSlug) {
  if (!seasonSlug || teamOptionsBySeason.value[seasonSlug]) return
  const result = await $fetch('/api/homepage/spielplan-options', {
    query: { season: seasonSlug }
  })
  teamOptionsBySeason.value = {
    ...teamOptionsBySeason.value,
    [seasonSlug]: result?.teams || []
  }
  if (!spielplanSeasons.value.length && Array.isArray(result?.seasons)) {
    spielplanSeasons.value = result.seasons
  }
}

async function loadWidgetOptions() {
  if (widgetOptionsLoading.value) return
  widgetOptionsLoading.value = true
  try {
    const result = await $fetch('/api/homepage/spielplan-options')
    spielplanSeasons.value = Array.isArray(result?.seasons) ? result.seasons : []

    const selectedSeason = result?.selectedSeason || spielplanSeasons.value[0]?.slug || ''
    if (selectedSeason) {
      teamOptionsBySeason.value = {
        ...teamOptionsBySeason.value,
        [selectedSeason]: result?.teams || []
      }
    }

    if (!newWidgetSeason.value) {
      newWidgetSeason.value = selectedSeason
    }
    if (newWidgetSeason.value) {
      await ensureTeamOptions(newWidgetSeason.value)
      const teams = getTeamsForSeason(newWidgetSeason.value)
      if (teams.length && !newWidgetTeamKey.value) {
        newWidgetTeamKey.value = teams[0].key
      }
    }
  } finally {
    widgetOptionsLoading.value = false
  }
}

async function openEditor() {
  editorMessage.value = ''
  editorSections.value = resolvedSections.value.map(section => ({
    key: section.key,
    id: section.id,
    enabled: section.enabled !== false,
    config: normalizeConfig(section.config)
  }))

  await loadWidgetOptions()

  for (const section of editorSections.value.filter(item => item.id === 'spielplan_team')) {
    const fallbackSeason = section.config?.season || newWidgetSeason.value || spielplanSeasons.value[0]?.slug || ''
    if (!section.config) section.config = {}
    section.config.season = fallbackSeason
    await ensureTeamOptions(fallbackSeason)
    const currentTeamKey = teamKeyFromConfig(section.config)
    const availableTeams = getTeamsForSeason(fallbackSeason)
    if (availableTeams.length && !availableTeams.find(item => item.key === currentTeamKey)) {
      applyTeamToSectionConfig(section, availableTeams[0].key)
    }
  }

  editorOpen.value = true
}

function closeEditor() {
  editorOpen.value = false
  editorMessage.value = ''
}

function moveEditorSectionUp(index) {
  if (index <= 0) return
  const item = editorSections.value[index]
  editorSections.value.splice(index, 1)
  editorSections.value.splice(index - 1, 0, item)
}

function moveEditorSectionDown(index) {
  if (index >= editorSections.value.length - 1) return
  const item = editorSections.value[index]
  editorSections.value.splice(index, 1)
  editorSections.value.splice(index + 1, 0, item)
}

async function onWidgetSeasonChanged(section, seasonSlug) {
  if (!section.config) section.config = {}
  section.config.season = seasonSlug
  await ensureTeamOptions(seasonSlug)
  const teams = getTeamsForSeason(seasonSlug)
  const currentTeamKey = teamKeyFromConfig(section.config)
  if (teams.length && !teams.find(item => item.key === currentTeamKey)) {
    applyTeamToSectionConfig(section, teams[0].key)
  }
}

function onWidgetTeamChanged(section, teamKey) {
  applyTeamToSectionConfig(section, teamKey)
}

const newWidgetTeams = computed(() => getTeamsForSeason(newWidgetSeason.value))
const canAddSpielplanWidget = computed(() => !!newWidgetSeason.value && !!newWidgetTeamKey.value)

async function onNewWidgetSeasonChanged() {
  await ensureTeamOptions(newWidgetSeason.value)
  const teams = getTeamsForSeason(newWidgetSeason.value)
  newWidgetTeamKey.value = teams[0]?.key || ''
}

function addSpielplanWidget() {
  const teams = getTeamsForSeason(newWidgetSeason.value)
  const selectedTeam = teams.find(team => team.key === newWidgetTeamKey.value)
  if (!selectedTeam) return

  editorSections.value.push({
    key: createEntryKey('spielplan_team'),
    id: 'spielplan_team',
    enabled: true,
    config: {
      season: newWidgetSeason.value,
      teamName: selectedTeam.teamName,
      teamAgeGroup: selectedTeam.teamAgeGroup || ''
    }
  })
}

async function saveEditor() {
  isSavingSettings.value = true
  editorMessage.value = ''

  try {
    await $fetch('/api/homepage/settings', {
      method: 'PUT',
      body: {
        sections: editorSections.value.map((section, index) => ({
          key: section.key || `${section.id}-${index}`,
          id: section.id,
          enabled: section.enabled !== false,
          config: normalizeConfig(section.config)
        }))
      }
    })

    await refreshHomepageSettings()
    editorMessageType.value = 'success'
    editorMessage.value = 'Startseiten-Einstellungen gespeichert.'
  } catch (error) {
    editorMessageType.value = 'error'
    editorMessage.value = error?.data?.message || 'Speichern fehlgeschlagen.'
  } finally {
    isSavingSettings.value = false
  }
}
</script>
