import { computed, reactive, ref, watch } from 'vue'

import {
  normalizeSocialIconKey,
  simpleIconForKey,
  socialIconOptionForKey,
} from '../../lib/socialIcons'
import {
  plainTextContentForStorage,
  plainTextContentFromStorage,
  privacyContentForStorage,
  privacyContentToHtml,
} from '../../lib/privacyContent'
import { useAwardsStore } from '../../stores/awards'
import type { ShowactFormField } from '../../types/awards/showactForm'
import { DEFAULT_SHOWACT_SCHEMA } from '../../types/awards/showactForm'
import type { AdminContentForm, SocialLinkForm } from './adminContentTypes'

function parseShowactSchema(json: string): ShowactFormField[] {
  try {
    const parsed = JSON.parse(json)
    if (Array.isArray(parsed) && parsed.length > 0) return parsed as ShowactFormField[]
  } catch {
    // ignore parse errors
  }
  return DEFAULT_SHOWACT_SCHEMA
}

function createEmptyForm(): AdminContentForm {
  return {
    hostDisplayName: '',
    hostTagline: '',
    hostArtistName: '',
    hostImageUrl: '/assets/amaterasu2sei_2.png',
    newsletterUrl: '',
    shareXUrl: '',
    shareDiscordUrl: '',
    privacyEmail: '',
    privacyPolicyContent: '',
    imprintUrl: '',
    imprintContent: '',
    contactUrl: '',
    contactContent: '',
    sponsorsUrl: '',
    sponsorsContent: '',
    showactsUrl: '',
    showactsContent: '',
    streamBannerEyebrow: 'Das große Finale',
    streamBannerTitle: 'Award-Show Finale',
    streamBannerText: 'Finale, Countdown und Stream-Link an einem Ort. Sei live dabei, wenn die Community ihre Stars feiert.',
    streamBannerLiveButtonLabel: 'Jetzt live · Zum Stream',
    streamBannerLiveButtonUrl: '',
    streamBannerLockedButtonLabel: 'Stream noch gesperrt',
    streamBannerUseCompletedContent: false,
    streamBannerCompletedEyebrow: 'Danke fürs Mitfiebern',
    streamBannerCompletedTitle: 'Award-Show abgeschlossen',
    streamBannerCompletedText: 'Die große Award-Show ist vorbei. Danke an alle, die nominiert, gevotet und live mitgefiebert haben.',
    streamBannerCompletedButtonLabel: 'Highlights ansehen',
    streamBannerCompletedButtonUrl: '',
    awardsSectionTitle: '',
    awardsSectionDescription: '',
    subcategoriesSectionTitle: '',
    subcategoriesSectionDescription: '',
    socialLinks: [],
    faq: [],
    showactFormSchema: [],
  }
}

function readFileAsDataUrl(file: File) {
  return new Promise<string>((resolve, reject) => {
    const reader = new FileReader()
    reader.onload = () => resolve(String(reader.result ?? ''))
    reader.onerror = () => reject(new Error('Icon konnte nicht gelesen werden.'))
    reader.readAsDataURL(file)
  })
}

async function validateRasterDimensions(file: File) {
  if (file.type === 'image/svg+xml') {
    return
  }

  const objectUrl = URL.createObjectURL(file)
  try {
    await new Promise<void>((resolve, reject) => {
      const image = new Image()
      image.onload = () => {
        if (image.naturalWidth > 512 || image.naturalHeight > 512) {
          reject(new Error('Icon ist zu groß. Maximal erlaubt sind 512 x 512 px.'))
          return
        }
        resolve()
      }
      image.onerror = () => reject(new Error('Icon-Abmessungen konnten nicht geprüft werden.'))
      image.src = objectUrl
    })
  } finally {
    URL.revokeObjectURL(objectUrl)
  }
}

export function useAdminContentManager() {
  const store = useAwardsStore()
  const form = reactive(createEmptyForm())
  const saving = ref(false)
  const saveMessage = ref('')
  const saveError = ref('')
  const privacyPreviewOpen = ref(false)
  const iconUploadError = ref('')
  const hostImageUploadError = ref('')
  const hostImageUploading = ref(false)

  watch(
    () => store.adminSiteSettings,
    (settings) => {
      form.hostDisplayName = settings.hostDisplayName
      form.hostTagline = settings.hostTagline
      form.hostArtistName = settings.hostArtistName
      form.hostImageUrl = settings.hostImageUrl
      form.newsletterUrl = settings.newsletterUrl
      form.shareXUrl = settings.shareXUrl
      form.shareDiscordUrl = settings.shareDiscordUrl
      form.privacyEmail = settings.privacyEmail
      form.privacyPolicyContent = settings.privacyPolicyContent
      form.imprintUrl = settings.imprintUrl
      form.imprintContent = settings.imprintContent
      form.contactUrl = settings.contactUrl
      form.contactContent = settings.contactContent
      form.sponsorsUrl = settings.sponsorsUrl
      form.sponsorsContent = settings.sponsorsContent
      form.showactsUrl = settings.showactsUrl
      form.showactsContent = settings.showactsContent
      form.streamBannerEyebrow = settings.streamBannerEyebrow
      form.streamBannerTitle = settings.streamBannerTitle
      form.streamBannerText = plainTextContentFromStorage(settings.streamBannerText)
      form.streamBannerLiveButtonLabel = settings.streamBannerLiveButtonLabel
      form.streamBannerLiveButtonUrl = settings.streamBannerLiveButtonUrl
      form.streamBannerLockedButtonLabel = settings.streamBannerLockedButtonLabel
      form.streamBannerUseCompletedContent = settings.streamBannerUseCompletedContent
      form.streamBannerCompletedEyebrow = settings.streamBannerCompletedEyebrow
      form.streamBannerCompletedTitle = settings.streamBannerCompletedTitle
      form.streamBannerCompletedText = plainTextContentFromStorage(settings.streamBannerCompletedText)
      form.streamBannerCompletedButtonLabel = settings.streamBannerCompletedButtonLabel
      form.streamBannerCompletedButtonUrl = settings.streamBannerCompletedButtonUrl
      form.awardsSectionTitle = settings.awardsSectionTitle
      form.awardsSectionDescription = plainTextContentFromStorage(settings.awardsSectionDescription)
      form.subcategoriesSectionTitle = settings.subcategoriesSectionTitle
      form.subcategoriesSectionDescription = plainTextContentFromStorage(settings.subcategoriesSectionDescription)
      form.socialLinks = settings.socialLinks.map((item) => ({
        label: item.label ?? '',
        platform: item.platform ?? '',
        icon: item.icon ?? '',
        url: item.url ?? '',
        showOnHost: item.showOnHost ?? true,
        showOnCommunity: item.showOnCommunity ?? true,
      }))
      form.faq = settings.faq.map((item) => ({
        question: item.question ?? '',
        answer: item.answer ?? '',
      }))
      form.showactFormSchema = parseShowactSchema(settings.showactFormSchemaJson ?? '[]')
    },
    { immediate: true, deep: true },
  )

  const privacyPreviewHtml = computed(() => privacyContentToHtml(form.privacyPolicyContent))

  const privacyUpdatedLabel = computed(() => {
    const updatedAt = store.adminSiteSettings.privacyPolicyUpdatedAt
    if (!updatedAt) {
      return 'Noch keine Änderung gespeichert'
    }

    return new Intl.DateTimeFormat('de-DE', {
      dateStyle: 'medium',
      timeStyle: 'short',
    }).format(new Date(updatedAt))
  })

  function addSocialLink() {
    form.socialLinks.push({
      label: 'Neu',
      platform: 'website',
      icon: '',
      url: '',
      showOnHost: true,
      showOnCommunity: true,
    })
  }

  function removeSocialLink(index: number) {
    form.socialLinks.splice(index, 1)
  }

  function addFaqItem() {
    form.faq.push({ question: '', answer: '' })
  }

  function removeFaqItem(index: number) {
    form.faq.splice(index, 1)
  }

  function isUploadedIcon(icon: string) {
    return icon.startsWith('data:image/')
  }

  function socialIconKey(social: SocialLinkForm) {
    return normalizeSocialIconKey(social.icon || social.platform)
  }

  function selectedSocialIconValue(social: SocialLinkForm) {
    return socialIconOptionForKey(social.platform)
      ? normalizeSocialIconKey(social.platform)
      : 'custom'
  }

  function handleSocialIconSelection(value: string, index: number) {
    const social = form.socialLinks[index]
    if (!social) {
      return
    }

    if (value === 'custom') {
      if (socialIconOptionForKey(social.platform)) {
        social.platform = ''
      }
      return
    }

    const option = socialIconOptionForKey(value)
    social.platform = value
    if (!social.label || social.label === 'Neu' || social.label === 'Website / Fallback') {
      social.label = option?.label ?? value
    }
    if (social.icon && !isUploadedIcon(social.icon)) {
      social.icon = ''
    }
  }

  function hasSocialIconPreview(social: SocialLinkForm) {
    return Boolean(social.label || social.platform || social.icon)
  }

  function socialIconModeLabel(social: SocialLinkForm) {
    if (isUploadedIcon(social.icon)) {
      return 'hochgeladenes Custom Icon'
    }

    const icon = simpleIconForKey(socialIconKey(social))
    if (icon) {
      return `eingebautes ${icon.title} Icon`
    }

    return 'generisches Fallback Icon'
  }

  function socialSimpleIconPath(social: SocialLinkForm) {
    return simpleIconForKey(socialIconKey(social))?.path ?? ''
  }

  function socialSimpleIconColor(social: SocialLinkForm) {
    return `#${simpleIconForKey(socialIconKey(social))?.hex ?? '8b5cf6'}`
  }

  async function handleSocialIconUpload(event: Event, index: number) {
    iconUploadError.value = ''
    const input = event.target as HTMLInputElement
    const file = input.files?.[0]
    input.value = ''
    if (!file) {
      return
    }

    const allowedTypes = ['image/png', 'image/jpeg', 'image/webp', 'image/svg+xml']
    if (!allowedTypes.includes(file.type)) {
      iconUploadError.value = 'Bitte PNG, JPG, WebP oder SVG hochladen.'
      return
    }

    const maxBytes = 256 * 1024
    if (file.size > maxBytes) {
      iconUploadError.value = 'Icon ist zu groß. Maximal erlaubt sind 256 KB.'
      return
    }

    try {
      await validateRasterDimensions(file)
      form.socialLinks[index].icon = await readFileAsDataUrl(file)
    } catch (error) {
      iconUploadError.value = error instanceof Error ? error.message : 'Icon konnte nicht hochgeladen werden.'
    }
  }

  function clearSocialIcon(index: number) {
    form.socialLinks[index].icon = ''
  }

  async function handleHostImageUpload(event: Event) {
    hostImageUploadError.value = ''
    saveMessage.value = ''
    saveError.value = ''
    const input = event.target as HTMLInputElement
    const file = input.files?.[0]
    input.value = ''
    if (!file) {
      return
    }

    const allowedTypes = ['image/png', 'image/jpeg', 'image/webp']
    if (!allowedTypes.includes(file.type)) {
      hostImageUploadError.value = 'Bitte PNG, JPG oder WebP hochladen.'
      return
    }

    const maxBytes = 8 * 1024 * 1024
    if (file.size > maxBytes) {
      hostImageUploadError.value = 'Hostbild ist zu groß. Maximal erlaubt sind 8 MB.'
      return
    }

    hostImageUploading.value = true
    try {
      await store.uploadAdminHostImage(file)
      saveMessage.value = 'Hostbild gespeichert und auf der Landingpage aktualisiert.'
    } catch (error) {
      hostImageUploadError.value = error instanceof Error ? error.message : 'Hostbild konnte nicht gespeichert werden.'
    } finally {
      hostImageUploading.value = false
    }
  }

  async function saveSiteSettings(sectionLabel = 'Landingpage-Inhalte') {
    saving.value = true
    saveMessage.value = ''
    saveError.value = ''

    try {
      await store.updateAdminSiteSettings({
        hostDisplayName: form.hostDisplayName,
        hostTagline: form.hostTagline,
        hostArtistName: form.hostArtistName,
        newsletterUrl: form.newsletterUrl,
        shareXUrl: form.shareXUrl,
        shareDiscordUrl: form.shareDiscordUrl,
        privacyEmail: form.privacyEmail,
        privacyPolicyContent: privacyContentForStorage(form.privacyPolicyContent),
        imprintUrl: form.imprintUrl,
        imprintContent: privacyContentForStorage(form.imprintContent),
        contactUrl: form.contactUrl,
        contactContent: privacyContentForStorage(form.contactContent),
        sponsorsUrl: form.sponsorsUrl,
        sponsorsContent: privacyContentForStorage(form.sponsorsContent),
        showactsUrl: form.showactsUrl,
        showactsContent: privacyContentForStorage(form.showactsContent),
        streamBannerEyebrow: form.streamBannerEyebrow,
        streamBannerTitle: form.streamBannerTitle,
        streamBannerText: plainTextContentForStorage(form.streamBannerText),
        streamBannerLiveButtonLabel: form.streamBannerLiveButtonLabel,
        streamBannerLiveButtonUrl: form.streamBannerLiveButtonUrl,
        streamBannerLockedButtonLabel: form.streamBannerLockedButtonLabel,
        streamBannerUseCompletedContent: form.streamBannerUseCompletedContent,
        streamBannerCompletedEyebrow: form.streamBannerCompletedEyebrow,
        streamBannerCompletedTitle: form.streamBannerCompletedTitle,
        streamBannerCompletedText: plainTextContentForStorage(form.streamBannerCompletedText),
        streamBannerCompletedButtonLabel: form.streamBannerCompletedButtonLabel,
        streamBannerCompletedButtonUrl: form.streamBannerCompletedButtonUrl,
        awardsSectionTitle: form.awardsSectionTitle,
        awardsSectionDescription: plainTextContentForStorage(form.awardsSectionDescription),
        subcategoriesSectionTitle: form.subcategoriesSectionTitle,
        subcategoriesSectionDescription: plainTextContentForStorage(form.subcategoriesSectionDescription),
        showactFormSchemaJson: JSON.stringify(form.showactFormSchema),
        socialLinks: form.socialLinks
          .map((item) => ({
            label: item.label.trim(),
            platform: item.platform.trim(),
            icon: item.icon.trim(),
            url: item.url.trim(),
            showOnHost: item.showOnHost,
            showOnCommunity: item.showOnCommunity,
          }))
          .filter((item) => item.label && item.platform && item.url),
        faq: form.faq
          .map((item) => ({
            question: item.question.trim(),
            answer: item.answer.trim(),
          }))
          .filter((item) => item.question && item.answer),
      })
      saveMessage.value = `${sectionLabel} gespeichert und auf der Landingpage aktualisiert.`
    } catch (error) {
      saveError.value = error instanceof Error ? error.message : 'Inhalte konnten nicht gespeichert werden.'
    } finally {
      saving.value = false
    }
  }

  return {
    form,
    saving,
    saveMessage,
    saveError,
    privacyPreviewOpen,
    iconUploadError,
    hostImageUploadError,
    hostImageUploading,
    privacyPreviewHtml,
    privacyUpdatedLabel,
    addSocialLink,
    removeSocialLink,
    addFaqItem,
    removeFaqItem,
    isUploadedIcon,
    selectedSocialIconValue,
    handleSocialIconSelection,
    hasSocialIconPreview,
    socialIconModeLabel,
    socialSimpleIconPath,
    socialSimpleIconColor,
    handleSocialIconUpload,
    clearSocialIcon,
    handleHostImageUpload,
    saveSiteSettings,
    adminSiteSettings: computed(() => store.adminSiteSettings),
  }
}
