import { computed, onBeforeUnmount, ref, type ComputedRef, type Ref } from 'vue' import type { HomeDisplayCategory, HomePreviewPhase } from './homeLandingTypes' export function useHomePhasePresentation(params: { previewPhase: Ref displayCategories: ComputedRef candidateCount: ComputedRef publicStreamUrl: ComputedRef showDate: ComputedRef showStartsAt: ComputedRef currentYear: ComputedRef formatRange: (key: 'nomination' | 'voting' | 'preparation') => string formatShowDate: () => string }) { const { previewPhase, displayCategories, candidateCount, publicStreamUrl, showDate, showStartsAt, currentYear, formatRange, formatShowDate, } = params const nominationPhase = computed(() => previewPhase.value === 'nomination') const votingPhase = computed(() => previewPhase.value === 'voting') const preparationPhase = computed(() => previewPhase.value === 'preparation') const showPhase = computed(() => previewPhase.value === 'show') const completedPhase = computed(() => previewPhase.value === 'completed') const currentTimestamp = ref(Date.now()) const ticker = setInterval(() => { currentTimestamp.value = Date.now() }, 1000) onBeforeUnmount(() => clearInterval(ticker)) const showCountdown = computed(() => true) const showStartMs = computed(() => parseShowStartMs(showDate.value, showStartsAt.value)) const streamLive = computed(() => showPhase.value && !Number.isNaN(showStartMs.value) && currentTimestamp.value >= showStartMs.value) const streamLocked = computed(() => !streamLive.value) const phaseCardTitle = computed(() => completedPhase.value ? 'Award-Jahr abgeschlossen' : nominationPhase.value ? 'Community Nominierung' : votingPhase.value ? 'Community Voting' : preparationPhase.value ? 'Aufbereitung bis zur Show' : 'Award Show Live') const phaseCardDescription = computed(() => completedPhase.value ? 'Die grosse Award-Show ist beendet. Das Jahr ist abgeschlossen und alle Teilnahme-Aktionen sind gesperrt.' : nominationPhase.value ? 'Die Nominierungsphase läuft gerade. Reiche deine Favoriten und Highlight-Clips ein.' : votingPhase.value ? 'Die Nominierungsphase ist abgeschlossen.\nJetzt liegt es an dir: Stimme für deine Favoriten!' : preparationPhase.value ? 'Das Voting ist abgeschlossen. Das Team bereitet Clips, Ablauf und Gewinner-Momente für die Show vor.' : 'Die Award-Show läuft jetzt live. Zeit für Bühne, Gewinner:innen und ganz viel Glitzer.') const phaseCardRange = computed(() => completedPhase.value ? `Finale abgeschlossen · ${formatShowDate()}` : nominationPhase.value ? `Nominierungszeitraum · ${formatRange('nomination')}` : votingPhase.value ? `Voting-Zeitraum · ${formatRange('voting')}` : preparationPhase.value ? `Aufbereitungszeit · ${formatRange('preparation')}` : `Live · ${formatShowDate()} · ${formatTimeLabel(showStartsAt.value)} Uhr`) const phaseStatusLabel = computed(() => completedPhase.value ? 'ABGESCHLOSSEN' : streamLive.value ? 'LIVE' : showPhase.value ? 'STARTET BALD' : preparationPhase.value ? 'IN AUFBEREITUNG' : 'AKTIV') const phaseStatusStyle = computed(() => completedPhase.value ? 'display:inline-flex;align-items:center;gap:5px;padding:4px 11px;border-radius:999px;background:#f1ecfb;color:#8b6cdb;font-size:11px;font-weight:700;letter-spacing:.5px;' : showPhase.value ? 'display:inline-flex;align-items:center;gap:5px;padding:4px 11px;border-radius:999px;background:#ffe5ec;color:#ec3b5a;font-size:11px;font-weight:700;letter-spacing:.5px;' : preparationPhase.value ? 'display:inline-flex;align-items:center;gap:5px;padding:4px 11px;border-radius:999px;background:#fff1d6;color:#b7791f;font-size:11px;font-weight:700;letter-spacing:.5px;' : 'display:inline-flex;align-items:center;gap:5px;padding:4px 11px;border-radius:999px;background:#e3f7ec;color:#1f9d5a;font-size:11px;font-weight:700;letter-spacing:.5px;') const phasePrimaryLabel = computed(() => completedPhase.value ? '✦ Award beendet' : nominationPhase.value ? '✦ Nominieren & Clip' : votingPhase.value ? '★ Jetzt voten' : preparationPhase.value ? '✦ Show wird vorbereitet' : '● Zum Live-Stream') const phasePrimaryDisabled = computed(() => preparationPhase.value || completedPhase.value) const phasePrimaryActionStyle = computed(() => phasePrimaryDisabled.value ? 'display:flex;align-items:center;justify-content:center;gap:8px;width:100%;padding:15px 18px;border-radius:13px;background:#eee7f8;color:#9b8abf;border:none;text-decoration:none;font-family:\'Outfit\',sans-serif;font-weight:600;font-size:15px;box-shadow:none;cursor:not-allowed;' : 'display:flex;align-items:center;justify-content:center;gap:8px;width:100%;padding:15px 18px;border-radius:13px;background:linear-gradient(135deg,#8b6cdb,#7355c8);color:#fff;border:none;text-decoration:none;font-family:\'Outfit\',sans-serif;font-weight:600;font-size:15px;box-shadow:0 10px 22px rgba(124,86,196,.32);cursor:pointer;') const streamEyebrow = computed(() => 'Das grosse Finale') const streamTitle = computed(() => 'Award-Show Countdown') const streamMeta = computed(() => `Finale am ${formatShowDate()} · ${formatTimeLabel(showStartsAt.value)} Uhr`) const streamLockedLabel = computed(() => completedPhase.value ? 'Award abgeschlossen' : 'Stream noch gesperrt') const streamLockedTitle = computed(() => completedPhase.value ? 'Die Award-Show ist beendet' : 'Verfügbar, sobald die Show startet') const statOneValue = computed(() => completedPhase.value ? 'DONE' : streamLive.value ? 'LIVE' : String(candidateCount.value)) const statOneLabel = computed(() => completedPhase.value ? 'Jahr-Status' : showPhase.value ? 'Show-Status' : 'Kandidat:innen') const statTwoValue = computed(() => String(displayCategories.value.length)) const statThreeValue = computed(() => currentYear.value || '—') const statThreeLabel = computed(() => 'Award-Jahr') const categoryIntroText = computed(() => { const count = displayCategories.value.length const countLabel = count === 1 ? 'Eine Kategorie' : `${count || 'Alle'} Kategorien` return `${countLabel}, eine Show, eine Szene. Stimm für deine Lieblings-VTuber ab und sei live dabei, wenn die Gewinner feststehen.` }) const timelineLineStyle = computed(() => nominationPhase.value ? 'position:absolute;top:27px;left:10%;right:10%;height:3px;background:linear-gradient(90deg,#e2d6f4 0%,#e2d6f4 100%);border-radius:3px;z-index:0;' : votingPhase.value ? 'position:absolute;top:27px;left:10%;right:10%;height:3px;background:linear-gradient(90deg,#8b6cdb 0%,#8b6cdb 33.33%,#e2d6f4 33.33%,#e2d6f4 100%);border-radius:3px;z-index:0;' : preparationPhase.value ? 'position:absolute;top:27px;left:10%;right:10%;height:3px;background:linear-gradient(90deg,#8b6cdb 0%,#8b6cdb 66.66%,#e2d6f4 66.66%,#e2d6f4 100%);border-radius:3px;z-index:0;' : 'position:absolute;top:27px;left:10%;right:10%;height:3px;background:linear-gradient(90deg,#8b6cdb 0%,#8b6cdb 100%,#e2d6f4 100%,#e2d6f4 100%);border-radius:3px;z-index:0;') const sectionTitle = computed(() => completedPhase.value ? 'Das Award-Jahr ist abgeschlossen ✦' : nominationPhase.value ? 'Jetzt Highlights und Favoriten einreichen ✦' : votingPhase.value ? 'Meine Favoriten unterstützen ⭐' : preparationPhase.value ? 'Die Show wird vorbereitet ✦' : 'Die Gewinner werden jetzt live gekürt ✦') const sectionText = computed(() => completedPhase.value ? 'Danke an alle, die nominiert, abgestimmt und live mitgefiebert haben. Die nächsten Aktionen sind gesperrt, bis ein neues Award-Jahr startet.' : nominationPhase.value ? 'Reiche deine Lieblingsmomente ein und hilf mit, die stärksten Clips und spannendsten Namen in die Show zu bringen.' : votingPhase.value ? 'Jede Stimme erzählt eine Geschichte. Unterstütze die Creator, die dich zum Lachen, Staunen und Mitfiebern bringen.' : preparationPhase.value ? 'Die Community hat abgestimmt. Jetzt bereitet das Team Clips, Ablauf und Show-Momente für die Award-Nacht vor.' : 'Die Bühne ist offen. Schau live zu, wie die Stars der Szene ausgezeichnet werden und die besten Momente gezeigt werden.') const sectionActionLabel = computed(() => completedPhase.value ? 'Award-Jahr abgeschlossen' : nominationPhase.value ? 'Nominieren & Clip einreichen' : votingPhase.value ? 'Mit Twitch anmelden & voten' : preparationPhase.value ? 'Aufbereitung läuft' : 'Zum Live-Stream') const sectionActionHref = computed(() => showPhase.value ? publicStreamUrl.value : '#') const sectionActionDisabled = computed(() => preparationPhase.value || completedPhase.value) const sectionActionStyle = computed(() => sectionActionDisabled.value ? 'display:inline-flex;align-items:center;gap:11px;padding:17px 38px;border-radius:14px;background:rgba(255,255,255,.72);color:#9b8abf;text-decoration:none;font-family:\'Outfit\',sans-serif;font-weight:700;font-size:18px;box-shadow:none;cursor:not-allowed;border:none;' : nominationPhase.value ? 'display:inline-flex;align-items:center;gap:11px;padding:17px 38px;border-radius:14px;background:#fff;color:#e855a5;text-decoration:none;font-family:\'Outfit\',sans-serif;font-weight:700;font-size:18px;box-shadow:0 14px 34px rgba(0,0,0,.22);' : 'display:inline-flex;align-items:center;gap:11px;padding:17px 38px;border-radius:14px;background:#fff;color:#7a3fd0;text-decoration:none;font-family:\'Outfit\',sans-serif;font-weight:700;font-size:18px;box-shadow:0 14px 34px rgba(0,0,0,.22);') return { nominationPhase, votingPhase, preparationPhase, showPhase, completedPhase, showCountdown, streamLive, streamLocked, phaseCardTitle, phaseCardDescription, phaseCardRange, phaseStatusLabel, phaseStatusStyle, phasePrimaryLabel, phasePrimaryDisabled, phasePrimaryActionStyle, streamEyebrow, streamTitle, streamMeta, streamLockedLabel, streamLockedTitle, statOneValue, statOneLabel, statTwoValue, statThreeValue, statThreeLabel, categoryIntroText, timelineLineStyle, sectionTitle, sectionText, sectionActionLabel, sectionActionHref, sectionActionDisabled, sectionActionStyle, } } function parseShowStartMs(showDate: string, showStartsAt: string) { if (!showDate) return Number.NaN const time = normalizeTime(showStartsAt) return new Date(`${showDate}T${time}`).getTime() } function normalizeTime(value: string) { if (!value) return '20:00:00' return value.length === 5 ? `${value}:00` : value } function formatTimeLabel(value: string) { return normalizeTime(value).slice(0, 5) }