// ── 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'))

  // ── Grouped by date ──────────────────────────────────────────────────────────
  const unassignedGrouped = computed(() => {
    const today = todayStr
    const jobs = unscheduledJobs.value.slice()
    jobs.sort((a, b) => {
      const da = a.scheduledDate || '9999-99-99'
      const db = b.scheduledDate || '9999-99-99'
      const aToday = da === today ? 0 : 1
      const bToday = db === today ? 0 : 1
      if (aToday !== bToday) return aToday - bToday
      if (da !== db) return da.localeCompare(db)
      const prio = { high: 0, medium: 1, low: 2 }
      return (prio[a.priority] ?? 2) - (prio[b.priority] ?? 2)
    })
    const groups = []
    let currentDate = null
    jobs.forEach(job => {
      const d = job.scheduledDate || null
      if (d !== currentDate) {
        currentDate = d
        let label = d === today ? "Aujourd'hui" : d ? d : 'Sans date'
        if (d && d !== today) {
          label = fmtDate(new Date(d + 'T00:00:00'))
        }
        groups.push({ date: d, label, 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, startBottomResize,
    bottomSelected, toggleBottomSelect, selectAllBottom, clearBottomSelect, batchAssignBottom,
    dispatchCriteria, dispatchCriteriaModal, saveDispatchCriteria, moveCriterion,
    btColWidths, btColW, startColResize,
  }
}
