import type { BurnUpData } from '../../lib/dates.js'

/**
 * Charts — geometry, not decoration. Ported from the handoff's Chart.js. When a
 * `data` prop is supplied the cone is drawn from real Monte Carlo output
 * (#10); without it, the fixed sample paths below stand in (demo mode). The
 * shapes (cone from today, 80% band, today rule) are final.
 */

export interface BurnUpConeProps {
  width?: number
  height?: number
  /** Real forecast geometry. When present it replaces the demo sample paths. */
  data?: BurnUpData
}

export function BurnUpCone({ width = 640, height = 220, data }: BurnUpConeProps) {
  if (data) return <BurnUpConeReal width={width} height={height} data={data} />
  const pad = { l: 34, r: 96, t: 16, b: 26 }
  const W = width - pad.l - pad.r
  const H = height - pad.t - pad.b
  const x = (f: number) => pad.l + f * W
  const y = (f: number) => pad.t + (1 - f) * H

  const today = 0.58
  const actual: number[][] = [
    [0, 0],
    [0.08, 0.05],
    [0.18, 0.13],
    [0.26, 0.16],
    [0.36, 0.27],
    [0.46, 0.38],
    [0.58, 0.47],
  ]
  const coneHi: number[][] = [
    [0.58, 0.47],
    [0.72, 0.66],
    [0.86, 0.88],
    [0.95, 1.0],
  ]
  const coneLo: number[][] = [
    [0.58, 0.47],
    [0.74, 0.58],
    [0.9, 0.74],
    [1.0, 0.86],
  ]
  const mid: number[][] = [
    [0.58, 0.47],
    [0.76, 0.63],
    [0.92, 0.83],
    [1.0, 0.93],
  ]
  const pts = (arr: number[][]) => arr.map(([a, b]) => `${x(a)},${y(b)}`).join(' ')
  const cone = [...coneHi, ...[...coneLo].reverse()]

  return (
    <svg width="100%" viewBox={`0 0 ${width} ${height}`} style={{ display: 'block' }}>
      {/* gridlines */}
      {[0, 0.25, 0.5, 0.75, 1].map((f) => (
        <line key={f} x1={pad.l} x2={width - pad.r} y1={y(f)} y2={y(f)} stroke="var(--line-1)" strokeWidth="1" />
      ))}
      {/* scope */}
      <line x1={pad.l} x2={width - pad.r} y1={y(1)} y2={y(1)} stroke="var(--line-2)" strokeWidth="1.5" />
      <text x={pad.l} y={y(1) - 6} style={{ font: '400 10.5px var(--font-mono)', fill: 'var(--ink-3)' }}>
        scope · 42 issues
      </text>
      {/* cone */}
      <polygon points={pts(cone)} fill="var(--cone-fill)" />
      <polyline points={pts(coneHi)} fill="none" stroke="var(--cone-line)" strokeWidth="1.2" strokeDasharray="3 3" />
      <polyline points={pts(coneLo)} fill="none" stroke="var(--cone-line)" strokeWidth="1.2" strokeDasharray="3 3" />
      <polyline points={pts(mid)} fill="none" stroke="var(--cone-line)" strokeWidth="1.4" />
      {/* actual */}
      <polyline points={pts(actual)} fill="none" stroke="var(--cone-actual)" strokeWidth="2" />
      <circle cx={x(0.58)} cy={y(0.47)} r="3.5" fill="var(--cone-actual)" />
      {/* today rule */}
      <line x1={x(today)} x2={x(today)} y1={pad.t} y2={height - pad.b} stroke="var(--jade)" strokeWidth="1" />
      <text x={x(today) + 5} y={pad.t + 10} style={{ font: '400 10.5px var(--font-mono)', fill: 'var(--jade-7)' }}>
        today
      </text>
      {/* 80% band label */}
      <text x={width - pad.r + 10} y={y(0.95)} style={{ font: '500 11.5px var(--font-mono)', fill: 'var(--ink-1)' }}>
        80%
      </text>
      <text x={width - pad.r + 10} y={y(0.95) + 14} style={{ font: '400 11px var(--font-mono)', fill: 'var(--ink-2)' }}>
        Mar 3–12
      </text>
      {/* x labels */}
      <text x={pad.l} y={height - 8} style={{ font: '400 10.5px var(--font-mono)', fill: 'var(--ink-3)' }}>
        Jan 6
      </text>
      <text x={width - pad.r - 34} y={height - 8} style={{ font: '400 10.5px var(--font-mono)', fill: 'var(--ink-3)' }}>
        Mar 15
      </text>
    </svg>
  )
}

/** Data-driven twin of BurnUpCone — same visual grammar, real forecast geometry. */
function BurnUpConeReal({ width, height, data }: { width: number; height: number; data: BurnUpData }) {
  const pad = { l: 34, r: 96, t: 16, b: 26 }
  const W = width - pad.l - pad.r
  const H = height - pad.t - pad.b
  const x = (day: number) => pad.l + (day / data.horizonDays) * W
  const y = (frac: number) => pad.t + (1 - frac) * H

  const hi = data.band.map((p) => `${x(p.hiDay)},${y(p.fraction)}`).join(' ')
  const lo = data.band.map((p) => `${x(p.loDay)},${y(p.fraction)}`).join(' ')
  const mid = data.band.map((p) => `${x(p.midDay)},${y(p.fraction)}`).join(' ')
  const cone = [
    ...data.band.map((p) => `${x(p.hiDay)},${y(p.fraction)}`),
    ...[...data.band].reverse().map((p) => `${x(p.loDay)},${y(p.fraction)}`),
  ].join(' ')

  return (
    <svg width="100%" viewBox={`0 0 ${width} ${height}`} style={{ display: 'block' }}>
      {[0, 0.25, 0.5, 0.75, 1].map((f) => (
        <line key={f} x1={pad.l} x2={width - pad.r} y1={y(f)} y2={y(f)} stroke="var(--line-1)" strokeWidth="1" />
      ))}
      {/* scope */}
      <line x1={pad.l} x2={width - pad.r} y1={y(1)} y2={y(1)} stroke="var(--line-2)" strokeWidth="1.5" />
      <text x={pad.l} y={y(1) - 6} style={{ font: '400 10.5px var(--font-mono)', fill: 'var(--ink-3)' }}>
        scope · {data.scope} {data.scope === 1 ? 'issue' : 'issues'}
      </text>
      {/* cone */}
      <polygon points={cone} fill="var(--cone-fill)" />
      <polyline points={hi} fill="none" stroke="var(--cone-line)" strokeWidth="1.2" strokeDasharray="3 3" />
      <polyline points={lo} fill="none" stroke="var(--cone-line)" strokeWidth="1.2" strokeDasharray="3 3" />
      <polyline points={mid} fill="none" stroke="var(--cone-line)" strokeWidth="1.4" />
      {/* origin = today, 0% of remaining scope */}
      <circle cx={x(0)} cy={y(0)} r="3.5" fill="var(--cone-actual)" />
      {/* today rule */}
      <line x1={x(0)} x2={x(0)} y1={pad.t} y2={height - pad.b} stroke="var(--jade)" strokeWidth="1" />
      <text x={x(0) + 5} y={pad.t + 10} style={{ font: '400 10.5px var(--font-mono)', fill: 'var(--jade-7)' }}>
        today
      </text>
      {/* 80% band label */}
      <text x={width - pad.r + 10} y={y(0.95)} style={{ font: '500 11.5px var(--font-mono)', fill: 'var(--ink-1)' }}>
        80%
      </text>
      <text x={width - pad.r + 10} y={y(0.95) + 14} style={{ font: '400 11px var(--font-mono)', fill: 'var(--ink-2)' }}>
        {data.rangeLabel}
      </text>
      {/* x labels */}
      <text x={pad.l} y={height - 8} style={{ font: '400 10.5px var(--font-mono)', fill: 'var(--ink-3)' }}>
        {data.startLabel}
      </text>
      <text x={width - pad.r - 34} y={height - 8} style={{ font: '400 10.5px var(--font-mono)', fill: 'var(--ink-3)' }}>
        {data.endLabel}
      </text>
    </svg>
  )
}

export interface RunwayBarMilestone {
  tone: 'ok' | 'warn'
  pos: number
  spread: number
}

/** Milestone due-date vs forecast-range position. Used by the Runway screen (P3-5). */
export function RunwayBar({ m }: { m: RunwayBarMilestone }) {
  const toneColor = m.tone === 'warn' ? 'var(--warn)' : 'var(--ok)'
  const left = Math.max(0, (m.pos - m.spread / 2) * 100)
  const w = Math.min(100 - left, m.spread * 100)
  return (
    <div style={{ position: 'relative', height: 22, background: 'var(--paper-2)', borderRadius: 4, overflow: 'hidden' }}>
      <div
        style={{
          position: 'absolute',
          left: `${left}%`,
          width: `${w}%`,
          top: 0,
          bottom: 0,
          background: 'var(--cone-fill)',
          borderLeft: `1.5px solid ${toneColor}`,
          borderRight: `1.5px solid ${toneColor}`,
        }}
      />
      <div style={{ position: 'absolute', left: `${m.pos * 100}%`, top: 0, bottom: 0, width: 2, background: toneColor }} />
      <div style={{ position: 'absolute', left: 'calc(88% - 1px)', top: 0, bottom: 0, width: 2, background: 'var(--ink-1)' }} />
    </div>
  )
}
