<script setup>
/**
 * Google Calendar–style recurrence selector.
 * Generates context-aware quick options based on the reference date,
 * plus a "Personnalisé…" mode for full RRULE editing.
 *
 * Props:
 *   modelValue  — RRULE string (or '' / null for no recurrence)
 *   refDate     — YYYY-MM-DD reference date (for contextual labels)
 *   showNone    — show "Ne se répète pas" option (default true)
 *
 * Emits:
 *   update:modelValue — new RRULE string (or '' for none)
 */
import { ref, computed, watch } from 'vue'
import { buildRRule, parseRRule } from 'src/composables/useHelpers'

const props = defineProps({
  modelValue: { type: String, default: '' },
  refDate: { type: String, default: '' },
  showNone: { type: Boolean, default: true },
})
const emit = defineEmits(['update:modelValue'])

const DAY_NAMES_FR = { MO: 'lundi', TU: 'mardi', WE: 'mercredi', TH: 'jeudi', FR: 'vendredi', SA: 'samedi', SU: 'dimanche' }
const DAY_KEYS_BY_DOW = ['SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA']
const DAY_SHORT = [
  { k: 'MO', l: 'L' }, { k: 'TU', l: 'M' }, { k: 'WE', l: 'M' },
  { k: 'TH', l: 'J' }, { k: 'FR', l: 'V' }, { k: 'SA', l: 'S' }, { k: 'SU', l: 'D' },
]
const MONTH_NAMES_FR = ['janvier','février','mars','avril','mai','juin','juillet','août','septembre','octobre','novembre','décembre']

const showCustom = ref(false)
const customForm = ref({ freq: 'WEEKLY', interval: 1, byDay: [], byMonthDay: null })

// ── Derive context from refDate ─────────────────────────────────────────────
const refDateObj = computed(() => props.refDate ? new Date(props.refDate + 'T12:00:00') : new Date())
const refDow = computed(() => DAY_KEYS_BY_DOW[refDateObj.value.getDay()])
const refDowName = computed(() => DAY_NAMES_FR[refDow.value])
const refDayOfMonth = computed(() => refDateObj.value.getDate())
const refMonthName = computed(() => MONTH_NAMES_FR[refDateObj.value.getMonth()])

// Nth weekday of month (e.g., "le 2e mercredi")
const refNthWeekday = computed(() => {
  const d = refDateObj.value
  const nth = Math.ceil(d.getDate() / 7)
  const ordinals = ['', '1er', '2e', '3e', '4e', '5e']
  return { nth, ordinal: ordinals[nth] || nth + 'e', dayName: refDowName.value }
})

// ── Quick options (Google Calendar style) ───────────────────────────────────
const quickOptions = computed(() => {
  const opts = []
  if (props.showNone) opts.push({ label: 'Ne se répète pas', rrule: '' })
  opts.push({ label: 'Tous les jours', rrule: 'FREQ=DAILY' })
  opts.push({ label: `Toutes les semaines le ${refDowName.value}`, rrule: `FREQ=WEEKLY;BYDAY=${refDow.value}` })
  opts.push({ label: `Tous les mois le ${refNthWeekday.value.ordinal} ${refNthWeekday.value.dayName}`, rrule: `FREQ=MONTHLY;BYMONTHDAY=${refDayOfMonth.value}` })
  opts.push({ label: `Tous les ans le ${refDayOfMonth.value} ${refMonthName.value}`, rrule: `FREQ=YEARLY;BYMONTHDAY=${refDayOfMonth.value}` })
  opts.push({ label: 'Tous les jours de semaine (lun–ven)', rrule: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' })

  // If current RRULE is custom and doesn't match any quick option, show it as selected
  return opts
})

// ── Current selection ───────────────────────────────────────────────────────
const isCustom = computed(() => {
  if (!props.modelValue) return false
  return !quickOptions.value.some(o => o.rrule === props.modelValue)
})

const displayLabel = computed(() => {
  if (!props.modelValue) return props.showNone ? 'Ne se répète pas' : 'Récurrence…'
  const match = quickOptions.value.find(o => o.rrule === props.modelValue)
  if (match) return match.label
  return describeRRule(props.modelValue)
})

// ── Human-readable RRULE description ────────────────────────────────────────
function describeRRule (rrule) {
  if (!rrule) return 'Ne se répète pas'
  const p = parseRRule(rrule)
  const intervalStr = p.interval > 1 ? ` ${p.interval} ` : ' '
  if (p.freq === 'DAILY') return `Tous les${p.interval > 1 ? ' ' + p.interval : ''} jour${p.interval > 1 ? 's' : ''}`
  if (p.freq === 'WEEKLY') {
    const days = p.byDay.map(d => DAY_NAMES_FR[d] || d).join(', ')
    if (p.interval === 1) return days ? `Chaque semaine le ${days}` : 'Chaque semaine'
    return `Toutes les ${p.interval} semaines le ${days}`
  }
  if (p.freq === 'MONTHLY') {
    return `Tous les${intervalStr}mois le ${p.byMonthDay || refDayOfMonth.value}`
  }
  if (p.freq === 'YEARLY') return `Tous les${intervalStr}an${p.interval > 1 ? 's' : ''}`
  return rrule
}

// ── Dropdown state ──────────────────────────────────────────────────────────
const dropdownOpen = ref(false)

function selectOption (opt) {
  dropdownOpen.value = false
  showCustom.value = false
  emit('update:modelValue', opt.rrule)
}

function openCustom () {
  dropdownOpen.value = false
  const p = parseRRule(props.modelValue || `FREQ=WEEKLY;BYDAY=${refDow.value}`)
  customForm.value = { ...p }
  if (!customForm.value.byDay?.length) customForm.value.byDay = [refDow.value]
  showCustom.value = true
}

function applyCustom () {
  const rrule = buildRRule(customForm.value)
  showCustom.value = false
  emit('update:modelValue', rrule)
}

function toggleDay (day) {
  const idx = customForm.value.byDay.indexOf(day)
  if (idx >= 0) {
    if (customForm.value.byDay.length > 1) customForm.value.byDay.splice(idx, 1)
  } else {
    customForm.value.byDay.push(day)
  }
}

// Close dropdown on outside click
function onClickOutside (e) {
  if (!e.target.closest('.rc-sel-wrap')) dropdownOpen.value = false
}
</script>

<template>
<div class="rc-sel-wrap" v-click-outside="() => dropdownOpen = false">
  <!-- Selected value display -->
  <button class="rc-sel-btn" @click="dropdownOpen = !dropdownOpen" type="button">
    <span class="rc-sel-label">{{ displayLabel }}</span>
    <span class="rc-sel-arrow">{{ dropdownOpen ? '▲' : '▼' }}</span>
  </button>

  <!-- Dropdown -->
  <transition name="rc-fade">
    <div v-if="dropdownOpen" class="rc-dropdown">
      <button v-for="opt in quickOptions" :key="opt.rrule"
              class="rc-opt" :class="{ 'rc-opt-active': opt.rrule === modelValue }"
              @click="selectOption(opt)">
        {{ opt.label }}
      </button>
      <div class="rc-sep"></div>
      <button class="rc-opt rc-opt-custom" :class="{ 'rc-opt-active': isCustom }"
              @click="openCustom">
        Personnalisé…
      </button>
    </div>
  </transition>

  <!-- Custom editor (inline, below the selector) -->
  <transition name="rc-fade">
    <div v-if="showCustom" class="rc-custom">
      <div class="rc-custom-hdr">
        <span>Récurrence personnalisée</span>
        <button class="rc-custom-close" @click="showCustom = false">✕</button>
      </div>

      <!-- Frequency + Interval -->
      <div class="rc-custom-row">
        <span class="rc-custom-lbl">Chaque</span>
        <input type="number" v-model.number="customForm.interval" min="1" max="99" class="rc-input rc-input-num" />
        <select v-model="customForm.freq" class="rc-input rc-input-sel">
          <option value="DAILY">jour(s)</option>
          <option value="WEEKLY">semaine(s)</option>
          <option value="MONTHLY">mois</option>
          <option value="YEARLY">an(s)</option>
        </select>
      </div>

      <!-- Day picker (WEEKLY) -->
      <div v-if="customForm.freq === 'WEEKLY'" class="rc-custom-row rc-day-row">
        <span class="rc-custom-lbl">Le</span>
        <button v-for="d in DAY_SHORT" :key="d.k"
                class="rc-day-btn" :class="{ active: customForm.byDay.includes(d.k) }"
                @click="toggleDay(d.k)">
          {{ d.l }}
        </button>
      </div>

      <!-- Day of month (MONTHLY) -->
      <div v-if="customForm.freq === 'MONTHLY'" class="rc-custom-row">
        <span class="rc-custom-lbl">Le jour</span>
        <input type="number" v-model.number="customForm.byMonthDay" min="1" max="31" class="rc-input rc-input-num" />
        <span class="rc-custom-hint">du mois</span>
      </div>

      <!-- Preview -->
      <div class="rc-preview">{{ describeRRule(buildRRule(customForm)) }}</div>

      <div class="rc-custom-actions">
        <button class="rc-btn rc-btn-cancel" @click="showCustom = false">Annuler</button>
        <button class="rc-btn rc-btn-apply" @click="applyCustom">Appliquer</button>
      </div>
    </div>
  </transition>
</div>
</template>

<script>
// v-click-outside directive
export default {
  directives: {
    'click-outside': {
      mounted (el, binding) {
        el._clickOutside = e => { if (!el.contains(e.target)) binding.value() }
        document.addEventListener('click', el._clickOutside)
      },
      unmounted (el) { document.removeEventListener('click', el._clickOutside) },
    },
  },
}
</script>

<style lang="scss">
.rc-sel-wrap { position: relative; display: inline-block; width: 100%; }
.rc-sel-btn {
  display: flex; align-items: center; justify-content: space-between; width: 100%;
  background: var(--sb-bg, #0d1017); border: 1px solid var(--sb-border, rgba(255,255,255,0.08));
  border-radius: 6px; color: var(--sb-text, #e2e4ef); font-size: 0.78rem;
  padding: 6px 10px; cursor: pointer; transition: border-color 0.12s;
  &:hover { border-color: var(--sb-border-acc, rgba(99,102,241,0.4)); }
}
.rc-sel-label { flex: 1; text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rc-sel-arrow { font-size: 0.55rem; margin-left: 6px; opacity: 0.5; }

.rc-dropdown {
  position: absolute; z-index: 200; top: calc(100% + 4px); left: 0; right: 0;
  background: var(--sb-card, #151820); border: 1px solid var(--sb-border, rgba(255,255,255,0.1));
  border-radius: 8px; padding: 4px 0; box-shadow: 0 8px 24px rgba(0,0,0,0.4);
  max-height: 320px; overflow-y: auto;
}
.rc-opt {
  display: block; width: 100%; text-align: left; border: none; background: none;
  color: var(--sb-text, #e2e4ef); font-size: 0.78rem; padding: 8px 14px;
  cursor: pointer; transition: background 0.1s;
  &:hover { background: rgba(255,255,255,0.06); }
  &.rc-opt-active { background: rgba(99,102,241,0.15); color: #a5b4fc; }
}
.rc-opt-custom { font-style: italic; color: var(--sb-muted, #9ca3af); }
.rc-sep { height: 1px; background: var(--sb-border, rgba(255,255,255,0.06)); margin: 2px 8px; }

.rc-custom {
  margin-top: 8px; padding: 10px 12px;
  background: var(--sb-card, #151820); border: 1px solid var(--sb-border, rgba(255,255,255,0.1));
  border-radius: 8px;
}
.rc-custom-hdr {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 8px; font-size: 0.78rem; font-weight: 600; color: var(--sb-text, #e2e4ef);
}
.rc-custom-close { background: none; border: none; color: var(--sb-muted); cursor: pointer; font-size: 0.8rem; }
.rc-custom-row { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; flex-wrap: wrap; }
.rc-custom-lbl { font-size: 0.72rem; color: var(--sb-muted, #9ca3af); min-width: 38px; }
.rc-custom-hint { font-size: 0.72rem; color: var(--sb-muted); }

.rc-input {
  background: var(--sb-bg, #0d1017); border: 1px solid var(--sb-border, rgba(255,255,255,0.08));
  border-radius: 4px; color: var(--sb-text, #e2e4ef); font-size: 0.75rem; padding: 4px 6px;
  outline: none; transition: border-color 0.12s;
  &:focus { border-color: var(--sb-acc, #6366f1); }
}
.rc-input-num { width: 48px; text-align: center; }
.rc-input-sel { width: auto; }

.rc-day-row { gap: 4px; }
.rc-day-btn {
  width: 28px; height: 28px; border-radius: 50%; border: 1px solid var(--sb-border, rgba(255,255,255,0.1));
  background: none; color: var(--sb-text, #c8cad6); font-size: 0.68rem; font-weight: 600;
  cursor: pointer; transition: all 0.12s; display: flex; align-items: center; justify-content: center;
  &:hover { border-color: var(--sb-acc, #6366f1); }
  &.active { background: var(--sb-acc, #6366f1); color: #fff; border-color: var(--sb-acc, #6366f1); }
}

.rc-preview {
  font-size: 0.72rem; color: var(--sb-acc, #a5b4fc); padding: 4px 0;
  border-top: 1px solid var(--sb-border, rgba(255,255,255,0.06));
  margin-top: 4px; font-style: italic;
}

.rc-custom-actions { display: flex; justify-content: flex-end; gap: 6px; margin-top: 6px; }
.rc-btn {
  border: none; border-radius: 5px; font-size: 0.72rem; font-weight: 500;
  padding: 5px 12px; cursor: pointer; transition: background 0.12s;
}
.rc-btn-cancel { background: rgba(255,255,255,0.06); color: var(--sb-muted); &:hover { background: rgba(255,255,255,0.1); } }
.rc-btn-apply { background: var(--sb-acc, #6366f1); color: #fff; &:hover { filter: brightness(1.1); } }

.rc-fade-enter-active, .rc-fade-leave-active { transition: opacity 0.12s, transform 0.12s; }
.rc-fade-enter-from, .rc-fade-leave-to { opacity: 0; transform: translateY(-4px); }
</style>
