import { useEffect, useState, useCallback } from 'react'
import {
  Heart, ChevronLeft, ChevronRight, Plus, X,
  CalendarDays, FlaskConical, Baby, AlertCircle, CheckCircle2, Activity
} from 'lucide-react'
import { useNavigate } from 'react-router-dom'
import axios from 'axios'

// ─── Date helpers ────────────────────────────────────────────────────────────
const toISO = d => d.toISOString().split('T')[0]
const addDays = (dateStr, n) => {
  const d = new Date(dateStr); d.setDate(d.getDate() + n); return toISO(d)
}
const fmt = str => str ? new Date(str + 'T00:00:00').toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }) : '–'
const today = toISO(new Date())

// ─── Canine gestation constants (days from breeding date) ─────────────────────
const GESTATION_EARLIEST = 58
const GESTATION_EXPECTED = 63
const GESTATION_LATEST   = 65

/** Returns { earliest, expected, latest } ISO date strings, or null if no breeding_date */
function getWhelpDates(cycle) {
  if (!cycle?.breeding_date) return null
  return {
    earliest: addDays(cycle.breeding_date, GESTATION_EARLIEST),
    expected: addDays(cycle.breeding_date, GESTATION_EXPECTED),
    latest:   addDays(cycle.breeding_date, GESTATION_LATEST),
  }
}

// ─── Cycle window classifier ─────────────────────────────────────────────────
function getWindowForDate(cycle, dateStr) {
  if (!cycle?.start_date) return null
  const start = new Date(cycle.start_date + 'T00:00:00')
  const check = new Date(dateStr + 'T00:00:00')
  const day = Math.round((check - start) / 86400000)
  if (day < 0 || day > 28) return null
  if (day <= 8)  return 'proestrus'
  if (day <= 15) return 'optimal'
  if (day <= 21) return 'late'
  return 'diestrus'
}

const WINDOW_STYLES = {
  proestrus: { bg: 'rgba(244,114,182,0.18)', border: '#f472b6', label: 'Proestrus', dot: '#f472b6' },
  optimal:   { bg: 'rgba(16,185,129,0.22)',  border: '#10b981', label: 'Optimal Breeding', dot: '#10b981' },
  late:      { bg: 'rgba(245,158,11,0.18)',  border: '#f59e0b', label: 'Late Estrus', dot: '#f59e0b' },
  diestrus:  { bg: 'rgba(148,163,184,0.12)', border: '#64748b', label: 'Diestrus', dot: '#64748b' },
}

// Whelp window style (used in legend + calendar marker)
const WHELP_STYLE = {
  bg: 'rgba(99,102,241,0.15)',
  border: '#6366f1',
  label: 'Projected Whelp',
  dot: '#6366f1',
}

// ─── Start Heat Cycle Modal ───────────────────────────────────────────────────
function StartCycleModal({ females, onClose, onSaved }) {
  const [dogId, setDogId] = useState('')
  const [startDate, setStartDate] = useState(today)
  const [notes, setNotes] = useState('')
  const [saving, setSaving] = useState(false)
  const [error, setError] = useState(null)

  async function handleSubmit(e) {
    e.preventDefault()
    if (!dogId || !startDate) return
    setSaving(true); setError(null)
    try {
      const res = await fetch('/api/breeding/heat-cycles', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ dog_id: parseInt(dogId), start_date: startDate, notes: notes || null })
      })
      if (!res.ok) { const e = await res.json(); throw new Error(e.error || 'Failed to save') }
      onSaved()
    } catch (err) {
      setError(err.message)
      setSaving(false)
    }
  }

  return (
    <div className="modal-overlay" onClick={e => e.target === e.currentTarget && onClose()}>
      <div className="modal-content" style={{ maxWidth: '480px' }}>
        <div className="modal-header">
          <div style={{ display: 'flex', alignItems: 'center', gap: '0.6rem' }}>
            <Heart size={18} style={{ color: '#f472b6' }} />
            <h2>Start Heat Cycle</h2>
          </div>
          <button className="btn-icon" onClick={onClose}><X size={20} /></button>
        </div>
        <form onSubmit={handleSubmit}>
          <div className="modal-body">
            {error && <div className="error" style={{ marginBottom: '1rem' }}>{error}</div>}
            <div className="form-group">
              <label className="label">Female Dog *</label>
              <select value={dogId} onChange={e => setDogId(e.target.value)} required>
                <option value="">– Select Female –</option>
                {females.map(d => (
                  <option key={d.id} value={d.id}>
                    {d.name}{d.breed ? ` · ${d.breed}` : ''}
                  </option>
                ))}
              </select>
              {females.length === 0 && <p style={{ color: 'var(--text-muted)', fontSize: '0.8rem', marginTop: '0.4rem' }}>No female dogs registered.</p>}
            </div>
            <div className="form-group">
              <label className="label">Heat Start Date *</label>
              <input type="date" className="input" value={startDate} onChange={e => setStartDate(e.target.value)} required />
            </div>
            <div className="form-group" style={{ marginBottom: 0 }}>
              <label className="label">Notes</label>
              <textarea className="input" value={notes} onChange={e => setNotes(e.target.value)} placeholder="Optional notes..." rows={3} />
            </div>
          </div>
          <div className="modal-footer">
            <button type="button" className="btn btn-secondary" onClick={onClose}>Cancel</button>
            <button type="submit" className="btn btn-primary" disabled={saving || !dogId}>
              {saving ? 'Saving…' : <><Heart size={15} /> Start Cycle</>}
            </button>
          </div>
        </form>
      </div>
    </div>
  )
}

// ─── Cycle Detail Modal ───────────────────────────────────────────────────────
function CycleDetailModal({ cycle, onClose, onDeleted, onRecordLitter }) {
  const [suggestions, setSuggestions] = useState(null)
  const [breedingDate, setBreedingDate] = useState(cycle.breeding_date || '')
  const [savingBreed, setSavingBreed] = useState(false)
  const [deleting, setDeleting] = useState(false)
  const [error, setError] = useState(null)

  useEffect(() => {
    fetch(`/api/breeding/heat-cycles/${cycle.id}/suggestions`)
      .then(r => r.json())
      .then(setSuggestions)
      .catch(() => {})
  }, [cycle.id])

  async function saveBreedingDate() {
    if (!breedingDate) return
    setSavingBreed(true); setError(null)
    try {
      const res = await fetch(`/api/breeding/heat-cycles/${cycle.id}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ ...cycle, breeding_date: breedingDate })
      })
      if (!res.ok) { const e = await res.json(); throw new Error(e.error) }
      // Refresh suggestions
      const s = await fetch(`/api/breeding/heat-cycles/${cycle.id}/suggestions`).then(r => r.json())
      setSuggestions(s)
    } catch (err) { setError(err.message) }
    finally { setSavingBreed(false) }
  }

  async function deleteCycle() {
    if (!window.confirm(`Delete heat cycle for ${cycle.dog_name}? This cannot be undone.`)) return
    setDeleting(true)
    try {
      await fetch(`/api/breeding/heat-cycles/${cycle.id}`, { method: 'DELETE' })
      onDeleted()
    } catch (err) { setError(err.message); setDeleting(false) }
  }

  const whelp = suggestions?.whelping
  const hasBreedingDate = !!(breedingDate && breedingDate === cycle.breeding_date)

  // Client-side projected whelp dates (immediate, before API suggestions load)
  const projectedWhelp = getWhelpDates({ breeding_date: breedingDate })

  return (
    <div className="modal-overlay" onClick={e => e.target === e.currentTarget && onClose()}>
      <div className="modal-content" style={{ maxWidth: '560px' }}>
        <div className="modal-header">
          <div style={{ display: 'flex', alignItems: 'center', gap: '0.6rem' }}>
            <Heart size={18} style={{ color: '#f472b6' }} />
            <h2>{cycle.dog_name}</h2>
          </div>
          <button className="btn-icon" onClick={onClose}><X size={20} /></button>
        </div>
        <div className="modal-body">
          {error && <div className="error">{error}</div>}

          {/* Cycle meta */}
          <div style={{ display: 'flex', gap: '1rem', marginBottom: '1.5rem', flexWrap: 'wrap' }}>
            <div style={infoChip}>
              <span style={{ color: 'var(--text-muted)', fontSize: '0.75rem', textTransform: 'uppercase', letterSpacing: '0.05em' }}>Started</span>
              <span style={{ fontWeight: 600 }}>{fmt(cycle.start_date)}</span>
            </div>
            {cycle.breed && (
              <div style={infoChip}>
                <span style={{ color: 'var(--text-muted)', fontSize: '0.75rem', textTransform: 'uppercase', letterSpacing: '0.05em' }}>Breed</span>
                <span style={{ fontWeight: 600 }}>{cycle.breed}</span>
              </div>
            )}
          </div>

          {/* Breeding date windows */}
          {suggestions && (
            <>
              <h3 style={{ fontSize: '0.9375rem', marginBottom: '0.75rem', display: 'flex', alignItems: 'center', gap: '0.4rem' }}>
                <FlaskConical size={16} style={{ color: 'var(--accent)' }} /> Breeding Date Windows
              </h3>
              <div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem', marginBottom: '1.5rem' }}>
                {suggestions.windows.map(w => (
                  <div key={w.type} style={{
                    display: 'flex', alignItems: 'flex-start', gap: '0.75rem',
                    padding: '0.625rem 0.875rem',
                    background: WINDOW_STYLES[w.type]?.bg,
                    border: `1px solid ${WINDOW_STYLES[w.type]?.border}`,
                    borderRadius: 'var(--radius-sm)'
                  }}>
                    <div style={{ width: 10, height: 10, borderRadius: '50%', background: WINDOW_STYLES[w.type]?.dot, marginTop: 4, flexShrink: 0 }} />
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: '0.5rem', flexWrap: 'wrap' }}>
                        <span style={{ fontWeight: 600, fontSize: '0.875rem' }}>{w.label}</span>
                        <span style={{ fontSize: '0.8125rem', color: 'var(--text-secondary)', whiteSpace: 'nowrap' }}>{fmt(w.start)} – {fmt(w.end)}</span>
                      </div>
                      <p style={{ fontSize: '0.8rem', color: 'var(--text-muted)', margin: '0.15rem 0 0' }}>{w.description}</p>
                    </div>
                  </div>
                ))}
              </div>
            </>
          )}

          {/* Log breeding date */}
          <div style={{ background: 'var(--bg-tertiary)', borderRadius: 'var(--radius)', padding: '1rem', marginBottom: '1.25rem' }}>
            <h3 style={{ fontSize: '0.9375rem', marginBottom: '0.75rem', display: 'flex', alignItems: 'center', gap: '0.4rem' }}>
              <CalendarDays size={16} style={{ color: 'var(--primary)' }} /> Log Breeding Date
            </h3>
            <div style={{ display: 'flex', gap: '0.75rem', alignItems: 'flex-end', flexWrap: 'wrap' }}>
              <div style={{ flex: 1, minWidth: 160 }}>
                <label className="label" style={{ marginBottom: '0.4rem' }}>Breeding Date</label>
                <input type="date" className="input" value={breedingDate} onChange={e => setBreedingDate(e.target.value)} />
              </div>
              <button className="btn btn-primary" onClick={saveBreedingDate} disabled={savingBreed || !breedingDate} style={{ marginBottom: 0 }}>
                {savingBreed ? 'Saving…' : 'Save'}
              </button>
            </div>
            {/* Live projected whelp preview — shown as soon as a breeding date is entered */}
            {projectedWhelp && (
              <div style={{
                marginTop: '0.875rem',
                padding: '0.625rem 0.875rem',
                background: WHELP_STYLE.bg,
                border: `1px solid ${WHELP_STYLE.border}`,
                borderRadius: 'var(--radius-sm)',
                display: 'flex',
                alignItems: 'center',
                gap: '0.5rem',
                flexWrap: 'wrap'
              }}>
                <Baby size={15} style={{ color: WHELP_STYLE.dot, flexShrink: 0 }} />
                <span style={{ fontSize: '0.8125rem', fontWeight: 600, color: WHELP_STYLE.dot }}>Projected Whelp:</span>
                <span style={{ fontSize: '0.8125rem', color: 'var(--text-secondary)' }}>
                  {fmt(projectedWhelp.earliest)} – {fmt(projectedWhelp.latest)}
                  &nbsp;<span style={{ color: 'var(--text-muted)' }}>(expected {fmt(projectedWhelp.expected)})</span>
                </span>
              </div>
            )}
          </div>

          {/* Whelping estimate (from API suggestions) */}
          {whelp && (
            <div style={{ background: 'rgba(16,185,129,0.08)', border: '1px solid rgba(16,185,129,0.3)', borderRadius: 'var(--radius)', padding: '1rem', marginBottom: '1rem' }}>
              <h3 style={{ fontSize: '0.9375rem', marginBottom: '0.75rem', display: 'flex', alignItems: 'center', gap: '0.4rem', color: 'var(--success)' }}>
                <Baby size={16} /> Whelping Estimate
              </h3>
              <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '0.75rem', textAlign: 'center' }}>
                {[['Earliest', whelp.earliest], ['Expected', whelp.expected], ['Latest', whelp.latest]].map(([label, date]) => (
                  <div key={label}>
                    <div style={{ fontSize: '0.75rem', color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '0.05em', marginBottom: '0.2rem' }}>{label}</div>
                    <div style={{ fontWeight: 700, fontSize: '0.9375rem' }}>{fmt(date)}</div>
                  </div>
                ))}
              </div>
            </div>
          )}

          {/* Record Litter CTA — shown when breeding date is saved */}
          {hasBreedingDate && (
            <div style={{
              background: 'rgba(16,185,129,0.06)',
              border: '1px dashed rgba(16,185,129,0.5)',
              borderRadius: 'var(--radius)',
              padding: '0.875rem 1rem',
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'space-between',
              gap: '1rem',
              flexWrap: 'wrap'
            }}>
              <div>
                <div style={{ fontWeight: 600, fontSize: '0.9rem' }}>🐾 Ready to record the litter?</div>
                <div style={{ fontSize: '0.8rem', color: 'var(--text-secondary)', marginTop: '0.2rem' }}>
                  Breeding date logged on {fmt(cycle.breeding_date)}. Create a litter record to track puppies.
                </div>
              </div>
              <button
                className="btn btn-primary"
                style={{ whiteSpace: 'nowrap', fontSize: '0.85rem' }}
                onClick={() => {
                  onClose()
                  onRecordLitter(cycle)
                }}
              >
                <Activity size={14} style={{ marginRight: '0.4rem' }} />
                Record Litter
              </button>
            </div>
          )}
        </div>
        <div className="modal-footer" style={{ justifyContent: 'space-between' }}>
          <button className="btn btn-danger" onClick={deleteCycle} disabled={deleting}>
            {deleting ? 'Deleting…' : 'Delete Cycle'}
          </button>
          <button className="btn btn-secondary" onClick={onClose}>Close</button>
        </div>
      </div>
    </div>
  )
}

const infoChip = {
  display: 'flex', flexDirection: 'column', gap: '0.15rem',
  padding: '0.5rem 0.875rem',
  background: 'var(--bg-tertiary)',
  borderRadius: 'var(--radius-sm)'
}

// ─── Main Calendar ────────────────────────────────────────────────────────────
export default function BreedingCalendar() {
  const now = new Date()
  const [year, setYear] = useState(now.getFullYear())
  const [month, setMonth] = useState(now.getMonth()) // 0-indexed
  const [cycles, setCycles] = useState([])
  const [females, setFemales] = useState([])
  const [loading, setLoading] = useState(true)
  const [showStartModal, setShowStartModal] = useState(false)
  const [selectedCycle, setSelectedCycle] = useState(null)
  const [selectedDay, setSelectedDay] = useState(null)
  const [pendingLitterCycle, setPendingLitterCycle] = useState(null)
  const navigate = useNavigate()

  const load = useCallback(async () => {
    setLoading(true)
    try {
      const [cyclesRes, dogsRes] = await Promise.all([
        fetch('/api/breeding/heat-cycles'),
        fetch('/api/dogs')
      ])
      const allCycles = await cyclesRes.json()
      const dogsData = await dogsRes.json()
      const allDogs = Array.isArray(dogsData) ? dogsData : (dogsData.dogs || [])
      setCycles(Array.isArray(allCycles) ? allCycles : [])
      setFemales(allDogs.filter(d => d.sex === 'female'))
    } catch (e) {
      console.error(e)
    } finally {
      setLoading(false)
    }
  }, [])

  useEffect(() => { load() }, [load])

  // When user clicks Record Litter from cycle detail, create litter and navigate
  const handleRecordLitter = useCallback(async (cycle) => {
    try {
      // We need sire_id — navigate to litters page with pre-filled dam
      // Store cycle info in sessionStorage so LitterList can pre-fill
      sessionStorage.setItem('prefillLitter', JSON.stringify({
        dam_id: cycle.dog_id,
        dam_name: cycle.dog_name,
        breeding_date: cycle.breeding_date,
        whelping_date: cycle.whelping_date || ''
      }))
      navigate('/litters')
    } catch (err) {
      console.error(err)
    }
  }, [navigate])

  // ── Navigate to a specific year/month ──
  function goToMonth(y, m) {
    setYear(y)
    setMonth(m)
  }

  // ── Build calendar grid ──
  const firstDay = new Date(year, month, 1)
  const lastDay = new Date(year, month + 1, 0)
  const startPad = firstDay.getDay() // 0=Sun
  const totalCells = startPad + lastDay.getDate()
  const rows = Math.ceil(totalCells / 7)

  const MONTH_NAMES = ['January','February','March','April','May','June','July','August','September','October','November','December']
  const DAY_NAMES = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']

  function prevMonth() {
    if (month === 0) { setMonth(11); setYear(y => y - 1) }
    else setMonth(m => m - 1)
  }
  function nextMonth() {
    if (month === 11) { setMonth(0); setYear(y => y + 1) }
    else setMonth(m => m + 1)
  }

  function cyclesForDate(dateStr) {
    return cycles.filter(c => {
      const s = c.start_date
      if (!s) return false
      const end = c.end_date || addDays(s, 28)
      return dateStr >= s && dateStr <= end
    })
  }

  /** Returns array of cycles whose projected whelp expected date is this dateStr */
  function whelpingCyclesForDate(dateStr) {
    return cycles.filter(c => {
      const wd = getWhelpDates(c)
      if (!wd) return false
      return dateStr >= wd.earliest && dateStr <= wd.latest
    })
  }

  /** Returns true if this dateStr is the exact expected whelp date for any cycle */
  function isExpectedWhelpDate(dateStr) {
    return cycles.some(c => {
      const wd = getWhelpDates(c)
      return wd?.expected === dateStr
    })
  }

  function handleDayClick(dateStr, dayCycles) {
    setSelectedDay(dateStr)
    if (dayCycles.length === 1) {
      setSelectedCycle(dayCycles[0])
    } else if (dayCycles.length > 1) {
      setSelectedCycle(dayCycles[0])
    } else {
      setShowStartModal(true)
    }
  }

  const activeCycles = cycles.filter(c => {
    const s = c.start_date; if (!s) return false
    const end = c.end_date || addDays(s, 28)
    const mStart = toISO(new Date(year, month, 1))
    const mEnd = toISO(new Date(year, month + 1, 0))
    return s <= mEnd && end >= mStart
  })

  // Cycles that have a whelp window overlapping current month view
  const whelpingThisMonth = cycles.filter(c => {
    const wd = getWhelpDates(c)
    if (!wd) return false
    const mStart = toISO(new Date(year, month, 1))
    const mEnd = toISO(new Date(year, month + 1, 0))
    return wd.earliest <= mEnd && wd.latest >= mStart
  })

  return (
    <div className="container" style={{ paddingTop: '2rem', paddingBottom: '3rem' }}>
      {/* Header */}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '1.5rem', flexWrap: 'wrap', gap: '1rem' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: '0.75rem' }}>
          <div style={{ width: '2.5rem', height: '2.5rem', borderRadius: 'var(--radius)', background: 'rgba(244,114,182,0.2)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#f472b6' }}>
            <Heart size={20} />
          </div>
          <div>
            <h1 style={{ fontSize: '1.75rem', margin: 0 }}>Heat Cycle Calendar</h1>
            <p style={{ color: 'var(--text-muted)', margin: 0, fontSize: '0.875rem' }}>Track heat cycles, optimal breeding windows, and projected whelping dates</p>
          </div>
        </div>
        <button className="btn btn-primary" onClick={() => setShowStartModal(true)}>
          <Plus size={16} /> Start Heat Cycle
        </button>
      </div>

      {/* Legend */}
      <div style={{ display: 'flex', gap: '0.75rem', marginBottom: '1.25rem', flexWrap: 'wrap' }}>
        {Object.entries(WINDOW_STYLES).map(([key, s]) => (
          <div key={key} style={{ display: 'flex', alignItems: 'center', gap: '0.4rem', fontSize: '0.8125rem', color: 'var(--text-secondary)' }}>
            <div style={{ width: 10, height: 10, borderRadius: '50%', background: s.dot }} />
            {s.label}
          </div>
        ))}
        {/* Whelp legend entry */}
        <div style={{ display: 'flex', alignItems: 'center', gap: '0.4rem', fontSize: '0.8125rem', color: 'var(--text-secondary)' }}>
          <Baby size={11} style={{ color: WHELP_STYLE.dot }} />
          {WHELP_STYLE.label}
        </div>
      </div>

      {/* Month navigator */}
      <div className="card" style={{ marginBottom: '1rem', padding: '0' }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '0.875rem 1rem', borderBottom: '1px solid var(--border)' }}>
          <button className="btn-icon" onClick={prevMonth}><ChevronLeft size={20} /></button>
          <h2 style={{ margin: 0, fontSize: '1.1rem' }}>{MONTH_NAMES[month]} {year}</h2>
          <button className="btn-icon" onClick={nextMonth}><ChevronRight size={20} /></button>
        </div>

        {/* Day headers */}
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', borderBottom: '1px solid var(--border)' }}>
          {DAY_NAMES.map(d => (
            <div key={d} style={{ padding: '0.5rem', textAlign: 'center', fontSize: '0.75rem', fontWeight: 600, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '0.05em' }}>{d}</div>
          ))}
        </div>

        {/* Calendar cells */}
        {loading ? (
          <div className="loading" style={{ minHeight: 280 }}>Loading calendar…</div>
        ) : (
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)' }}>
            {Array.from({ length: rows * 7 }).map((_, idx) => {
              const dayNum = idx - startPad + 1
              const isValid = dayNum >= 1 && dayNum <= lastDay.getDate()
              const dateStr = isValid ? toISO(new Date(year, month, dayNum)) : null
              const dayCycles = dateStr ? cyclesForDate(dateStr) : []
              const isToday = dateStr === today

              // Whelp window cycles for this day
              const whelpCycles = dateStr ? whelpingCyclesForDate(dateStr) : []
              const isExpectedWhelp = dateStr ? isExpectedWhelpDate(dateStr) : false
              const hasWhelpActivity = whelpCycles.length > 0

              let cellBg = 'transparent'
              let cellBorder = 'var(--border)'
              if (dayCycles.length > 0) {
                const win = getWindowForDate(dayCycles[0], dateStr)
                if (win && WINDOW_STYLES[win]) {
                  cellBg = WINDOW_STYLES[win].bg
                  cellBorder = WINDOW_STYLES[win].border
                }
              } else if (hasWhelpActivity) {
                // Only color whelp window if not already in a heat window
                cellBg = WHELP_STYLE.bg
                cellBorder = WHELP_STYLE.border
              }

              return (
                <div
                  key={idx}
                  onClick={() => isValid && handleDayClick(dateStr, dayCycles)}
                  style={{
                    minHeight: 72,
                    padding: '0.375rem 0.5rem',
                    borderRight: '1px solid var(--border)',
                    borderBottom: '1px solid var(--border)',
                    background: cellBg,
                    cursor: isValid ? 'pointer' : 'default',
                    position: 'relative',
                    transition: 'filter 0.15s',
                    opacity: isValid ? 1 : 0.3,
                    outline: isToday ? `2px solid var(--primary)` : 'none',
                    outlineOffset: -2,
                  }}
                  onMouseEnter={e => { if (isValid) e.currentTarget.style.filter = 'brightness(1.15)' }}
                  onMouseLeave={e => { e.currentTarget.style.filter = 'none' }}
                >
                  {isValid && (
                    <>
                      <div style={{
                        fontSize: '0.8125rem', fontWeight: isToday ? 700 : 500,
                        color: isToday ? 'var(--primary)' : 'var(--text-primary)',
                        marginBottom: '0.25rem'
                      }}>{dayNum}</div>
                      {dayCycles.map((c, i) => {
                        const win = getWindowForDate(c, dateStr)
                        const dot = win ? WINDOW_STYLES[win]?.dot : '#94a3b8'
                        return (
                          <div key={i} style={{
                            fontSize: '0.7rem', color: dot, fontWeight: 600,
                            whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
                            lineHeight: 1.3
                          }}>
                            ♥ {c.dog_name}
                          </div>
                        )
                      })}
                      {/* Projected whelp window indicator */}
                      {hasWhelpActivity && (
                        <div style={{ marginTop: '0.15rem' }}>
                          {whelpCycles.map((c, i) => (
                            <div key={i} style={{
                              fontSize: '0.67rem',
                              color: WHELP_STYLE.dot,
                              fontWeight: 600,
                              whiteSpace: 'nowrap',
                              overflow: 'hidden',
                              textOverflow: 'ellipsis',
                              lineHeight: 1.3,
                              display: 'flex',
                              alignItems: 'center',
                              gap: '0.2rem'
                            }}>
                              <Baby size={9} />
                              {isExpectedWhelp && getWhelpDates(c)?.expected === dateStr
                                ? `${c.dog_name} due`
                                : c.dog_name
                              }
                            </div>
                          ))}
                        </div>
                      )}
                      {/* Breeding date marker dot */}
                      {dayCycles.some(c => c.breeding_date === dateStr) && (
                        <div style={{ position: 'absolute', top: 4, right: 4, width: 8, height: 8, borderRadius: '50%', background: 'var(--success)', border: '1.5px solid var(--bg-primary)' }} title="Breeding date logged" />
                      )}
                      {/* Expected whelp date ring marker */}
                      {isExpectedWhelp && (
                        <div style={{
                          position: 'absolute',
                          top: 2, right: dayCycles.some(c => c.breeding_date === dateStr) ? 14 : 4,
                          width: 8, height: 8,
                          borderRadius: '50%',
                          background: WHELP_STYLE.dot,
                          border: '1.5px solid var(--bg-primary)'
                        }} title="Projected whelp date" />
                      )}
                    </>
                  )}
                </div>
              )
            })}
          </div>
        )}
      </div>

      {/* Active cycles list */}
      <div style={{ marginTop: '1.5rem' }}>
        <h3 style={{ fontSize: '1rem', marginBottom: '0.875rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
          <AlertCircle size={16} style={{ color: '#f472b6' }} />
          Active Cycles This Month
          <span className="badge badge-primary">{activeCycles.length}</span>
        </h3>
        {activeCycles.length === 0 ? (
          <div className="card" style={{ textAlign: 'center', padding: '2rem', color: 'var(--text-muted)' }}>
            <Heart size={32} style={{ margin: '0 auto 0.75rem', opacity: 0.4 }} />
            <p>No active heat cycles this month.</p>
            <button className="btn btn-primary" style={{ marginTop: '1rem' }} onClick={() => setShowStartModal(true)}>
              <Plus size={15} /> Start First Cycle
            </button>
          </div>
        ) : (
          <div style={{ display: 'grid', gap: '0.75rem', gridTemplateColumns: 'repeat(auto-fill, minmax(260px, 1fr))' }}>
            {activeCycles.map(c => {
              const win = getWindowForDate(c, today)
              const ws = win ? WINDOW_STYLES[win] : null
              const daysSince = Math.round((new Date(today) - new Date(c.start_date + 'T00:00:00')) / 86400000)
              const projWhelp = getWhelpDates(c)
              return (
                <div
                  key={c.id}
                  className="card"
                  style={{ cursor: 'pointer', borderColor: ws?.border || 'var(--border)', background: ws?.bg || 'var(--bg-secondary)' }}
                  onClick={() => setSelectedCycle(c)}
                >
                  <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
                    <div>
                      <h4 style={{ margin: '0 0 0.2rem', fontSize: '1rem' }}>{c.dog_name}</h4>
                      {c.breed && <p style={{ color: 'var(--text-muted)', fontSize: '0.8rem', margin: 0 }}>{c.breed}</p>}
                    </div>
                    {ws && <span className="badge" style={{ background: ws.bg, color: ws.dot, border: `1px solid ${ws.border}`, flexShrink: 0 }}>{ws.label}</span>}
                  </div>
                  <div style={{ marginTop: '0.75rem', display: 'flex', gap: '1rem', fontSize: '0.8125rem', color: 'var(--text-secondary)' }}>
                    <span>Started {fmt(c.start_date)}</span>
                    <span>Day {daysSince + 1}</span>
                  </div>
                  {c.breeding_date && (
                    <div style={{ marginTop: '0.5rem', display: 'flex', alignItems: 'center', gap: '0.4rem', fontSize: '0.8rem', color: 'var(--success)' }}>
                      <CheckCircle2 size={13} /> Bred {fmt(c.breeding_date)}
                    </div>
                  )}
                  {/* Projected whelp date on card */}
                  {projWhelp && (
                    <div style={{
                      marginTop: '0.4rem',
                      display: 'flex',
                      alignItems: 'center',
                      gap: '0.4rem',
                      fontSize: '0.8rem',
                      color: WHELP_STYLE.dot,
                      fontWeight: 500
                    }}>
                      <Baby size={13} />
                      Whelp est. {fmt(projWhelp.expected)}
                      <span style={{ fontSize: '0.73rem', color: 'var(--text-muted)', fontWeight: 400 }}>
                        ({fmt(projWhelp.earliest)}–{fmt(projWhelp.latest)})
                      </span>
                      {/* Jump-to-month button if whelp month differs from current view */}
                      {(() => {
                        const wd = new Date(projWhelp.expected + 'T00:00:00')
                        const wdY = wd.getFullYear()
                        const wdM = wd.getMonth()
                        if (wdY !== year || wdM !== month) {
                          return (
                            <button
                              style={{
                                marginLeft: 'auto',
                                background: 'none',
                                border: `1px solid ${WHELP_STYLE.border}`,
                                borderRadius: '0.25rem',
                                color: WHELP_STYLE.dot,
                                fontSize: '0.7rem',
                                padding: '0.1rem 0.35rem',
                                cursor: 'pointer',
                                fontWeight: 600,
                                whiteSpace: 'nowrap'
                              }}
                              onClick={e => { e.stopPropagation(); goToMonth(wdY, wdM) }}
                            >
                              View {MONTH_NAMES[wdM].slice(0,3)} {wdY}
                            </button>
                          )
                        }
                        return null
                      })()}
                    </div>
                  )}
                </div>
              )
            })}
          </div>
        )}
      </div>

      {/* Whelping cycles banner — shown if any projected whelps fall this month but no active heat */}
      {whelpingThisMonth.length > 0 && activeCycles.length === 0 && (
        <div style={{
          marginTop: '1.5rem',
          padding: '1rem',
          background: WHELP_STYLE.bg,
          border: `1px solid ${WHELP_STYLE.border}`,
          borderRadius: 'var(--radius)',
          display: 'flex',
          alignItems: 'flex-start',
          gap: '0.75rem'
        }}>
          <Baby size={18} style={{ color: WHELP_STYLE.dot, flexShrink: 0, marginTop: 2 }} />
          <div>
            <div style={{ fontWeight: 600, color: WHELP_STYLE.dot, marginBottom: '0.3rem' }}>Projected Whelping This Month</div>
            {whelpingThisMonth.map(c => {
              const wd = getWhelpDates(c)
              return (
                <div key={c.id} style={{ fontSize: '0.85rem', color: 'var(--text-secondary)', marginBottom: '0.2rem' }}>
                  <strong>{c.dog_name}</strong> — expected {fmt(wd.expected)}
                  <span style={{ color: 'var(--text-muted)', fontSize: '0.78rem' }}> (range {fmt(wd.earliest)}–{fmt(wd.latest)})</span>
                </div>
              )
            })}
          </div>
        </div>
      )}

      {/* Modals */}
      {showStartModal && (
        <StartCycleModal
          females={females}
          onClose={() => setShowStartModal(false)}
          onSaved={() => { setShowStartModal(false); load() }}
        />
      )}
      {selectedCycle && (
        <CycleDetailModal
          cycle={selectedCycle}
          onClose={() => setSelectedCycle(null)}
          onDeleted={() => { setSelectedCycle(null); load() }}
          onRecordLitter={handleRecordLitter}
        />
      )}
    </div>
  )
}
