<script setup>
import { inject, ref } from 'vue'
import {
  localDateStr, fmtDate, fmtDur, shortAddr, dayLoadColor, stOf,
  ICON, jobSpansDate, techDayCapacityH, techDaySchedule, timeToH, expandRRule,
} from 'src/composables/useHelpers'
import { ABSENCE_REASONS } from 'src/composables/useTechManagement'

const props = defineProps({
  filteredResources: Array,
  dayColumns: Array,
  selectedTechId: String,
  dropGhost: Object,
  todayStr: String,
  colW: { type: Number, default: 0 },  // fixed column width (px), 0 = flex
})

const emit = defineEmits([
  'go-to-day', 'select-tech', 'ctx-tech',
  'tech-reorder-start', 'tech-reorder-drop',
  'cal-drop', 'job-dragstart', 'job-click', 'job-dblclick', 'job-ctx',
  'clear-filters',
  'open-absence', 'end-absence', 'open-schedule',
  'ghost-click', 'ghost-materialize',
])

const store = inject('store')
const TECH_COLORS = inject('TECH_COLORS')
const jobColor = inject('jobColor')
const selectedJob = inject('selectedJob')
const isJobMultiSelected = inject('isJobMultiSelected')
const ghostOccurrencesForDate = inject('ghostOccurrencesForDate', () => () => [])
const getTagColor = inject('getTagColor')
const planningMode = inject('planningMode', ref(false))

function isDayToday (d) { return localDateStr(d) === props.todayStr }

function isExplicitAbsent (tech, d) {
  if (tech.status !== 'off' || !tech.absenceFrom) return false
  const ds = localDateStr(d)
  const from = tech.absenceFrom
  const until = tech.absenceUntil || from
  return ds >= from && ds <= until
}

function isScheduleOff (tech, d) {
  const ds = localDateStr(d)
  return !techDaySchedule(tech, ds)
}

function isAbsentOnDay (tech, d) {
  return isExplicitAbsent(tech, d) || isScheduleOff(tech, d)
}

// Returns absence info for a given tech+day: { icon, label, isFullDay, hours, timeRange, remainH }
function absenceInfo (tech, d) {
  const ds = localDateStr(d)
  // Schedule off-day (always full day)
  if (isScheduleOff(tech, d) && !isExplicitAbsent(tech, d)) {
    return { icon: '📅', label: 'Repos', isFullDay: true, hours: 0, timeRange: null, remainH: 0 }
  }
  // Explicit absence
  const r = ABSENCE_REASONS.find(x => x.value === tech.absenceReason)
  const icon = r ? r.icon : '⏸'
  const label = r ? r.label : 'Absent'
  const sched = techDaySchedule(tech, ds)
  const schedStartH = sched ? sched.startH : 8
  const schedEndH = sched ? sched.endH : 16
  const schedHours = sched ? sched.hours : 8

  const absStartH = tech.absenceStartTime ? timeToH(tech.absenceStartTime) : schedStartH
  const absEndH = tech.absenceEndTime ? timeToH(tech.absenceEndTime) : schedEndH
  const absHours = Math.max(0, absEndH - absStartH)
  const isFullDay = absStartH <= schedStartH && absEndH >= schedEndH
  const remainH = Math.max(0, schedHours - absHours)

  const fmt = h => { const hh = Math.floor(h); const mm = Math.round((h - hh) * 60); return hh + 'h' + (mm ? (mm < 10 ? '0' : '') + mm : '') }
  const timeRange = !isFullDay ? fmt(absStartH) + '–' + fmt(absEndH) : null

  return { icon, label, isFullDay, hours: absHours, timeRange, remainH }
}

// ── Planning mode: schedule availability info per tech/day ──────────────────
function scheduleInfoForDay (tech, d) {
  const ds = localDateStr(d)
  const sched = techDaySchedule(tech, ds)
  const info = { available: false, label: '', start: '', end: '', isOnCall: false, onCallLabel: '' }
  if (sched) {
    info.available = true
    info.start = sched.start
    info.end = sched.end
    info.label = `${sched.start} – ${sched.end}`
  }
  // Check for on-call / extra shifts
  const extras = (tech.extraShifts || []).filter(s => {
    if (!s.rrule || !s.startTime || !s.endTime) return false
    const dates = expandRRule(s.rrule, s.from || ds, ds, ds, [])
    return dates.includes(ds)
  })
  if (extras.length) {
    const ex = extras[0]
    info.isOnCall = true
    info.onCallLabel = `${ex.label || 'Garde'}: ${ex.startTime} – ${ex.endTime}`
  }
  return info
}

defineExpose({ isDayToday })
</script>

<template>
<div class="sb-grid sb-grid-cal" :style="colW ? 'min-width:'+(200 + colW * dayColumns.length)+'px' : ''">
  <!-- Header -->
  <div class="sb-grid-hdr">
    <div class="sb-res-hdr">Ressources <span class="sbf-count">{{ filteredResources.length }}</span></div>
    <div class="sb-cal-hdr" :style="colW ? 'flex:none;width:'+(colW * dayColumns.length)+'px' : ''">
      <div v-for="d in dayColumns" :key="'ch-'+localDateStr(d)"
           class="sb-cal-hdr-cell" :class="{ 'sb-col-today': isDayToday(d) }"
           :style="colW ? 'flex:none;width:'+colW+'px' : ''"
           style="cursor:pointer" @click="emit('go-to-day', d)">
        <span class="sb-cal-wd">{{ fmtDate(d, {weekday:'short'}) }}</span>
        <span class="sb-cal-dn" :class="{ 'sb-today-bubble': isDayToday(d) }">{{ d.getDate() }}</span>
      </div>
    </div>
  </div>

  <!-- Loading / empty -->
  <div v-if="store.loading" class="sb-loading-row">Chargement…</div>
  <div v-else-if="!filteredResources.length" class="sb-empty-row">
    Aucune ressource.
    <button class="sbf-primary-btn" style="display:inline-block;margin-left:0.75rem" @click="emit('clear-filters')">Réinitialiser</button>
  </div>

  <!-- Rows -->
  <div v-for="tech in filteredResources" :key="tech.id"
       class="sb-row sb-row-cal" :class="{ 'sb-row-sel': selectedTechId===tech.id, 'sb-row-absent': tech.status==='off' }">
    <div class="sb-res-cell" @click="emit('select-tech', tech)" @contextmenu.prevent="emit('ctx-tech', $event, tech)"
         draggable="true" @dragstart="emit('tech-reorder-start', $event, tech)"
         @dragover.prevent="()=>{}" @drop.prevent="emit('tech-reorder-drop', $event, tech)">
      <div class="sb-avatar" :style="'background:'+TECH_COLORS[tech.colorIdx]">
        {{ tech.fullName.split(' ').map(n=>n[0]).join('').toUpperCase().slice(0,2) }}
      </div>
      <div class="sb-res-info">
        <div class="sb-res-name">{{ tech.fullName }}
          <span v-for="t in (tech.tags||[]).slice(0,3)" :key="t" class="sb-res-tag-dot" :style="'background:'+getTagColor(t)" :title="t"></span>
        </div>
        <div class="sb-res-sub">
          <span class="sb-st" :class="stOf(tech).cls">{{ stOf(tech).label }}</span>
          <span v-if="tech.status === 'off' && tech.absenceReason" class="sb-res-absence-tag">{{ tech.absenceReason }}</span>
        </div>
        <div class="sb-res-actions">
          <button @click.stop="emit('open-schedule', tech)" title="Horaire hebdo">🗓</button>
          <button v-if="tech.status !== 'off'" @click.stop="emit('open-absence', tech)" title="Mettre en absence">⏸</button>
          <button v-else @click.stop="emit('end-absence', tech)" title="Fin d'absence" class="sb-act-play">▶</button>
        </div>
      </div>
    </div>
    <div class="sb-cal-row" :style="colW ? 'flex:none;width:'+(colW * dayColumns.length)+'px' : ''">
      <div v-for="d in dayColumns" :key="localDateStr(d)"
           class="sb-cal-cell" :class="{ 'sb-bg-today': isDayToday(d), 'sb-bg-alt': dayColumns.indexOf(d)%2===1, 'sb-cal-absent': isExplicitAbsent(tech, d) || (planningMode && isScheduleOff(tech, d) && !isExplicitAbsent(tech, d)) }"
           :style="colW ? 'flex:none;width:'+colW+'px' : ''"
           :data-date-str="localDateStr(d)"
           @dblclick="emit('go-to-day', d)"
           @dragover.prevent="()=>{}" @dragleave="()=>{}"
           @drop.prevent="emit('cal-drop', $event, tech, localDateStr(d))">
        <div v-if="dropGhost?.techId===tech.id && dropGhost.dateStr===localDateStr(d)" class="sb-cal-drop"></div>
        <!-- Planning mode: availability band -->
        <div v-if="planningMode && !isAbsentOnDay(tech, d) && scheduleInfoForDay(tech, d).available"
             class="sb-sched-band sb-sched-available"
             @click.stop="emit('open-schedule', tech)"
             :title="'Disponible: ' + scheduleInfoForDay(tech, d).label + ' — cliquer pour modifier'">
          <span class="sb-sched-time">{{ scheduleInfoForDay(tech, d).label }}</span>
        </div>
        <div v-if="planningMode && scheduleInfoForDay(tech, d).isOnCall"
             class="sb-sched-band sb-sched-oncall"
             @click.stop="emit('open-schedule', tech)"
             :title="scheduleInfoForDay(tech, d).onCallLabel + ' — cliquer pour modifier'">
          <span class="sb-sched-time">🔔 {{ scheduleInfoForDay(tech, d).onCallLabel }}</span>
        </div>
        <!-- Explicit absences always shown; schedule off-days only in planning mode -->
        <div v-if="isExplicitAbsent(tech, d)" class="sb-chip sb-chip-absence sb-chip-absence-full"
             :title="absenceInfo(tech, d).label + (absenceInfo(tech, d).timeRange ? ' ' + absenceInfo(tech, d).timeRange : '')">
          <div class="sb-chip-line1">{{ absenceInfo(tech, d).icon }} {{ absenceInfo(tech, d).label }}</div>
          <div v-if="absenceInfo(tech, d).isFullDay" class="sb-chip-line2 sb-absence-detail">Journée complète</div>
          <div v-else class="sb-chip-line2 sb-absence-detail">
            {{ absenceInfo(tech, d).timeRange }} · reste {{ fmtDur(absenceInfo(tech, d).remainH) }}
          </div>
        </div>
        <template v-for="job in [...tech.queue.filter(j=>jobSpansDate(j,localDateStr(d),tech)), ...(tech.assistJobs||[]).filter(j=>jobSpansDate(j,localDateStr(d),tech)&&j.assistants.find(a=>a.techId===tech.id)?.pinned).map(j=>({...j,_isAssistChip:true,_assistDur:j.assistants.find(a=>a.techId===tech.id)?.duration||j.duration})), ...ghostOccurrencesForDate(tech, localDateStr(d))]" :key="job.id+(job._isAssistChip?'-a':'')">
          <div v-if="job._isGhost" class="sb-chip sb-chip-ghost"
               :style="'border-left-color:'+jobColor(job)+';background:'+jobColor(job)+'33;color:#ffffffaa;border-style:dashed'"
               @click.stop="emit('ghost-click', job._templateJob||job, localDateStr(d), tech.id)"
               @dblclick.stop="emit('ghost-materialize', job._templateJob||job, localDateStr(d), tech.id)">
            <div class="sb-chip-line1">🔄 {{ job.subject }}</div>
            <div class="sb-chip-line2">{{ fmtDur(job.duration) }} · récurrent</div>
          </div>
          <div v-else class="sb-chip"
               :class="{ 'sb-chip-sel': selectedJob?.job?.id===job.id, 'sb-chip-multi': isJobMultiSelected(job.id), 'sb-chip-assist': job._isAssistChip }"
               :data-job-id="job.id"
               :style="'border-left-color:'+jobColor(job)+';background:'+jobColor(job)+'cc;color:#fff'"
               :draggable="job._isAssistChip ? 'false' : 'true'"
               @dragstart="!job._isAssistChip && emit('job-dragstart', $event, job, tech.id)"
               @click.stop="emit('job-click', job, tech.id, false, null, $event)"
               @dblclick.stop="emit('job-dblclick', job)"
               @contextmenu.prevent="emit('job-ctx', $event, job, tech.id)">
            <div class="sb-chip-line1">
              <span v-if="job.priority==='high'" class="sb-chip-urgent"></span>
              <span v-if="job._isAssistChip" class="sb-chip-assist-tag" v-html="ICON.pin"></span>
              {{ job.subject }}
            </div>
            <div v-if="job.address" class="sb-chip-line2"><span v-html="ICON.mapPin"></span> {{ shortAddr(job.address) }}</div>
          </div>
        </template>
        <!-- Day load bar -->
        <div v-if="[...tech.queue.filter(j=>jobSpansDate(j,localDateStr(d),tech))].length" class="sb-day-load">
          <div class="sb-day-load-track">
            <div class="sb-day-load-fill" :style="{ width: Math.min(100, tech.queue.filter(j=>jobSpansDate(j,localDateStr(d),tech)).reduce((a,j)=>a+(parseFloat(j.duration)||0),0)/(techDayCapacityH(tech,localDateStr(d))||8)*100)+'%', background: dayLoadColor(tech.queue.filter(j=>jobSpansDate(j,localDateStr(d),tech)).reduce((a,j)=>a+(parseFloat(j.duration)||0),0)/(techDayCapacityH(tech,localDateStr(d))||8)) }"></div>
          </div>
          <span class="sb-day-load-label">{{ fmtDur(tech.queue.filter(j=>jobSpansDate(j,localDateStr(d),tech)).reduce((a,j)=>a+(parseFloat(j.duration)||0),0)) }}/{{ fmtDur(techDayCapacityH(tech,localDateStr(d))||8) }}</span>
        </div>
      </div>
    </div>
  </div>
</div>
</template>
