<template>
  <div class="contribuer-page">
    <div class="contribuer-inner">
      <!-- Retour -->
      <NuxtLink to="/pratiques-regeneratives" class="back-link">
        ← Retour à la carte
      </NuxtLink>

      <!-- En-tête -->
      <div class="contribuer-header">
        <h1>Proposer une pratique</h1>
        <p class="contribuer-subtitle">
          Tu connais une agence, un collectif ou un réseau qui incarne l'architecture régénérative ?
          Soumets-le ici — Jules valide manuellement les nouvelles entrées.
        </p>
        <p class="contribuer-hint">
          Si tu n'as pas le temps de tout remplir, laisse-nous juste le lien.
          Mais une description de ta main, c'est toujours plus vivant.
        </p>
      </div>

      <!-- Message succès -->
      <div v-if="success" class="success-block" role="status" aria-live="polite">
        <div class="success-icon">✓</div>
        <h2>Merci !</h2>
        <p>Ta proposition est en attente de modération.</p>
        <p class="success-detail">
          Jules valide manuellement chaque entrée avant publication.
        </p>
        <button type="button" class="btn-secondary" @click="reset">
          Proposer une autre pratique
        </button>
      </div>

      <!-- Formulaire -->
      <form v-else @submit.prevent="submit" class="contribuer-form" novalidate>

        <!-- Nom -->
        <div class="field-group" :class="{ 'field-error': errors.nom }">
          <label for="nom">Nom de l'organisation <span class="required">*</span></label>
          <input
            id="nom"
            v-model="form.nom"
            type="text"
            placeholder="Ex : Lacaton & Vassal, Plateau Urbain..."
            autocomplete="organization"
            @blur="validateField('nom')"
          />
          <span v-if="errors.nom" class="error-msg" role="alert">{{ errors.nom }}</span>
        </div>

        <!-- URL -->
        <div class="field-group" :class="{ 'field-error': errors.url }">
          <label for="url">
            Site web
            <span class="label-hint">(optionnel — recommandé)</span>
          </label>
          <input
            id="url"
            v-model="form.url"
            type="url"
            placeholder="https://..."
            @blur="validateField('url')"
          />
          <span v-if="errors.url" class="error-msg" role="alert">{{ errors.url }}</span>
        </div>

        <!-- Description -->
        <div class="field-group" :class="{ 'field-error': errors.description_user }">
          <label for="description_user">
            Description courte <span class="required">*</span>
            <span class="label-hint">(50 à 500 caractères)</span>
          </label>
          <textarea
            id="description_user"
            v-model="form.description_user"
            rows="4"
            placeholder="Décris cette pratique : approche, matériaux, posture, ce qui la rend régénérative..."
            @blur="validateField('description_user')"
          />
          <div class="field-meta">
            <span v-if="errors.description_user" class="error-msg" role="alert">
              {{ errors.description_user }}
            </span>
            <span v-else class="char-count" :class="{ 'char-warn': form.description_user.length > 450 }">
              {{ form.description_user.length }}/500
            </span>
          </div>
        </div>

        <!-- Critères régénératifs -->
        <div class="field-group" :class="{ 'field-error': errors.criteres }">
          <fieldset>
            <legend>
              Critères régénératifs <span class="required">*</span>
              <span class="label-hint">(3 minimum, 8 maximum)</span>
            </legend>
            <div class="checkbox-grid">
              <label
                v-for="c in CRITERES"
                :key="c.id"
                class="checkbox-label"
                :class="{
                  active: form.criteres.includes(c.id),
                  disabled: !form.criteres.includes(c.id) && form.criteres.length >= 8,
                }"
              >
                <input
                  type="checkbox"
                  :value="c.id"
                  :checked="form.criteres.includes(c.id)"
                  :disabled="!form.criteres.includes(c.id) && form.criteres.length >= 8"
                  @change="toggleCritere(c.id)"
                />
                {{ c.label }}
              </label>
            </div>
          </fieldset>
          <span v-if="errors.criteres" class="error-msg" role="alert">{{ errors.criteres }}</span>
        </div>

        <!-- Type d'entité -->
        <div class="field-group" :class="{ 'field-error': errors.type }">
          <fieldset>
            <legend>
              Type d'entité <span class="required">*</span>
            </legend>
            <div class="radio-group">
              <label
                v-for="t in TYPES_ENTITE"
                :key="t"
                class="radio-label"
                :class="{ active: form.type === t }"
              >
                <input
                  type="radio"
                  :value="t"
                  v-model="form.type"
                  name="type"
                  @change="validateField('type')"
                />
                {{ TYPES_ENTITE_LABELS[t] }}
              </label>
            </div>
          </fieldset>
          <span v-if="errors.type" class="error-msg" role="alert">{{ errors.type }}</span>
        </div>

        <!-- Pays -->
        <div class="field-group" :class="{ 'field-error': errors.pays }">
          <label for="pays">
            Pays <span class="required">*</span>
          </label>
          <select
            id="pays"
            v-model="form.pays"
            @change="validateField('pays')"
          >
            <option value="" disabled>Sélectionne un pays...</option>
            <optgroup label="Europe">
              <option v-for="code in EUROPE_CODES" :key="code" :value="code">
                {{ PAYS_LABELS[code] }}
              </option>
            </optgroup>
            <optgroup label="DOM-TOM">
              <option v-for="code in OUTREMER_CODES" :key="code" :value="code">
                {{ PAYS_LABELS[code] }}
              </option>
            </optgroup>
            <optgroup label="Autre">
              <option value="AUTRE">Autre pays...</option>
            </optgroup>
          </select>
          <span v-if="errors.pays" class="error-msg" role="alert">{{ errors.pays }}</span>
        </div>

        <!-- Pays autre (conditionnel) -->
        <div v-if="form.pays === 'AUTRE'" class="field-group" :class="{ 'field-error': errors.pays_autre }">
          <label for="pays_autre">Précise le pays</label>
          <input
            id="pays_autre"
            v-model="form.pays_autre"
            type="text"
            placeholder="Ex : Maroc, Brésil..."
            maxlength="50"
          />
          <span v-if="errors.pays_autre" class="error-msg" role="alert">{{ errors.pays_autre }}</span>
        </div>

        <!-- Ville -->
        <div class="field-group" :class="{ 'field-error': errors.ville }">
          <label for="ville">
            Ville principale
            <span class="label-hint">(optionnel)</span>
          </label>
          <input
            id="ville"
            v-model="form.ville"
            type="text"
            placeholder="Ex : Paris, Bordeaux, Bruxelles..."
          />
          <span v-if="errors.ville" class="error-msg" role="alert">{{ errors.ville }}</span>
        </div>

        <!-- Tags -->
        <div class="field-group" :class="{ 'field-error': errors.tags }">
          <label for="tags">
            Tags
            <span class="label-hint">(optionnel — 3 à 6 mots-clés, séparés par des virgules)</span>
          </label>
          <input
            id="tags"
            v-model="tagsInput"
            type="text"
            placeholder="Ex : biosourcé, réhabilitation, circuit-court"
            @blur="parseTags"
          />
          <span v-if="errors.tags" class="error-msg" role="alert">{{ errors.tags }}</span>
          <div v-if="form.tags && form.tags.length" class="tags-preview">
            <span v-for="tag in form.tags" :key="tag" class="tag-chip">{{ tag }}</span>
          </div>
        </div>

        <!-- Email -->
        <div class="field-group" :class="{ 'field-error': errors.submitted_by_email }">
          <label for="submitted_by_email">
            Ton email
            <span class="label-hint">(optionnel — pour le suivi)</span>
          </label>
          <input
            id="submitted_by_email"
            v-model="form.submitted_by_email"
            type="email"
            placeholder="ton@email.fr"
            autocomplete="email"
            @blur="validateField('submitted_by_email')"
          />
          <span v-if="errors.submitted_by_email" class="error-msg" role="alert">
            {{ errors.submitted_by_email }}
          </span>
        </div>

        <!-- Erreur globale -->
        <div v-if="serverError" class="server-error" role="alert">
          <strong>Erreur :</strong> {{ serverError }}
        </div>

        <!-- Actions -->
        <div class="form-actions">
          <NuxtLink to="/pratiques-regeneratives" class="btn-secondary">Annuler</NuxtLink>
          <button
            type="submit"
            class="btn-primary"
            :disabled="submitting"
          >
            {{ submitting ? 'Envoi en cours...' : 'Proposer la pratique →' }}
          </button>
        </div>

        <p class="form-note">
          Ta proposition sera examinée par Jules avant publication.
        </p>
      </form>
    </div>
  </div>
</template>

<script setup lang="ts">
import { z } from 'zod'
import { CRITERES, TYPES_ENTITE, TYPES_ENTITE_LABELS, EUROPE_CODES, OUTREMER_CODES, PAYS_LABELS } from '~/types/pratique'

// ── Schéma Zod (côté client — miroir du serveur) ──────────────────────────────

const PratiqueSubmitSchema = z.object({
  nom: z.string().min(3, 'Minimum 3 caractères').max(150, 'Maximum 150 caractères').trim(),
  url: z.string().url('URL invalide (commencer par https://)').optional().or(z.literal('')),
  description_user: z.string().min(50, 'Minimum 50 caractères').max(500, 'Maximum 500 caractères').trim(),
  criteres: z
    .array(z.number().int().min(1).max(8))
    .min(3, 'Sélectionne au moins 3 critères')
    .max(8, 'Maximum 8 critères'),
  pays: z.string().length(2, 'Sélectionne un pays').or(z.literal('AUTRE')),
  pays_autre: z.string().max(50).optional(),
  ville: z.string().max(100).optional(),
  type: z.enum(TYPES_ENTITE, { errorMap: () => ({ message: 'Sélectionne un type d\'entité' }) }),
  tags: z.array(z.string().max(30)).max(6).optional(),
  submitted_by_email: z.string().email('Email invalide').optional().or(z.literal('')),
})

// ── État du formulaire ────────────────────────────────────────────────────────

const form = reactive({
  nom: '',
  url: '',
  description_user: '',
  criteres: [] as number[],
  pays: '' as string,
  pays_autre: '',
  ville: '',
  type: '' as typeof TYPES_ENTITE[number] | '',
  tags: [] as string[],
  submitted_by_email: '',
})

const tagsInput = ref('')
const errors = reactive<Record<string, string>>({})
const submitting = ref(false)
const success = ref(false)
const serverError = ref('')

// ── Validation champ par champ ────────────────────────────────────────────────

function validateField(field: string) {
  const partial = PratiqueSubmitSchema.partial()
  const result = partial.safeParse({ [field]: (form as any)[field] })
  if (!result.success) {
    const fieldErrors = result.error.flatten().fieldErrors
    errors[field] = fieldErrors[field]?.[0] ?? ''
  } else {
    delete errors[field]
  }
}

function validateAll(): boolean {
  const result = PratiqueSubmitSchema.safeParse(form)
  if (!result.success) {
    const flat = result.error.flatten().fieldErrors
    Object.assign(errors, Object.fromEntries(
      Object.entries(flat).map(([k, v]) => [k, v?.[0] ?? ''])
    ))
    return false
  }
  Object.keys(errors).forEach(k => delete errors[k])
  return true
}

// ── Gestion critères ──────────────────────────────────────────────────────────

function toggleCritere(id: number) {
  const idx = form.criteres.indexOf(id)
  if (idx >= 0) {
    form.criteres.splice(idx, 1)
  } else if (form.criteres.length < 8) {
    form.criteres.push(id)
  }
  validateField('criteres')
}

// ── Gestion tags ──────────────────────────────────────────────────────────────

function parseTags() {
  const raw = tagsInput.value
    .split(',')
    .map(t => t.trim().toLowerCase())
    .filter(t => t.length > 0 && t.length <= 30)
    .slice(0, 6)
  form.tags = raw
}

// ── Soumission ────────────────────────────────────────────────────────────────

async function submit() {
  serverError.value = ''
  parseTags()

  if (!validateAll()) {
    await nextTick()
    const firstError = document.querySelector('.field-error')
    firstError?.scrollIntoView({ behavior: 'smooth', block: 'center' })
    return
  }

  submitting.value = true

  try {
    await $fetch('/api/submit-pratique', {
      method: 'POST',
      body: {
        nom: form.nom,
        url: form.url || undefined,
        description_user: form.description_user,
        criteres: form.criteres,
        pays: form.pays,
        pays_autre: form.pays_autre || undefined,
        ville: form.ville || undefined,
        type: form.type,
        tags: form.tags.length ? form.tags : undefined,
        submitted_by_email: form.submitted_by_email || undefined,
      },
    })

    success.value = true
  } catch (e: any) {
    const status = e?.status ?? e?.statusCode
    if (status === 429) {
      serverError.value = 'Tu as déjà soumis 3 pratiques aujourd\'hui. Réessaie demain.'
    } else if (status === 422 && e?.data) {
      const fieldErrors = e.data
      Object.entries(fieldErrors).forEach(([k, v]) => {
        errors[k] = Array.isArray(v) ? v[0] : String(v)
      })
      serverError.value = 'Certains champs sont invalides — vérifie les erreurs ci-dessus.'
    } else {
      serverError.value = 'Une erreur s\'est produite. Réessaie dans quelques instants.'
    }
  } finally {
    submitting.value = false
  }
}

function reset() {
  Object.assign(form, {
    nom: '', url: '', description_user: '', criteres: [],
    pays: '', pays_autre: '', ville: '', type: '', tags: [], submitted_by_email: '',
  })
  tagsInput.value = ''
  Object.keys(errors).forEach(k => delete errors[k])
  success.value = false
  serverError.value = ''
}

// ── Meta ──────────────────────────────────────────────────────────────────────

useHead({ title: 'Proposer une pratique — AEP' })
</script>

<style scoped>
/* ── Layout ─────────────────────────────────────────────────────────────────── */

.contribuer-page {
  min-height: 100vh;
  background: var(--nav-bg);
  padding: 1.5rem 1rem 4rem;
}

.contribuer-inner {
  max-width: 640px;
  margin: 0 auto;
}

/* ── Retour ──────────────────────────────────────────────────────────────────── */

.back-link {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.875rem;
  color: var(--nav-primary-solid);
  opacity: 0.7;
  text-decoration: none;
  margin-bottom: 1.5rem;
  transition: opacity 0.15s;
}

.back-link:hover {
  opacity: 1;
}

/* ── En-tête ─────────────────────────────────────────────────────────────────── */

.contribuer-header {
  margin-bottom: 2rem;
}

.contribuer-header h1 {
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--nav-text);
  margin: 0 0 0.5rem;
}

.contribuer-subtitle {
  font-size: 0.9rem;
  color: var(--nav-text-muted);
  line-height: 1.5;
  margin: 0 0 0.5rem;
}

.contribuer-hint {
  font-size: 0.82rem;
  color: var(--nav-text-muted);
  opacity: 0.75;
  line-height: 1.5;
  margin: 0;
}

/* ── Succès ──────────────────────────────────────────────────────────────────── */

.success-block {
  background: var(--nav-surface);
  border: 1px solid rgba(26, 34, 56, 0.15);
  border-radius: 12px;
  padding: 2rem 1.5rem;
  text-align: center;
}

.success-icon {
  width: 48px;
  height: 48px;
  background: rgba(26, 34, 56, 0.1);
  color: var(--nav-text);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.25rem;
  font-weight: 700;
  margin: 0 auto 1rem;
}

.success-block h2 {
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--nav-text);
  margin: 0 0 0.5rem;
}

.success-block p {
  font-size: 0.9rem;
  color: var(--nav-text-muted);
  margin: 0 0 0.5rem;
  line-height: 1.5;
}

.success-detail {
  font-size: 0.85rem !important;
}

/* ── Formulaire ──────────────────────────────────────────────────────────────── */

.contribuer-form {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

/* ── Champ générique ─────────────────────────────────────────────────────────── */

.field-group {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.field-group label,
.field-group legend {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--nav-text);
  display: block;
}

.field-group fieldset {
  border: none;
  padding: 0;
  margin: 0;
}

.required {
  color: #c0392b;
}

.label-hint {
  font-weight: 400;
  color: var(--nav-text-muted);
  font-size: 0.8rem;
  margin-left: 0.25rem;
}

.field-group input[type="text"],
.field-group input[type="url"],
.field-group input[type="email"],
.field-group select,
.field-group textarea {
  width: 100%;
  padding: 0.625rem 0.875rem;
  border: 1px solid rgba(26, 34, 56, 0.2);
  border-radius: 8px;
  font-size: 0.9rem;
  color: var(--nav-text);
  background: var(--nav-surface);
  font-family: inherit;
  transition: border-color 0.15s, box-shadow 0.15s;
  box-sizing: border-box;
}

.field-group select {
  cursor: pointer;
  appearance: auto;
}

.field-group input:focus,
.field-group select:focus,
.field-group textarea:focus {
  outline: none;
  border-color: var(--nav-primary-solid);
  box-shadow: 0 0 0 2px rgba(245, 179, 66, 0.4);
}

.field-group textarea {
  resize: vertical;
  min-height: 100px;
}

/* Erreur champ */

.field-error input,
.field-error select,
.field-error textarea {
  border-color: #c0392b !important;
}

.error-msg {
  font-size: 0.8rem;
  color: #c0392b;
}

.field-meta {
  display: flex;
  justify-content: flex-end;
}

.char-count {
  font-size: 0.75rem;
  color: var(--nav-text-muted);
}

.char-warn {
  color: #e67e22;
}

/* ── Radio (Type entité) ─────────────────────────────────────────────────────── */

.radio-group {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.375rem;
}

.radio-label {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.375rem 0.75rem;
  border: 1px solid rgba(26, 34, 56, 0.2);
  border-radius: 6px;
  font-size: 0.85rem;
  color: var(--nav-text);
  background: var(--nav-surface);
  cursor: pointer;
  transition: all 0.15s;
  user-select: none;
}

.radio-label input[type="radio"] {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.radio-label:hover {
  border-color: var(--nav-primary-solid);
  background: var(--nav-bg-alt);
}

.radio-label.active {
  background: var(--nav-primary);
  border-color: transparent;
  color: var(--nav-text-on-primary);
}

/* ── Checkboxes (Critères) ───────────────────────────────────────────────────── */

.checkbox-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.5rem;
  margin-top: 0.375rem;
}

@media (max-width: 400px) {
  .checkbox-grid {
    grid-template-columns: 1fr;
  }
}

.checkbox-label {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.375rem 0.75rem;
  border: 1px solid rgba(26, 34, 56, 0.2);
  border-radius: 6px;
  font-size: 0.85rem;
  color: var(--nav-text);
  background: var(--nav-surface);
  cursor: pointer;
  transition: all 0.15s;
  user-select: none;
}

.checkbox-label input[type="checkbox"] {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.checkbox-label:hover:not(.disabled) {
  border-color: var(--nav-primary-solid);
  background: var(--nav-bg-alt);
}

.checkbox-label.active {
  background: var(--nav-primary);
  border-color: transparent;
  color: var(--nav-text-on-primary);
}

.checkbox-label.disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* ── Tags preview ────────────────────────────────────────────────────────────── */

.tags-preview {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
  margin-top: 0.25rem;
}

.tag-chip {
  display: inline-flex;
  align-items: center;
  padding: 0.2rem 0.6rem;
  background: var(--nav-bg-alt);
  border: 1px solid rgba(26, 34, 56, 0.15);
  border-radius: 100px;
  font-size: 0.78rem;
  color: var(--nav-text-muted);
}

/* ── Erreur serveur ──────────────────────────────────────────────────────────── */

.server-error {
  padding: 0.875rem 1rem;
  background: #fdf0ee;
  border: 1px solid #e74c3c;
  border-radius: 8px;
  font-size: 0.875rem;
  color: #c0392b;
}

/* ── Actions ──────────────────────────────────────────────────────────────────── */

.form-actions {
  display: flex;
  gap: 0.75rem;
  justify-content: flex-end;
  margin-top: 0.5rem;
}

.btn-primary {
  padding: 0.75rem 1.5rem;
  background: var(--nav-primary);
  color: var(--nav-text-on-primary);
  border: none;
  border-radius: 8px;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
  transition: background 0.15s, opacity 0.15s;
}

.btn-primary:hover:not(:disabled) {
  background: rgba(26, 34, 56, 0.75);
}

.btn-primary:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn-secondary {
  padding: 0.75rem 1.25rem;
  background: transparent;
  color: var(--nav-text-muted);
  border: 1px solid rgba(26, 34, 56, 0.2);
  border-radius: 8px;
  font-size: 0.9rem;
  cursor: pointer;
  font-family: inherit;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  transition: border-color 0.15s, color 0.15s;
}

.btn-secondary:hover {
  border-color: var(--nav-primary-solid);
  color: var(--nav-text);
}

.form-note {
  font-size: 0.75rem;
  color: var(--nav-text-muted);
  text-align: center;
  margin: 0;
}

/* ── Responsive ──────────────────────────────────────────────────────────────── */

@media (max-width: 480px) {
  .contribuer-page {
    padding: 1rem 0.75rem 3rem;
  }

  .form-actions {
    flex-direction: column-reverse;
  }

  .btn-primary,
  .btn-secondary {
    width: 100%;
    justify-content: center;
  }
}
</style>
