import { useEffect, useRef } from 'react'

function parseDate(s) {
  if (!s) return null
  const [y, m, d] = s.split('-').map(Number)
  return new Date(y, (m || 1) - 1, (d || 1))
}

function addMonths(date, months) {
  const d = new Date(date)
  d.setMonth(d.getMonth() + months)
  return d
}

function fmtDate(d) {
  return d.getFullYear() + '-' + String(d.getMonth() + 1).padStart(2, '0') + '-' + String(d.getDate()).padStart(2, '0')
}

function roundRect(ctx, x, y, w, h, r, fill, stroke) {
  ctx.beginPath()
  ctx.moveTo(x + r, y)
  ctx.lineTo(x + w - r, y)
  ctx.quadraticCurveTo(x + w, y, x + w, y + r)
  ctx.lineTo(x + w, y + h - r)
  ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h)
  ctx.lineTo(x + r, y + h)
  ctx.quadraticCurveTo(x, y + h, x, y + h - r)
  ctx.lineTo(x, y + r)
  ctx.quadraticCurveTo(x, y, x + r, y)
  ctx.closePath()
  if (fill) ctx.fill()
  if (stroke) ctx.stroke()
}

export default function Timeline({ dateFrom, dateTo, offsetYr, offsetMo }) {
  const canvasRef = useRef(null)

  useEffect(() => {
    const canvas = canvasRef.current
    if (!canvas) return
    const dpr = window.devicePixelRatio || 1
    const W = canvas.offsetWidth || 500
    canvas.width = W * dpr
    canvas.height = 90 * dpr
    const ctx = canvas.getContext('2d')
    ctx.scale(dpr, dpr)

    const H = 90
    const PAD = { l: 8, r: 8 }
    const trackH = 22
    const srcY = 20
    const projY = srcY + trackH + 10
    const drawW = W - PAD.l - PAD.r

    const srcStart = parseDate(dateFrom)
    const srcEnd   = parseDate(dateTo)
    if (!srcStart || !srcEnd || isNaN(srcStart) || isNaN(srcEnd)) return

    const offsetMoTotal = (offsetYr || 0) * 12 + (offsetMo || 0)
    const projStart = addMonths(srcStart, offsetMoTotal)
    const projEnd   = addMonths(srcEnd, offsetMoTotal)

    const winStart = addMonths(srcStart, -1)
    const winEnd   = addMonths(projEnd, 1)
    const winMs    = winEnd - winStart

    function xOf(date) {
      return PAD.l + ((date - winStart) / winMs) * drawW
    }

    ctx.clearRect(0, 0, W, H)

    // axis
    ctx.strokeStyle = '#e5e7eb'
    ctx.lineWidth = 1
    ctx.beginPath()
    ctx.moveTo(PAD.l, srcY - 8)
    ctx.lineTo(PAD.l + drawW, srcY - 8)
    ctx.stroke()

    // month ticks + year labels
    const tickStart = new Date(winStart.getFullYear(), winStart.getMonth(), 1)
    for (let d = new Date(tickStart); d <= winEnd; d = addMonths(d, 1)) {
      const x = xOf(d)
      if (x < PAD.l || x > PAD.l + drawW) continue
      ctx.strokeStyle = '#f3f4f6'
      ctx.lineWidth = 1
      ctx.beginPath()
      ctx.moveTo(x, srcY - 8)
      ctx.lineTo(x, projY + trackH)
      ctx.stroke()
      if (d.getMonth() === 0) {
        ctx.fillStyle = '#6b7280'
        ctx.font = 'bold 9px system-ui'
        ctx.textAlign = 'center'
        ctx.fillText(d.getFullYear(), x, srcY - 10)
      }
    }

    // source band
    const sx1 = xOf(srcStart), sx2 = xOf(srcEnd)
    ctx.fillStyle = '#dbeafe'
    ctx.strokeStyle = '#93c5fd'
    ctx.lineWidth = 1
    roundRect(ctx, sx1, srcY, Math.max(sx2 - sx1, 4), trackH, 4, true, true)
    ctx.fillStyle = '#1d4ed8'
    ctx.font = '10px system-ui'
    ctx.textAlign = 'left'
    ctx.fillText('Source  ' + dateFrom + ' → ' + dateTo, sx1 + 6, srcY + 14)

    if (offsetMoTotal > 0) {
      const px1 = xOf(projStart), px2 = xOf(projEnd)
      ctx.fillStyle = '#dcfce7'
      ctx.strokeStyle = '#86efac'
      roundRect(ctx, px1, projY, Math.max(px2 - px1, 4), trackH, 4, true, true)
      ctx.fillStyle = '#15803d'
      ctx.font = '10px system-ui'
      ctx.textAlign = 'left'
      ctx.fillText('Projected  ' + fmtDate(projStart) + ' → ' + fmtDate(projEnd), px1 + 6, projY + 14)

      // arrow
      const arrowY = srcY + trackH / 2
      ctx.strokeStyle = '#94a3b8'
      ctx.lineWidth = 1
      ctx.setLineDash([3, 3])
      ctx.beginPath()
      ctx.moveTo(sx1, arrowY)
      ctx.lineTo(px1 - 2, arrowY)
      ctx.stroke()
      ctx.setLineDash([])
      ctx.fillStyle = '#94a3b8'
      ctx.beginPath()
      ctx.moveTo(px1 + 4, arrowY)
      ctx.lineTo(px1 - 4, arrowY - 4)
      ctx.lineTo(px1 - 4, arrowY + 4)
      ctx.closePath()
      ctx.fill()
      const label = '+' + (offsetYr ? offsetYr + 'yr ' : '') + (offsetMo ? offsetMo + 'mo' : '')
      ctx.fillStyle = '#64748b'
      ctx.font = '9px system-ui'
      ctx.textAlign = 'center'
      ctx.fillText(label.trim(), (sx1 + px1) / 2, arrowY - 5)
    }
  }, [dateFrom, dateTo, offsetYr, offsetMo])

  return <canvas ref={canvasRef} height={90} style={{ width: '100%', display: 'block' }} />
}
