<script setup lang="ts">
// Wrapper Carte O : fetch /data/carte-o.json + state modal.
// Vue island Astro hydratée client:visible.
import { ref, onMounted, computed } from 'vue'
import CarteO from './CarteO.vue'
import CarteOModal from './CarteOModal.vue'

interface CarteNode {
  id: string
  label: string
  family: string
  intention?: string
  slug?: string
  theme?: string
}

interface CarteEdge {
  source: string
  target: string
}

interface CarteData {
  meta?: {
    nodeCount?: number
    edgeCount?: number
    familyDistribution?: Record<string, number>
    familyColors?: Record<string, string>
  }
  nodes: CarteNode[]
  edges: CarteEdge[]
}

const props = withDefaults(defineProps<{
  src?: string
}>(), {
  src: '/data/carte-o.json',
})

const data = ref<CarteData | null>(null)
const error = ref<string | null>(null)
const selectedNode = ref<CarteNode | null>(null)
const isMobileScreen = ref(false)

const familyColors = computed(() =>
  data.value?.meta?.familyColors || {
    penseur:   '#3b82f6',
    concept:   '#10b981',
    methode:   '#f59e0b',
    collectif: '#ef4444',
    ressource: '#8b5cf6',
  }
)

onMounted(async () => {
  isMobileScreen.value = window.innerWidth < 768
  try {
    const res = await fetch(props.src)
    if (!res.ok) throw new Error(`HTTP ${res.status}`)
    data.value = await res.json()
  } catch (e: any) {
    console.error('[CarteO] failed to load', e)
    error.value = e?.message || 'Erreur de chargement'
  }

  // Update mobile flag on resize.
  window.addEventListener('resize', () => {
    isMobileScreen.value = window.innerWidth < 768
  })
})
</script>

<template>
  <div class="wrapper">
    <!-- Mobile fallback (V1) -->
    <div v-if="isMobileScreen" class="mobile-fallback">
      <div class="mini-map">
        <svg viewBox="0 0 200 120" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
          <circle cx="100" cy="60" r="8" fill="#3b82f6" />
          <circle cx="50" cy="35" r="5" fill="#10b981" />
          <circle cx="150" cy="35" r="5" fill="#f59e0b" />
          <circle cx="55" cy="90" r="5" fill="#ef4444" />
          <circle cx="145" cy="90" r="5" fill="#8b5cf6" />
          <line x1="100" y1="60" x2="50" y2="35" stroke="#94a3b8" stroke-width="0.8" opacity="0.5" />
          <line x1="100" y1="60" x2="150" y2="35" stroke="#94a3b8" stroke-width="0.8" opacity="0.5" />
          <line x1="100" y1="60" x2="55" y2="90" stroke="#94a3b8" stroke-width="0.8" opacity="0.5" />
          <line x1="100" y1="60" x2="145" y2="90" stroke="#94a3b8" stroke-width="0.8" opacity="0.5" />
        </svg>
      </div>
      <p class="msg">
        Carte O optimisée desktop. Retournez sur grand écran pour explorer la mindmap interactive.
      </p>
    </div>

    <!-- Loading state -->
    <div v-else-if="!data && !error" class="state">
      <span>Chargement de la Carte O…</span>
    </div>

    <!-- Error state -->
    <div v-else-if="error" class="state error">
      <span>Impossible de charger la Carte O ({{ error }})</span>
    </div>

    <!-- Carte O -->
    <template v-else-if="data">
      <CarteO
        :nodes="data.nodes"
        :edges="data.edges"
        :family-colors="familyColors"
        @node-click="selectedNode = $event"
      />
      <CarteOModal
        :node="selectedNode"
        :family-colors="familyColors"
        @close="selectedNode = null"
      />
    </template>
  </div>
</template>

<style scoped>
.wrapper {
  height: 100%;
  width: 100%;
  position: relative;
}

.state {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #9ca3af;
  font-size: 0.9rem;
}

.state.error {
  color: #dc2626;
}

.mobile-fallback {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  text-align: center;
  gap: 1rem;
}

.mini-map {
  width: 70%;
  max-width: 240px;
}

.mini-map svg {
  width: 100%;
  height: auto;
}

.msg {
  color: #6b7280;
  font-size: 0.85rem;
  line-height: 1.45;
  font-style: italic;
  max-width: 24rem;
  margin: 0;
}
</style>
