import { useMemo, useState } from 'react'
import { format, startOfWeek, addDays, addWeeks, isToday } from 'date-fns'
import useProjectStore from '../../store/useProjectStore'
import useFocusStore from '../../store/useFocusStore'

const WEEKS = 20
const DAY_INIT = ['M','T','W','T','F','S','S']
const CELL = 16
const CELL_LG = 40
const GAP_LG  = 4
const GAP  = 2

const STATUS_KEYS = ['upcoming','in_progress','completed','overdue']
const STATUS_LABEL = {
  upcoming:    'Upcoming',
  in_progress: 'In Progress',
  completed:   'Completed',
  overdue:     'Overdue',
}
const STATUS_COLOR = {
  upcoming:    'text-blue-400',
  in_progress: 'text-amber-400',
  completed:   'text-green-400',
  overdue:     'text-red-400',
}

const STATUS_CELL_COLORS = {
  upcoming:    [
    'bg-blue-400/20 border-blue-400/30',
    'bg-blue-400/55 border-blue-400/70',
    'bg-blue-400 border-blue-400 shadow-[0_0_4px_rgba(96,165,250,0.6)]',
  ],
  in_progress: [
    'bg-amber-400/20 border-amber-400/30',
    'bg-amber-400/55 border-amber-400/70',
    'bg-amber-400 border-amber-400 shadow-[0_0_4px_rgba(251,191,36,0.6)]',
  ],
  completed:   [
    'bg-green-400/20 border-green-400/30',
    'bg-green-400/55 border-green-400/70',
    'bg-green-400 border-green-400 shadow-[0_0_4px_rgba(74,222,128,0.6)]',
  ],
  overdue:     [
    'bg-red-400/20 border-red-400/30',
    'bg-red-400/55 border-red-400/70',
    'bg-red-400 border-red-400 shadow-[0_0_4px_rgba(248,113,113,0.6)]',
  ],
}

const STATUS_HOVER_RING = {
  upcoming:    'hover:ring-1 hover:ring-blue-300/80',
  in_progress: 'hover:ring-1 hover:ring-amber-300/80',
  completed:   'hover:ring-1 hover:ring-green-300/80',
  overdue:     'hover:ring-1 hover:ring-red-400/90',
}

// Tie-break priority: overdue > in_progress > upcoming > completed
const STATUS_PRIORITY = { overdue: 4, in_progress: 3, upcoming: 2, completed: 1 }

function getCellClass(count, statusKey) {
  if (count === 0) return 'bg-surface border-surface-border'
  const colors = STATUS_CELL_COLORS[statusKey] || STATUS_CELL_COLORS.upcoming
  if (count === 1) return colors[0]
  if (count === 2) return colors[1]
  return colors[2]
}

function getDominantStatus(statusCounts) {
  let dominant = null
  let maxCount = 0
  let maxPriority = 0
  for (const [sk, count] of Object.entries(statusCounts)) {
    if (count === 0) continue
    if (
      count > maxCount ||
      (count === maxCount && (STATUS_PRIORITY[sk] || 0) > maxPriority)
    ) {
      dominant    = sk
      maxCount    = count
      maxPriority = STATUS_PRIORITY[sk] || 0
    }
  }
  return { dominant, total: Object.values(statusCounts).reduce((a, b) => a + b, 0) }
}

export default function WorkloadHeatmap() {
  const projects  = useProjectStore(s => s.projects)
  const openFocus = useFocusStore(s => s.openFocus)
  const [tooltip, setTooltip] = useState(null)

  const { weeks, stats } = useMemo(() => {
    const start = startOfWeek(addWeeks(new Date(), -10), { weekStartsOn: 1 })
    const map   = {}

    projects.forEach(p => {
      (p.deliverables || []).forEach(d => {
        const key = d.due_date
        if (!map[key]) map[key] = { items: [], statusCounts: { upcoming: 0, in_progress: 0, completed: 0, overdue: 0 } }
        map[key].items.push({ deliverable: d, project: p })
        const s = (d.status || 'upcoming')
        if (map[key].statusCounts[s] !== undefined) map[key].statusCounts[s]++
      })
    })

    const grid = Array.from({ length: WEEKS }, (_, wi) =>
      Array.from({ length: 7 }, (_, di) => {
        const date  = addDays(start, wi * 7 + di)
        const key   = format(date, 'yyyy-MM-dd')
        const entry = map[key] || { items: [], statusCounts: { upcoming: 0, in_progress: 0, completed: 0, overdue: 0 } }
        return { date, key, ...entry }
      })
    )

    const all   = projects.flatMap(p => p.deliverables || [])
    const stats = {
      total:       all.length,
      upcoming:    all.filter(d => d.status === 'upcoming').length,
      in_progress: all.filter(d => d.status === 'in_progress').length,
      completed:   all.filter(d => d.status === 'completed').length,
      overdue:     all.filter(d => d.status === 'overdue').length,
    }
    return { weeks: grid, stats }
  }, [projects])

  const monthLabels = useMemo(() => {
    const labels = []; let last = -1
    weeks.forEach((week, wi) => {
      const m = week[0].date.getMonth()
      if (m !== last) { labels.push({ wi, label: format(week[0].date, 'MMM') }); last = m }
    })
    return labels
  }, [weeks])

  const monthLabelsBig = useMemo(() => {
    const labels = []; let last = -1
    weeks.forEach((week, wi) => {
      const m = week[0].date.getMonth()
      if (m !== last) { labels.push({ wi, label: format(week[0].date, 'MMM') }); last = m }
    })
    return labels
  }, [weeks])

  return (
    <div className="flex flex-col h-full bg-surface overflow-auto">
      {/* Header — pl-24 clears the fixed 64px navbar button at left-4 */}
      <div className="flex items-center justify-between pl-24 pr-8 pt-6 pb-4">
        <div>
          <h2 className="text-gold font-bold text-lg tracking-wide">Workload Heatmap</h2>
          <p className="text-text-muted text-xs mt-0.5">20 weeks of deliverable density by status</p>
        </div>
        <div className="flex items-center gap-3 text-[10px] text-text-muted">
          <span className="uppercase tracking-[0.18em] text-text-muted/60">FABDASH</span>
        </div>
      </div>

      {/* Stat cards + per-status heatmaps */}
      <div className="grid grid-cols-4 gap-4 px-8 pb-4">
        {STATUS_KEYS.map((statusKey) => (
          <div key={statusKey} className="flex flex-col gap-3">
            <div className="bg-surface-elevated border border-surface-border rounded-xl p-4 text-center">
              <p className={`text-2xl font-bold ${STATUS_COLOR[statusKey]}`}>{stats[statusKey]}</p>
              <p className="text-text-muted text-xs mt-1">{STATUS_LABEL[statusKey]}</p>
            </div>
            <div className="bg-surface-elevated/40 border border-surface-border rounded-xl p-3 flex-1 min-h-[160px] flex items-center justify-center">
              <div className="flex gap-2 overflow-x-auto pb-1 justify-center">
                <div className="flex flex-col flex-shrink-0 pt-6" style={{ gap: GAP }}>
                  {DAY_INIT.map((d, i) => (
                    <div key={i} style={{ height: CELL }} className="flex items-center text-[9px] text-text-muted/50 font-mono w-3">{d}</div>
                  ))}
                </div>
                <div className="flex flex-col flex-shrink-0">
                  <div className="relative h-4 mb-1">
                    {monthLabels.map(({ wi, label }) => (
                      <span key={label+wi} className="absolute text-[9px] text-text-muted/60 font-medium" style={{ left: wi * (CELL + GAP) }}>{label}</span>
                    ))}
                  </div>
                  <div className="flex" style={{ gap: GAP }}>
                    {weeks.map((week, wi) => (
                      <div key={wi} className="flex flex-col flex-shrink-0" style={{ gap: GAP }}>
                        {week.map(({ date, key, items, statusCounts }) => {
                          const count = (statusCounts || {})[statusKey] || 0
                          return (
                            <div
                              key={key + statusKey}
                              style={{ width: CELL, height: CELL }}
                              className={`rounded-sm border cursor-pointer transition-transform duration-100 hover:scale-125 hover:z-10 relative
                                ${getCellClass(count, statusKey)}
                                ${isToday(date) ? 'ring-1 ring-white/60' : ''}
                                ${count > 0 ? STATUS_HOVER_RING[statusKey] : ''}
                              `}
                              onClick={() => {
                                if (!items?.length) return
                                const match = items.find(({ deliverable }) => deliverable.status === statusKey) || items[0]
                                if (match) openFocus(match.project.id, match.deliverable.id)
                              }}
                              onMouseEnter={(e) => {
                                const filtered = (items || []).filter(({ deliverable }) => deliverable.status === statusKey)
                                if (!filtered.length) return
                                setTooltip({ x: e.clientX, y: e.clientY, date, statusKey, items: filtered })
                              }}
                              onMouseLeave={() => setTooltip(null)}
                            />
                          )
                        })}
                      </div>
                    ))}
                  </div>
                </div>
              </div>
            </div>
          </div>
        ))}
      </div>

      {/* Combined heatmap */}
      <div className="px-8 pb-8">
        <div className="bg-surface-elevated/40 border border-surface-border rounded-xl p-5">
          <div className="flex items-center justify-between mb-4">
            <div className="flex items-baseline gap-2">
              <h3 className="text-xs font-semibold tracking-widest uppercase text-text-muted/70">All Tasks</h3>
              <span className="text-text-muted/60 text-[10px] font-mono">{stats.total} tasks</span>
            </div>
            <div className="flex items-center gap-4 text-[9px] text-text-muted/60">
              {STATUS_KEYS.map(sk => (
                <div key={sk} className="flex items-center gap-1.5">
                  <div className={`w-2.5 h-2.5 rounded-sm border ${STATUS_CELL_COLORS[sk][2].split(' ').slice(0,2).join(' ')}`} />
                  <span className={STATUS_COLOR[sk]}>{STATUS_LABEL[sk]}</span>
                </div>
              ))}
              <span className="ml-1 text-text-muted/40">· color = highest count</span>
            </div>
          </div>

          <div className="flex gap-3 overflow-x-auto pb-2 justify-center">
            {/* Day labels */}
            <div className="flex flex-col flex-shrink-0 pt-6" style={{ gap: GAP }}>
              {DAY_INIT.map((d, i) => (
                <div key={i} style={{ height: CELL_LG }} className="flex items-center text-[11px] text-text-muted/50 font-mono w-4">{d}</div>
              ))}
            </div>

            {/* Grid */}
            <div className="flex flex-col flex-shrink-0">
              <div className="relative h-5 mb-1">
                {monthLabelsBig.map(({ wi, label }) => (
                  <span key={label+wi} className="absolute text-[10px] text-text-muted/60 font-medium" style={{ left: wi * (CELL_LG + GAP_LG) }}>{label}</span>
                ))}
              </div>
              <div className="flex" style={{ gap: GAP_LG }}>
                {weeks.map((week, wi) => (
                  <div key={wi} className="flex flex-col flex-shrink-0" style={{ gap: GAP_LG }}>
                    {week.map(({ date, key, items, statusCounts }) => {
                      const { dominant, total } = getDominantStatus(statusCounts || {})
                      return (
                        <div
                          key={key + 'combined'}
                          style={{ width: CELL_LG, height: CELL_LG }}
                          className={`rounded-sm border cursor-pointer transition-transform duration-100 hover:scale-125 hover:z-10 relative
                            ${dominant ? getCellClass(total, dominant) : 'bg-surface border-surface-border'}
                            ${isToday(date) ? 'ring-1 ring-white/60' : ''}
                            ${dominant ? STATUS_HOVER_RING[dominant] : ''}
                          `}
                          onClick={() => {
                            if (!items?.length) return
                            openFocus(items[0].project.id, items[0].deliverable.id)
                          }}
                          onMouseEnter={(e) => {
                            if (!items?.length) return
                            setTooltip({
                              x: e.clientX,
                              y: e.clientY,
                              date,
                              statusKey: dominant,
                              items,
                              combined: true,
                              statusCounts,
                            })
                          }}
                          onMouseLeave={() => setTooltip(null)}
                        />
                      )
                    })}
                  </div>
                ))}
              </div>
            </div>
          </div>
        </div>
      </div>

      {/* Tooltip */}
      {tooltip && (
        <div
          className="fixed z-[200] pointer-events-none bg-surface-elevated border border-surface-border rounded-xl shadow-2xl px-3.5 py-3 min-w-[220px] max-w-[320px]"
          style={{ left: Math.min(tooltip.x + 14, window.innerWidth - 330), top: Math.max(tooltip.y - 100, 8) }}
        >
          <p className={`text-xs font-bold mb-1.5 ${isToday(tooltip.date) ? 'text-gold' : 'text-text-primary'}`}>
            {isToday(tooltip.date) ? 'Today \u2014 ' : ''}{format(tooltip.date, 'EEE, MMM d, yyyy')}
          </p>
          {tooltip.combined && tooltip.statusCounts ? (
            <div className="space-y-1 mb-2">
              {STATUS_KEYS.filter(sk => (tooltip.statusCounts[sk] || 0) > 0).map(sk => (
                <div key={sk} className="flex items-center justify-between gap-3">
                  <span className={`text-[10px] ${STATUS_COLOR[sk]}`}>{STATUS_LABEL[sk]}</span>
                  <span className="text-[10px] text-text-muted/60 font-mono">{tooltip.statusCounts[sk]}</span>
                </div>
              ))}
            </div>
          ) : (
            <p className={`text-[10px] mb-1.5 ${tooltip.statusKey ? STATUS_COLOR[tooltip.statusKey] : 'text-text-muted/60'}`}>
              {tooltip.statusKey ? STATUS_LABEL[tooltip.statusKey] : ''} \u00b7 {tooltip.items.length} task{tooltip.items.length !== 1 ? 's' : ''}
            </p>
          )}
          <div className="space-y-1.5">
            {(tooltip.items || []).slice(0, 5).map(({ deliverable, project }) => (
              <div key={deliverable.id} className="flex items-start gap-1.5">
                <div className="w-1.5 h-1.5 rounded-full mt-1 flex-shrink-0" style={{ backgroundColor: project.color }} />
                <div className="min-w-0 flex-1">
                  <p className="text-[11px] text-text-primary truncate">{deliverable.title}</p>
                  <p className="text-[10px] text-text-muted/60">{project.name}</p>
                </div>
              </div>
            ))}
            {(tooltip.items || []).length > 5 && (
              <p className="text-[10px] text-text-muted/50 pl-3">+{tooltip.items.length - 5} more</p>
            )}
          </div>
        </div>
      )}
    </div>
  )
}
