// ── Bottom panel composable: unassigned jobs table, multi-select, criteria ────
import { ref, computed, watch } from 'vue'
import { localDateStr, fmtDate } from './useHelpers'

export function useBottomPanel (store, todayStr, unscheduledJobs, { pushUndo, smartAssign, invalidateRoutes, periodStart }) {
  const bottomPanelOpen = ref(localStorage.getItem('sbv2-bottomPanel') !== 'false')
  const bottomPanelH    = ref(parseInt(localStorage.getItem('sbv2-bottomH')) || 220)
  watch(bottomPanelOpen, v => localStorage.setItem('sbv2-bottomPanel', v ? 'true' : 'false'))

  // ── Tri / regroupement (date · ville · priorité) ─────────────────────────────
  const bottomSort = ref(localStorage.getItem('sbv2-bottomSort') || 'date')
  watch(bottomSort, v => localStorage.setItem('sbv2-bottomSort', v))
  const PRIO = { urgent: 0, high: 1, medium: 2, low: 3 }
  // Ville : 2e segment de l'adresse libre, sinon 1er token du sujet avant « | » (tickets legacy), sinon vide.
  function cityOf (job) {
    const a = String(job.address || '')
    const parts = a.split(',').map(s => s.trim()).filter(Boolean)
    if (parts.length >= 2) return parts[1]
    const subj = String(job.subject || ''); if (subj.includes('|')) return subj.split('|')[0].trim()
    return parts[0] || ''
  }
  const unassignedGrouped = computed(() => {
    const today = todayStr
    const sort = bottomSort.value
    const jobs = unscheduledJobs.value.slice()
    const byDate = (a, b) => { // ordre secondaire : date (aujourd'hui d'abord)
      const da = a.scheduledDate || '9999-99-99'; const db = b.scheduledDate || '9999-99-99'
      const at = da === today ? 0 : 1; const bt = db === today ? 0 : 1
      return at !== bt ? at - bt : da.localeCompare(db)
    }
    jobs.sort((a, b) => {
      if (sort === 'priority') return (PRIO[a.priority] ?? 3) - (PRIO[b.priority] ?? 3) || byDate(a, b)
      if (sort === 'city') return cityOf(a).localeCompare(cityOf(b)) || byDate(a, b)
      return byDate(a, b) || ((PRIO[a.priority] ?? 3) - (PRIO[b.priority] ?? 3))
    })
    const keyOf = job => sort === 'priority' ? (job.priority || 'low') : sort === 'city' ? (cityOf(job) || 'Sans ville') : (job.scheduledDate || null)
    const labelOf = key => {
      if (sort === 'priority') return ({ urgent: '🔴 Urgent', high: '🟠 Élevée', medium: '🔵 Moyenne', low: '⚪ Basse' })[key] || key
      if (sort === 'city') return key
      return key === today ? "Aujourd'hui" : (key ? fmtDate(new Date(key + 'T00:00:00')) : 'Sans date')
    }
    const groups = []; let cur = Symbol('init')
    jobs.forEach(job => {
      const k = keyOf(job)
      if (k !== cur) { cur = k; groups.push({ key: String(k), date: sort === 'date' ? k : null, label: labelOf(k), jobs: [] }) }
      groups.at(-1).jobs.push(job)
    })
    return groups
  })

  // ── Resize ───────────────────────────────────────────────────────────────────
  function startBottomResize (e) {
    e.preventDefault()
    const startY = e.clientY, startH = bottomPanelH.value
    function onMove (ev) { bottomPanelH.value = Math.max(100, Math.min(window.innerHeight * 0.6, startH - (ev.clientY - startY))) }
    function onUp () { document.removeEventListener('mousemove', onMove); document.removeEventListener('mouseup', onUp); localStorage.setItem('sbv2-bottomH', String(bottomPanelH.value)) }
    document.addEventListener('mousemove', onMove); document.addEventListener('mouseup', onUp)
  }

  // ── Multi-select ─────────────────────────────────────────────────────────────
  const bottomSelected = ref(new Set())
  function toggleBottomSelect (jobId, event) {
    const s = new Set(bottomSelected.value)
    // Checkbox click: always toggle (no modifier needed)
    // Shift+click: range select
    if (event?.shiftKey && s.size) {
      const flat = unassignedGrouped.value.flatMap(g => g.jobs)
      const ids = flat.map(j => j.id)
      const lastId = [...s].pop()
      const fromIdx = ids.indexOf(lastId), toIdx = ids.indexOf(jobId)
      if (fromIdx >= 0 && toIdx >= 0) {
        const [lo, hi] = fromIdx < toIdx ? [fromIdx, toIdx] : [toIdx, fromIdx]
        for (let i = lo; i <= hi; i++) s.add(ids[i])
      }
    } else {
      // Simple toggle (no Ctrl needed)
      if (s.has(jobId)) s.delete(jobId); else s.add(jobId)
    }
    bottomSelected.value = s
  }
  function selectAllBottom () { const s = new Set(); unscheduledJobs.value.forEach(j => s.add(j.id)); bottomSelected.value = s }
  function clearBottomSelect () { bottomSelected.value = new Set() }
  function batchAssignBottom (techId) {
    const dayStr = localDateStr(periodStart.value)
    bottomSelected.value.forEach(jobId => {
      const job = store.jobs.find(j => j.id === jobId)
      if (job) {
        pushUndo({ type: 'unassignJob', jobId: job.id, techId: job.assignedTech, routeOrder: job.routeOrder, scheduledDate: job.scheduledDate, assistants: [...(job.assistants || [])] })
        smartAssign(job, techId, dayStr)
      }
    })
    bottomSelected.value = new Set()
    invalidateRoutes()
  }

  // ── Dispatch criteria ────────────────────────────────────────────────────────
  const defaultCriteria = [
    { id: 'urgency', label: 'Urgence (priorité haute en premier)', enabled: true },
    { id: 'balance', label: 'Équilibrage de charge (tech le moins chargé)', enabled: true },
    { id: 'proximity', label: 'Proximité géographique', enabled: true },
    { id: 'skills', label: 'Correspondance des tags/skills', enabled: false },
  ]
  const dispatchCriteria = ref(JSON.parse(localStorage.getItem('sbv2-dispatchCriteria') || 'null') || defaultCriteria.map(c => ({ ...c })))
  const dispatchCriteriaModal = ref(false)
  function saveDispatchCriteria () { localStorage.setItem('sbv2-dispatchCriteria', JSON.stringify(dispatchCriteria.value)); dispatchCriteriaModal.value = false }
  function moveCriterion (idx, dir) {
    const arr = dispatchCriteria.value, newIdx = idx + dir
    if (newIdx < 0 || newIdx >= arr.length) return
    const tmp = arr[idx]; arr[idx] = arr[newIdx]; arr[newIdx] = tmp
  }

  // ── Column widths ────────────────────────────────────────────────────────────
  const btColWidths = ref(JSON.parse(localStorage.getItem('sbv2-btColW') || '{}'))
  function btColW (col, def) { return (btColWidths.value[col] || def) + 'px' }
  function startColResize (e, col) {
    e.preventDefault(); e.stopPropagation()
    const startX = e.clientX, startW = btColWidths.value[col] || parseInt(getComputedStyle(e.target.parentElement).width)
    function onMove (ev) { btColWidths.value = { ...btColWidths.value, [col]: Math.max(40, startW + (ev.clientX - startX)) } }
    function onUp () { document.removeEventListener('mousemove', onMove); document.removeEventListener('mouseup', onUp); localStorage.setItem('sbv2-btColW', JSON.stringify(btColWidths.value)) }
    document.addEventListener('mousemove', onMove); document.addEventListener('mouseup', onUp)
  }

  return {
    bottomPanelOpen, bottomPanelH, unassignedGrouped, bottomSort, startBottomResize,
    bottomSelected, toggleBottomSelect, selectAllBottom, clearBottomSelect, batchAssignBottom,
    dispatchCriteria, dispatchCriteriaModal, saveDispatchCriteria, moveCriterion,
    btColWidths, btColW, startColResize,
  }
}
