<template>
  <Teleport to="body">
    <!-- Backdrop -->
    <transition name="backdrop">
      <div
        v-if="modelValue"
        class="fixed inset-0 z-[1010]"
        style="background: rgba(26,34,56,0.5);"
        @click="emit('update:modelValue', false)"
        aria-hidden="true"
      />
    </transition>

    <!-- Bottom sheet plein écran -->
    <transition name="sheet">
      <div
        v-if="modelValue"
        class="fixed inset-x-0 bottom-0 z-[1011] flex flex-col"
        style="
          background: var(--nav-surface);
          height: 100dvh;
          max-height: 100dvh;
          border-radius: 0;
          box-shadow: 0 -4px 32px rgba(26,34,56,0.18);
        "
        role="dialog"
        aria-modal="true"
        aria-label="Assistant AEP"
      >
        <!-- Poignée visuelle -->
        <div class="flex justify-center pt-3 pb-1 shrink-0">
          <div
            class="rounded-full"
            style="width: 36px; height: 4px; background: var(--nav-bg-alt);"
          />
        </div>

        <!-- Header -->
        <div
          class="flex items-center justify-between px-4 py-3 shrink-0 border-b"
          style="border-color: var(--nav-bg-alt);"
        >
          <button
            @click="emit('update:modelValue', false)"
            class="flex items-center gap-2 text-sm font-medium transition-opacity hover:opacity-70"
            style="color: var(--nav-text-muted);"
            aria-label="Retour"
          >
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
              <polyline points="15 18 9 12 15 6"/>
            </svg>
            Retour
          </button>

          <div class="flex items-center gap-2">
            <div
              class="w-7 h-7 rounded-full flex items-center justify-center shrink-0"
              style="background: var(--nav-primary);"
            >
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" style="color: var(--nav-text-on-primary);">
                <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
              </svg>
            </div>
            <span class="font-bold text-sm" style="color: var(--nav-text);">Chatbot</span>
          </div>
        </div>

        <!-- Zone conversation -->
        <div ref="messagesContainer" class="flex-1 overflow-y-auto px-4 py-4 flex flex-col gap-3">
          <!-- Message onboarding (avant la première question) -->
          <div v-if="messages.length === 0" class="onboarding-bubble">
            <p>Ce chatbot fonctionne sur un serveur européen souverain
(Mistral FR, zéro rétention), conçu sobre en énergie.</p>
            <p>Pour m'aider à te répondre efficacement,
formule ta requête ainsi :</p>
            <ul>
              <li>• Besoin : [ce que tu cherches]</li>
              <li>• Thématique : [juridique / technique / économique / ...]</li>
              <li>• Lieu : [région ou ville]</li>
            </ul>
            <p class="example">Exemple : "Je suis salarié d'agence, litige avec mon
employeur, besoin conseil juridique droit du travail,
Île-de-France."</p>
          </div>

          <!-- Messages -->
          <template v-for="(msg, i) in messages" :key="i">
            <!-- Message utilisateur -->
            <div v-if="msg.role === 'user'" class="user-bubble">
              {{ msg.content }}
            </div>

            <!-- Message assistant -->
            <div v-else class="assistant-bubble">
              <p>{{ msg.content }}</p>

              <!-- Fiches recommandées -->
              <div v-if="msg.fiches && msg.fiches.length > 0" class="fiches-list">
                <p class="fiches-title">Fiches recommandées :</p>
                <a
                  v-for="fiche in msg.fiches"
                  :key="fiche.id"
                  :href="`/fiche/${fiche.id}`"
                  class="fiche-card"
                >
                  <span class="fiche-nom">{{ fiche.nom }}</span>
                  <span v-if="fiche.explication" class="fiche-expl">{{ fiche.explication }}</span>
                </a>
              </div>
            </div>
          </template>

          <!-- Indicateur de chargement -->
          <div v-if="loading" class="assistant-bubble loading-bubble">
            <span class="dot" /><span class="dot" /><span class="dot" />
          </div>

          <!-- Message d'erreur -->
          <div v-if="errorMsg" class="error-bubble">
            {{ errorMsg }}
          </div>
        </div>

        <!-- Input -->
        <div
          class="shrink-0 px-4 pt-3 border-t"
          style="border-color: var(--nav-bg-alt); padding-bottom: max(1rem, env(safe-area-inset-bottom));"
        >
          <div class="flex items-center gap-2">
            <input
              v-model="inputText"
              type="text"
              :disabled="loading"
              placeholder="Pose ta question…"
              class="flex-1 px-4 py-3 rounded-xl text-sm border"
              :class="loading ? 'cursor-not-allowed' : ''"
              style="
                border-color: var(--nav-bg-alt);
                background: var(--nav-bg);
                color: var(--nav-text);
                font-family: var(--nav-font);
                font-size: 16px;
              "
              @keydown.enter.prevent="sendMessage"
            />
            <button
              :disabled="loading || !inputText.trim()"
              class="w-11 h-11 rounded-xl flex items-center justify-center shrink-0 transition-opacity"
              style="background: var(--nav-primary);"
              :style="{ opacity: (loading || !inputText.trim()) ? 0.4 : 1 }"
              aria-label="Envoyer"
              @click="sendMessage"
            >
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" style="color: var(--nav-text-on-primary);">
                <line x1="22" y1="2" x2="11" y2="13"/>
                <polygon points="22 2 15 22 11 13 2 9 22 2"/>
              </svg>
            </button>
          </div>
        </div>
      </div>
    </transition>
  </Teleport>
</template>

<script setup lang="ts">
interface FicheReco {
  id: number | string
  nom: string
  explication?: string
}

interface ChatMessage {
  role: 'user' | 'assistant'
  content: string
  fiches?: FicheReco[]
}

const props = defineProps<{
  modelValue: boolean
}>()

const emit = defineEmits<{
  'update:modelValue': [value: boolean]
  'highlightOrgs': [ids: (number | string)[]]
}>()

const messages = ref<ChatMessage[]>([])
const inputText = ref('')
const loading = ref(false)
const errorMsg = ref('')
const messagesContainer = ref<HTMLElement | null>(null)

watch(() => props.modelValue, (open) => {
  if (typeof document === 'undefined') return
  if (open) {
    document.body.style.overflow = 'hidden'
    document.documentElement.style.overflow = 'hidden'
  } else {
    document.body.style.overflow = ''
    document.documentElement.style.overflow = ''
  }
})

onUnmounted(() => {
  if (typeof document !== 'undefined') {
    document.body.style.overflow = ''
    document.documentElement.style.overflow = ''
  }
})

async function sendMessage() {
  const question = inputText.value.trim()
  if (!question || loading.value) return

  inputText.value = ''
  errorMsg.value = ''
  messages.value.push({ role: 'user', content: question })
  loading.value = true

  await nextTick()
  scrollToBottom()

  try {
    const res = await $fetch<{
      reponse_texte: string
      fiches_recommandees: { id: number | string; nom: string; explication: string }[]
    }>('/api/chatbot', {
      method: 'POST',
      body: { question },
    })

    const assistantMsg: ChatMessage = {
      role: 'assistant',
      content: res.reponse_texte,
      fiches: res.fiches_recommandees || [],
    }
    messages.value.push(assistantMsg)

    // Highlight carte si des fiches sont recommandées
    if (assistantMsg.fiches && assistantMsg.fiches.length > 0) {
      emit('highlightOrgs', assistantMsg.fiches.map((f) => f.id))
    }
  } catch (e: any) {
    const status = e?.statusCode ?? e?.status
    if (status === 429) {
      errorMsg.value = 'Limite de 10 questions par jour atteinte. Reviens demain.'
    } else if (status === 503) {
      errorMsg.value = 'Le budget IA mensuel est épuisé. Soutiens NAV sur Liberapay pour continuer.'
    } else {
      errorMsg.value = 'Une erreur est survenue. Réessaie dans quelques instants.'
    }
  } finally {
    loading.value = false
    await nextTick()
    scrollToBottom()
  }
}

function scrollToBottom() {
  if (messagesContainer.value) {
    messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight
  }
}
</script>

<style scoped>
.backdrop-enter-active,
.backdrop-leave-active { transition: opacity 0.2s ease; }
.backdrop-enter-from,
.backdrop-leave-to { opacity: 0; }

.sheet-enter-active,
.sheet-leave-active { transition: transform 0.3s cubic-bezier(0.32, 0.72, 0, 1); }
.sheet-enter-from,
.sheet-leave-to { transform: translateY(100%); }

/* Onboarding */
.onboarding-bubble {
  background: var(--nav-bg);
  border: 1px solid var(--nav-bg-alt);
  border-radius: 12px;
  padding: 16px;
  font-size: 0.85rem;
  line-height: 1.65;
  color: var(--nav-text-muted);
  white-space: pre-line;
}
.onboarding-bubble p { margin-bottom: 10px; }
.onboarding-bubble ul { margin: 8px 0; padding: 0; list-style: none; }
.onboarding-bubble li { margin-bottom: 4px; }
.onboarding-bubble .example {
  margin-top: 12px;
  font-style: italic;
  opacity: 0.8;
  font-size: 0.8rem;
}

/* Bulles utilisateur */
.user-bubble {
  align-self: flex-end;
  max-width: 80%;
  background: var(--nav-primary);
  color: var(--nav-text-on-primary);
  border-radius: 16px 16px 4px 16px;
  padding: 10px 14px;
  font-size: 0.875rem;
  line-height: 1.5;
}

/* Bulles assistant */
.assistant-bubble {
  align-self: flex-start;
  max-width: 90%;
  background: var(--nav-surface);
  border: 1px solid var(--nav-bg-alt);
  border-radius: 16px 16px 16px 4px;
  padding: 12px 14px;
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--nav-text);
}
.assistant-bubble p { margin: 0; }

/* Fiches recommandées */
.fiches-list {
  margin-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.fiches-title {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--nav-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 4px;
}
.fiche-card {
  display: block;
  background: var(--nav-bg);
  border: 1px solid var(--nav-bg-alt);
  border-radius: 8px;
  padding: 8px 12px;
  text-decoration: none;
  transition: border-color 0.15s, background 0.15s;
}
.fiche-card:hover {
  border-color: var(--nav-primary);
  background: var(--nav-surface);
}
.fiche-nom {
  display: block;
  font-size: 0.825rem;
  font-weight: 600;
  color: var(--nav-text);
}
.fiche-expl {
  display: block;
  font-size: 0.775rem;
  color: var(--nav-text-muted);
  margin-top: 2px;
}

/* Chargement */
.loading-bubble {
  display: flex;
  gap: 5px;
  padding: 12px 16px;
}
.dot {
  width: 7px;
  height: 7px;
  background: var(--nav-text-muted);
  border-radius: 50%;
  animation: blink 1.2s infinite ease-in-out;
}
.dot:nth-child(2) { animation-delay: 0.2s; }
.dot:nth-child(3) { animation-delay: 0.4s; }
@keyframes blink {
  0%, 80%, 100% { opacity: 0.3; transform: scale(0.85); }
  40% { opacity: 1; transform: scale(1); }
}

/* Erreur */
.error-bubble {
  align-self: center;
  background: rgba(220, 50, 50, 0.08);
  border: 1px solid rgba(220, 50, 50, 0.2);
  border-radius: 10px;
  padding: 10px 14px;
  font-size: 0.825rem;
  color: #c0392b;
  text-align: center;
  max-width: 90%;
}

@media (prefers-reduced-motion: reduce) {
  .sheet-enter-active,
  .sheet-leave-active { transition: none; }
  .backdrop-enter-active,
  .backdrop-leave-active { transition: none; }
  .dot { animation: none; opacity: 0.5; }
}
</style>
