<template>
  <div>
    <div class="page-header">
      <NuxtLink :to="`/admin/communes/${slug}`" style="color: var(--color-text-muted);">&larr; {{ slug }}</NuxtLink>
      <h1>Contenu CMS</h1>
    </div>

    <div v-if="error" class="alert alert-error">{{ error }}</div>
    <div v-if="success" class="alert alert-success">{{ success }}</div>

    <!-- Create new page -->
    <div class="card" style="margin-bottom: 1.5rem;">
      <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
        <h3>Pages de contenu</h3>
        <button class="btn btn-primary" @click="showCreate = !showCreate">
          {{ showCreate ? 'Annuler' : 'Nouvelle page' }}
        </button>
      </div>

      <div v-if="showCreate" style="margin-bottom: 1rem; padding: 1rem; background: var(--color-bg); border-radius: var(--radius);">
        <div class="grid grid-2">
          <div class="form-group">
            <label>Slug (identifiant URL)</label>
            <input v-model="newSlug" class="form-input" placeholder="ex: presentation" pattern="[a-z0-9-]+" />
          </div>
          <div class="form-group">
            <label>Titre</label>
            <input v-model="newTitle" class="form-input" placeholder="ex: Presentation de la commune" />
          </div>
        </div>
        <button class="btn btn-primary" @click="createPage" :disabled="!newSlug || !newTitle">
          Creer la page
        </button>
      </div>

      <!-- Pages list -->
      <div v-if="loading" style="text-align: center; padding: 1rem;">
        <div class="spinner" style="margin: 0 auto;"></div>
      </div>

      <div v-else-if="pages.length === 0" class="alert alert-info">
        Aucune page de contenu. Cliquez sur "Nouvelle page" pour en creer une.
      </div>

      <div v-else>
        <div
          v-for="page in pages" :key="page.slug"
          class="page-item"
          :class="{ active: editing?.slug === page.slug }"
          @click="startEdit(page)"
        >
          <div>
            <strong>{{ page.title }}</strong>
            <span style="color: var(--color-text-muted); font-size: 0.8rem; margin-left: 0.5rem;">
              /{{ page.slug }}
            </span>
          </div>
          <div style="font-size: 0.75rem; color: var(--color-text-muted);">
            {{ new Date(page.updated_at).toLocaleDateString('fr-FR') }}
          </div>
        </div>
      </div>
    </div>

    <!-- Editor -->
    <div v-if="editing" class="card">
      <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
        <h3>{{ editing.title }} <span style="color: var(--color-text-muted); font-size: 0.8rem;">/{{ editing.slug }}</span></h3>
        <div style="display: flex; gap: 0.5rem;">
          <button class="btn btn-secondary" @click="previewMode = !previewMode">
            {{ previewMode ? 'Editer' : 'Apercu' }}
          </button>
          <button class="btn btn-danger btn-sm" @click="confirmDelete">Supprimer</button>
        </div>
      </div>

      <div class="form-group">
        <label>Titre</label>
        <input v-model="editing.title" class="form-input" />
      </div>

      <div v-if="!previewMode" class="form-group">
        <label>Contenu (Markdown)</label>

        <!-- Toolbar -->
        <div class="md-toolbar">
          <div class="md-toolbar-group">
            <button type="button" class="md-btn" title="Titre 1" @click="insertBlock('# ')">H1</button>
            <button type="button" class="md-btn" title="Titre 2" @click="insertBlock('## ')">H2</button>
            <button type="button" class="md-btn" title="Titre 3" @click="insertBlock('### ')">H3</button>
          </div>
          <div class="md-toolbar-sep"></div>
          <div class="md-toolbar-group">
            <button type="button" class="md-btn" title="Gras (Ctrl+B)" @click="wrapSelection('**')"><b>G</b></button>
            <button type="button" class="md-btn" title="Italique (Ctrl+I)" @click="wrapSelection('*')"><i>I</i></button>
            <button type="button" class="md-btn" title="Barre (Ctrl+D)" @click="wrapSelection('~~')"><s>S</s></button>
          </div>
          <div class="md-toolbar-sep"></div>
          <div class="md-toolbar-group">
            <button type="button" class="md-btn" title="Lien" @click="insertLink">Lien</button>
            <button type="button" class="md-btn" title="Image" @click="insertImage">Image</button>
          </div>
          <div class="md-toolbar-sep"></div>
          <div class="md-toolbar-group">
            <button type="button" class="md-btn" title="Liste a puces" @click="insertBlock('- ')">&#8226; Liste</button>
            <button type="button" class="md-btn" title="Liste numerotee" @click="insertBlock('1. ')">1. Liste</button>
            <button type="button" class="md-btn" title="Citation" @click="insertBlock('> ')">Citation</button>
          </div>
          <div class="md-toolbar-sep"></div>
          <div class="md-toolbar-group">
            <button type="button" class="md-btn" title="Code inline" @click="wrapSelection('`')">Code</button>
            <button type="button" class="md-btn" title="Bloc de code" @click="insertCodeBlock">```</button>
            <button type="button" class="md-btn" title="Ligne horizontale" @click="insertHR">&#8212;</button>
          </div>
        </div>

        <textarea
          ref="textareaRef"
          v-model="editing.body_markdown"
          class="form-input content-textarea"
          rows="20"
          placeholder="Redigez votre contenu en Markdown..."
          @keydown="onKeydown"
        ></textarea>
      </div>

      <div v-else class="preview-box">
        <div v-html="renderMarkdown(editing.body_markdown)"></div>
      </div>

      <div style="display: flex; gap: 0.5rem; margin-top: 1rem;">
        <button class="btn btn-primary" @click="savePage" :disabled="saving">
          {{ saving ? 'Enregistrement...' : 'Enregistrer' }}
        </button>
        <button class="btn btn-secondary" @click="editing = null">Fermer</button>
      </div>
    </div>

    <!-- Delete confirmation modal -->
    <div v-if="deleting" class="modal-overlay" @click.self="deleting = false">
      <div class="card modal-content">
        <h3>Supprimer cette page ?</h3>
        <p style="margin: 1rem 0; color: var(--color-text-muted);">
          Supprimer la page <strong>{{ editing?.title }}</strong> est irreversible.
        </p>
        <div style="display: flex; gap: 0.5rem; justify-content: flex-end;">
          <button class="btn btn-secondary" @click="deleting = false">Annuler</button>
          <button class="btn btn-danger" @click="doDelete">Confirmer</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
definePageMeta({ middleware: 'admin' })

const route = useRoute()
const api = useApi()
const slug = route.params.slug as string

interface ContentPage {
  slug: string
  title: string
  body_markdown: string
  updated_at: string
}

const pages = ref<ContentPage[]>([])
const loading = ref(true)
const error = ref('')
const success = ref('')
const showCreate = ref(false)
const newSlug = ref('')
const newTitle = ref('')
const editing = ref<ContentPage | null>(null)
const previewMode = ref(false)
const saving = ref(false)
const deleting = ref(false)
const textareaRef = ref<HTMLTextAreaElement | null>(null)

onMounted(async () => {
  await loadPages()
})

async function loadPages() {
  loading.value = true
  error.value = ''
  try {
    pages.value = await api.get<ContentPage[]>(`/communes/${slug}/content`)
  } catch (e: any) {
    error.value = e.message
  } finally {
    loading.value = false
  }
}

async function createPage() {
  error.value = ''; success.value = ''
  try {
    const page = await api.put<ContentPage>(
      `/communes/${slug}/content/${newSlug.value}`,
      { title: newTitle.value, body_markdown: '' },
    )
    showCreate.value = false
    newSlug.value = ''; newTitle.value = ''
    await loadPages()
    startEdit(page)
    success.value = 'Page creee'
  } catch (e: any) {
    error.value = e.message
  }
}

function startEdit(page: ContentPage) {
  editing.value = { ...page }
  previewMode.value = false
}

async function savePage() {
  if (!editing.value) return
  saving.value = true
  error.value = ''; success.value = ''
  try {
    await api.put(
      `/communes/${slug}/content/${editing.value.slug}`,
      { title: editing.value.title, body_markdown: editing.value.body_markdown },
    )
    success.value = 'Page enregistree'
    await loadPages()
  } catch (e: any) {
    error.value = e.message
  } finally {
    saving.value = false
  }
}

function confirmDelete() {
  deleting.value = true
}

async function doDelete() {
  if (!editing.value) return
  error.value = ''; success.value = ''
  try {
    await api.delete(`/communes/${slug}/content/${editing.value.slug}`)
    success.value = 'Page supprimee'
    editing.value = null
    deleting.value = false
    await loadPages()
  } catch (e: any) {
    error.value = e.message
  }
}

// ── Markdown toolbar helpers ──

function getTextarea(): HTMLTextAreaElement | null {
  return textareaRef.value
}

function wrapSelection(marker: string) {
  const ta = getTextarea()
  if (!ta || !editing.value) return
  const start = ta.selectionStart
  const end = ta.selectionEnd
  const text = editing.value.body_markdown
  const selected = text.substring(start, end)
  const placeholder = selected || 'texte'
  const replacement = `${marker}${placeholder}${marker}`

  editing.value.body_markdown = text.substring(0, start) + replacement + text.substring(end)

  nextTick(() => {
    ta.focus()
    if (selected) {
      ta.selectionStart = start
      ta.selectionEnd = start + replacement.length
    } else {
      ta.selectionStart = start + marker.length
      ta.selectionEnd = start + marker.length + placeholder.length
    }
  })
}

function insertBlock(prefix: string) {
  const ta = getTextarea()
  if (!ta || !editing.value) return
  const start = ta.selectionStart
  const text = editing.value.body_markdown

  // Find the start of the current line
  const lineStart = text.lastIndexOf('\n', start - 1) + 1
  const before = text.substring(0, lineStart)
  const after = text.substring(lineStart)

  editing.value.body_markdown = before + prefix + after

  nextTick(() => {
    ta.focus()
    ta.selectionStart = ta.selectionEnd = lineStart + prefix.length
  })
}

function insertLink() {
  const ta = getTextarea()
  if (!ta || !editing.value) return
  const start = ta.selectionStart
  const end = ta.selectionEnd
  const text = editing.value.body_markdown
  const selected = text.substring(start, end)
  const label = selected || 'titre du lien'
  const replacement = `[${label}](url)`

  editing.value.body_markdown = text.substring(0, start) + replacement + text.substring(end)

  nextTick(() => {
    ta.focus()
    // Select "url" for quick editing
    const urlStart = start + label.length + 3
    ta.selectionStart = urlStart
    ta.selectionEnd = urlStart + 3
  })
}

function insertImage() {
  const ta = getTextarea()
  if (!ta || !editing.value) return
  const start = ta.selectionStart
  const end = ta.selectionEnd
  const text = editing.value.body_markdown
  const selected = text.substring(start, end)
  const alt = selected || 'description'
  const replacement = `![${alt}](url)`

  editing.value.body_markdown = text.substring(0, start) + replacement + text.substring(end)

  nextTick(() => {
    ta.focus()
    const urlStart = start + alt.length + 4
    ta.selectionStart = urlStart
    ta.selectionEnd = urlStart + 3
  })
}

function insertCodeBlock() {
  const ta = getTextarea()
  if (!ta || !editing.value) return
  const start = ta.selectionStart
  const end = ta.selectionEnd
  const text = editing.value.body_markdown
  const selected = text.substring(start, end)
  const code = selected || 'code'
  const replacement = `\n\`\`\`\n${code}\n\`\`\`\n`

  editing.value.body_markdown = text.substring(0, start) + replacement + text.substring(end)

  nextTick(() => {
    ta.focus()
    ta.selectionStart = start + 4
    ta.selectionEnd = start + 4 + code.length
  })
}

function insertHR() {
  const ta = getTextarea()
  if (!ta || !editing.value) return
  const start = ta.selectionStart
  const text = editing.value.body_markdown
  const replacement = '\n---\n'

  editing.value.body_markdown = text.substring(0, start) + replacement + text.substring(start)

  nextTick(() => {
    ta.focus()
    ta.selectionStart = ta.selectionEnd = start + replacement.length
  })
}

function onKeydown(e: KeyboardEvent) {
  if (!editing.value) return
  // Ctrl+B = bold
  if (e.ctrlKey && e.key === 'b') {
    e.preventDefault()
    wrapSelection('**')
  }
  // Ctrl+I = italic
  if (e.ctrlKey && e.key === 'i') {
    e.preventDefault()
    wrapSelection('*')
  }
  // Ctrl+D = strikethrough
  if (e.ctrlKey && e.key === 'd') {
    e.preventDefault()
    wrapSelection('~~')
  }
  // Ctrl+K = link
  if (e.ctrlKey && e.key === 'k') {
    e.preventDefault()
    insertLink()
  }
}

function renderMarkdown(md: string): string {
  if (!md) return '<p style="color: var(--color-text-muted);">Aucun contenu.</p>'
  let html = md
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')

  // Code blocks (before other transformations)
  html = html.replace(/```(\w*)\n([\s\S]*?)```/g, (_m, _lang, code) =>
    `<pre><code>${code.trim()}</code></pre>`)

  // Headings
  html = html.replace(/^### (.+)$/gm, '<h3>$1</h3>')
  html = html.replace(/^## (.+)$/gm, '<h2>$1</h2>')
  html = html.replace(/^# (.+)$/gm, '<h1>$1</h1>')

  // Horizontal rule
  html = html.replace(/^---$/gm, '<hr />')

  // Bold, italic, strikethrough, inline code
  html = html.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
  html = html.replace(/\*(.+?)\*/g, '<em>$1</em>')
  html = html.replace(/~~(.+?)~~/g, '<del>$1</del>')
  html = html.replace(/`([^`]+)`/g, '<code class="inline">$1</code>')

  // Images and links
  html = html.replace(/!\[(.+?)\]\((.+?)\)/g, '<img src="$2" alt="$1" style="max-width:100%;" />')
  html = html.replace(/\[(.+?)\]\((.+?)\)/g, '<a href="$2" target="_blank">$1</a>')

  // Blockquotes
  html = html.replace(/^&gt; (.+)$/gm, '<blockquote>$1</blockquote>')

  // Unordered lists
  html = html.replace(/^- (.+)$/gm, '<li>$1</li>')
  // Ordered lists
  html = html.replace(/^\d+\. (.+)$/gm, '<li class="ol">$1</li>')

  // Wrap consecutive <li> in <ul> or <ol>
  html = html.replace(/((?:<li>.*<\/li>\n?)+)/g, '<ul>$1</ul>')
  html = html.replace(/((?:<li class="ol">.*<\/li>\n?)+)/g, (_m, items) =>
    '<ol>' + items.replace(/ class="ol"/g, '') + '</ol>')

  // Paragraphs (lines not already wrapped)
  html = html.replace(/\n\n/g, '</p><p>')
  html = html.replace(/^(?!<[hupodbia\-lr/])(.+)$/gm, '<p>$1</p>')

  return html
}
</script>

<style scoped>
.page-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.75rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  margin-bottom: 0.5rem;
  cursor: pointer;
  transition: all 0.15s;
}

.page-item:hover {
  background: var(--color-bg);
}

.page-item.active {
  border-color: var(--color-primary);
  background: #eff6ff;
}

/* Markdown toolbar */
.md-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  padding: 0.4rem;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-bottom: none;
  border-radius: var(--radius) var(--radius) 0 0;
}

.md-toolbar-group {
  display: flex;
  gap: 2px;
}

.md-toolbar-sep {
  width: 1px;
  background: var(--color-border);
  margin: 0 4px;
}

.md-btn {
  padding: 0.25rem 0.5rem;
  font-size: 0.8rem;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 3px;
  cursor: pointer;
  color: var(--color-text);
  white-space: nowrap;
  line-height: 1.4;
}

.md-btn:hover {
  background: var(--color-surface, #e5e7eb);
  border-color: var(--color-border);
}

.md-btn:active {
  background: var(--color-border);
}

.content-textarea {
  font-family: 'Fira Code', 'Consolas', monospace;
  font-size: 0.85rem;
  line-height: 1.6;
  resize: vertical;
  border-radius: 0 0 var(--radius) var(--radius);
}

.preview-box {
  padding: 1rem;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  min-height: 200px;
  line-height: 1.7;
}

.preview-box h1 { font-size: 1.5rem; margin: 1rem 0 0.5rem; }
.preview-box h2 { font-size: 1.25rem; margin: 0.75rem 0 0.5rem; }
.preview-box h3 { font-size: 1.1rem; margin: 0.5rem 0 0.25rem; }
.preview-box p { margin: 0.5rem 0; }
.preview-box ul, .preview-box ol { margin: 0.5rem 0; padding-left: 1.5rem; }
.preview-box a { color: var(--color-primary); }
.preview-box hr { border: none; border-top: 1px solid var(--color-border); margin: 1rem 0; }
.preview-box blockquote {
  border-left: 3px solid var(--color-primary);
  padding: 0.25rem 0.75rem;
  margin: 0.5rem 0;
  color: var(--color-text-muted);
  background: rgba(0,0,0,0.02);
}
.preview-box pre {
  background: #1e293b;
  color: #e2e8f0;
  padding: 0.75rem 1rem;
  border-radius: var(--radius);
  overflow-x: auto;
  font-size: 0.85rem;
  margin: 0.5rem 0;
}
.preview-box code.inline {
  background: rgba(0,0,0,0.06);
  padding: 0.1rem 0.35rem;
  border-radius: 3px;
  font-size: 0.85em;
}
.preview-box img { border-radius: var(--radius); margin: 0.5rem 0; }
.preview-box del { text-decoration: line-through; color: var(--color-text-muted); }

.btn-danger {
  background: var(--color-danger);
  color: white;
}

.btn-sm {
  padding: 0.25rem 0.75rem;
  font-size: 0.8rem;
}

.alert-success {
  background: #dcfce7;
  color: #166534;
  padding: 0.75rem 1rem;
  border-radius: var(--radius);
  margin-bottom: 1rem;
}

.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
}

.modal-content {
  max-width: 480px;
  width: 90%;
}
</style>
