import { computed, ref } from 'vue'
import { parsePptTemplateConfig, SYSTEM_DEFAULT_PPT_CONFIG } from '../config/pptTemplateDefaults'
import { fetchPptTemplates, type PptTemplateApiItem } from '../services/api'
import type { PptTemplate, PptTemplateConfig } from '../types/pptTemplate'
import { applyPptTemplate } from '../utils/applyPptTemplate'

const STORAGE_KEY = 'ppt_selected_template_id'

function readStoredTemplateId(): number | null {
  try {
    const raw = localStorage.getItem(STORAGE_KEY)
    if (!raw) return null
    const id = Number.parseInt(raw, 10)
    return Number.isFinite(id) && id > 0 ? id : null
  } catch {
    return null
  }
}

function writeStoredTemplateId(id: number): void {
  try {
    localStorage.setItem(STORAGE_KEY, String(id))
  } catch {
    /* ignore */
  }
}

function normalizeTemplate(raw: PptTemplateApiItem): PptTemplate {
  return {
    ...raw,
    config: parsePptTemplateConfig(raw.config),
  }
}

function buildFallbackTemplate(): PptTemplate {
  return {
    id: 0,
    name: '默认模板',
    slug: 'default',
    description: '',
    config: SYSTEM_DEFAULT_PPT_CONFIG,
    isSystem: true,
    isDefault: true,
    sortOrder: 0,
    isActive: true,
  }
}

export function usePptTemplate() {
  const templates = ref<PptTemplate[]>([])
  const loading = ref(false)
  const selectedTemplateId = ref<number | null>(readStoredTemplateId())

  const loadTemplates = async () => {
    loading.value = true
    try {
      const list = await fetchPptTemplates()
      templates.value = list.map(normalizeTemplate)
      if (!templates.value.length) {
        templates.value = [buildFallbackTemplate()]
        return
      }

      const storedId = selectedTemplateId.value
      const storedExists = storedId != null && templates.value.some((t) => t.id === storedId)
      if (!storedExists) {
        const fallback =
          templates.value.find((t) => t.isDefault) ??
          templates.value.find((t) => t.isSystem) ??
          templates.value[0]
        if (fallback) {
          selectedTemplateId.value = fallback.id
          writeStoredTemplateId(fallback.id)
        }
      }
    } catch (err) {
      console.error('Failed to load PPT templates:', err)
      templates.value = [buildFallbackTemplate()]
      selectedTemplateId.value = 0
    } finally {
      loading.value = false
    }
  }

  const activeTemplate = computed((): PptTemplate => {
    if (!templates.value.length) return buildFallbackTemplate()
    const id = selectedTemplateId.value
    const found = id != null ? templates.value.find((t) => t.id === id) : undefined
    if (found) return found
    return (
      templates.value.find((t) => t.isDefault) ??
      templates.value.find((t) => t.isSystem) ??
      templates.value[0] ??
      buildFallbackTemplate()
    )
  })

  const applied = computed(() => applyPptTemplate(activeTemplate.value.config))

  const templateVars = computed(() => applied.value.templateVars)
  const slideTransitionForward = computed(() => applied.value.slideTransitionForward)
  const slideTransitionBackward = computed(() => applied.value.slideTransitionBackward)
  const revealTransition = computed(() => applied.value.revealTransition)
  const showThumbnailsDefault = computed(
    () => activeTemplate.value.config.ui.showThumbnailsDefault
  )

  const setTemplate = (id: number) => {
    if (!templates.value.some((t) => t.id === id)) return
    selectedTemplateId.value = id
    writeStoredTemplateId(id)
  }

  const applyConfigPreview = (config: PptTemplateConfig) => applyPptTemplate(config)

  return {
    templates,
    loading,
    selectedTemplateId,
    activeTemplate,
    templateVars,
    slideTransitionForward,
    slideTransitionBackward,
    revealTransition,
    showThumbnailsDefault,
    loadTemplates,
    setTemplate,
    applyConfigPreview,
  }
}
