<script setup lang="ts">
import { computed, onActivated, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { formatLocalMatchDateTime } from '@thebet365/shared';
import GoldSpinner from '../components/GoldSpinner.vue';
import defaultBannerImg from '../assets/images/banner.webp';
import { usePlayerHome, type PlayerContentItem } from '../composables/usePlayerHome';
import { sanitizeAnnouncementHtml, stripHtml } from '../utils/html';

const FALLBACK_IMG = '/uploads/banners/welcome.svg';

const route = useRoute();
const router = useRouter();
const { t, locale } = useI18n();
const { announcementItems, bannerItems, loading, load } = usePlayerHome();

const announcementId = computed(() => String(route.params.id ?? ''));

const item = computed<PlayerContentItem | null>(() => {
  const id = announcementId.value;
  return (
    bannerItems.value.find((entry) => entry.id === id) ??
    announcementItems.value.find((entry) => entry.id === id) ??
    null
  );
});

const isBanner = computed(() => item.value?.contentType === 'BANNER');

function goBack() {
  router.back();
}

function goList() {
  router.push('/announcements');
}

function formatDate(createdAt?: string) {
  if (!createdAt) return '';
  return formatLocalMatchDateTime(createdAt, locale.value, { variant: 'full' });
}

function itemTitle(entry: PlayerContentItem) {
  const title = entry.translation?.title?.trim();
  if (title) return title;
  const bodyText = stripHtml(entry.translation?.body ?? '');
  return bodyText || t('home.announcement_badge');
}

function itemBodyHtml(entry: PlayerContentItem) {
  const title = entry.translation?.title?.trim();
  const body = entry.translation?.body?.trim();
  if (!body) return '';
  if (title && stripHtml(body) === title) return '';
  return sanitizeAnnouncementHtml(body);
}

const heroImageUrl = computed(() => {
  const url = item.value?.translation?.imageUrl?.trim();
  if (url) return url;
  if (isBanner.value) return defaultBannerImg || FALLBACK_IMG;
  return '';
});

const linkTarget = computed(() => item.value?.linkTarget?.trim() ?? '');

const externalLinkUrl = computed(() => {
  if (item.value?.linkType !== 'URL' || !linkTarget.value) return '';
  return /^https?:\/\//i.test(linkTarget.value)
    ? linkTarget.value
    : `https://${linkTarget.value}`;
});

function onHeroError(e: Event) {
  const img = e.target as HTMLImageElement;
  if (img.dataset.fallbackApplied) return;
  img.dataset.fallbackApplied = '1';
  img.src = defaultBannerImg || FALLBACK_IMG;
}

function followRouteLink() {
  if (item.value?.linkType === 'ROUTE' && linkTarget.value) {
    void router.push(linkTarget.value);
  }
}

function openExternalLink() {
  if (externalLinkUrl.value) {
    window.open(externalLinkUrl.value, '_blank', 'noopener');
  }
}

async function refresh() {
  await load(true);
}

onActivated(() => {
  void refresh();
});

watch(announcementId, () => {
  if (!item.value && !loading.value) void refresh();
});
</script>

<template>
  <div class="announce-detail">
    <header class="page-header">
      <button type="button" class="back-btn" :aria-label="t('announcements.back')" @click="goBack">‹</button>
      <h1>{{ t('announcements.detail_title') }}</h1>
    </header>

    <div v-if="loading && !item" class="state">
      <GoldSpinner :size="36" />
    </div>

    <div v-else-if="!item" class="empty">
      <p>{{ t('announcements.not_found') }}</p>
      <button type="button" class="link-btn" @click="goList">{{ t('announcements.view_all') }}</button>
    </div>

    <article v-else class="detail-article">
      <figure v-if="heroImageUrl" class="detail-hero">
        <img :src="heroImageUrl" :alt="itemTitle(item)" loading="lazy" @error="onHeroError" />
      </figure>

      <div class="detail-body-wrap">
        <p v-if="item.createdAt" class="detail-date">{{ formatDate(item.createdAt) }}</p>
        <h2 class="detail-title">{{ itemTitle(item) }}</h2>
        <div v-if="itemBodyHtml(item)" class="detail-body" v-html="itemBodyHtml(item)" />

        <div v-if="item.linkType && linkTarget" class="detail-link">
          <p class="link-label">{{ t('announcements.related_link') }}</p>
          <p class="link-address">{{ linkTarget }}</p>
          <button
            v-if="item.linkType === 'ROUTE'"
            type="button"
            class="link-action"
            @click="followRouteLink"
          >
            {{ t('announcements.go_link') }}
          </button>
          <button
            v-else-if="item.linkType === 'URL'"
            type="button"
            class="link-action link-action--outline"
            @click="openExternalLink"
          >
            {{ t('announcements.open_link') }}
          </button>
        </div>
      </div>
    </article>
  </div>
</template>

<style scoped>
.announce-detail {
  min-height: 100%;
  padding: 0 0 24px;
}

.page-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 0 14px;
  margin-bottom: 0;
  border-bottom: 1px solid var(--border);
}

.back-btn {
  width: 36px;
  height: 36px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: #141414;
  color: var(--gold);
  font-size: 22px;
  line-height: 1;
}

.page-header h1 {
  margin: 0;
  font-size: 18px;
  font-weight: 700;
  color: #fff;
}

.state,
.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 48px 16px;
  color: var(--text-muted);
}

.link-btn {
  border: 1px solid var(--border-gold-soft);
  border-radius: 8px;
  padding: 8px 14px;
  background: rgba(212, 175, 55, 0.1);
  color: var(--gold);
  font-size: 13px;
  font-weight: 600;
}

.detail-article {
  margin: 0;
  padding: 0;
}

.detail-hero {
  margin: 16px -16px 0;
  padding: 0;
  background: #080808;
  line-height: 0;
}

.detail-hero img {
  width: 100%;
  height: auto;
  display: block;
  object-fit: contain;
  object-position: center;
}

.detail-body-wrap {
  padding: 18px 0 0;
}

.detail-date {
  margin: 0 0 10px;
  font-size: 12px;
  color: var(--text-muted);
}

.detail-title {
  margin: 0 0 12px;
  font-size: 20px;
  font-weight: 700;
  line-height: 1.45;
  color: #fff;
}

.detail-body {
  margin: 0;
  font-size: 15px;
  line-height: 1.75;
  color: #d0d0d0;
}

.detail-body :deep(p) {
  margin: 0 0 12px;
}

.detail-body :deep(p:last-child) {
  margin-bottom: 0;
}

.detail-body :deep(img) {
  max-width: 100%;
  height: auto;
  display: block;
  margin: 14px 0;
  border-radius: 8px;
}

.detail-body :deep(ul),
.detail-body :deep(ol) {
  margin: 0 0 12px;
  padding-left: 20px;
}

.detail-body :deep(a) {
  color: var(--primary-light);
  text-decoration: underline;
}

.detail-link {
  margin-top: 24px;
  padding-top: 18px;
  border-top: 1px solid var(--border);
}

.link-label {
  margin: 0 0 8px;
  font-size: 13px;
  color: var(--text-muted);
}

.link-address {
  margin: 0 0 14px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--primary-light);
  word-break: break-all;
}

.link-action {
  width: 100%;
  padding: 11px 14px;
  border: none;
  border-radius: 8px;
  background: var(--gradient-gold);
  color: #1a1000;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}

.link-action--outline {
  background: transparent;
  border: 1px solid var(--border-gold-soft);
  color: var(--gold);
}
</style>
