'use client'

import { useEffect, useRef, useState, useCallback, memo } from 'react'
import { useTranslations } from 'next-intl'
import {
  Chart as ChartJS,
  LineElement,
  PointElement,
  LinearScale,
  CategoryScale,
  Title,
  Tooltip,
  Legend,
  Filler
} from 'chart.js'
import { Line } from 'react-chartjs-2'
import Card from '@mui/material/Card'
import CardContent from '@mui/material/CardContent'
import Typography from '@mui/material/Typography'
import Box from '@mui/material/Box'
import Grid from '@mui/material/Grid2'
import Button from '@mui/material/Button'

ChartJS.register(LineElement, PointElement, LinearScale, CategoryScale, Title, Tooltip, Legend, Filler)

// ─── Types ───────────────────────────────────────────────────────────────────

interface Leaf {
  id: number
  side: 'left' | 'right'
  heightFraction: number
  scale: number
  swayOffset: number
  length: number
  branchId: number | null  // null = on main stem, number = on a branch
}

interface Branch {
  id: number
  side: 'left' | 'right'
  heightFraction: number   // where on stem it starts (0..1)
  length: number           // branch length px
  angle: number            // base angle in degrees
  scale: number            // 0..1 grow-in
  swayOffset: number
  thickness: number        // px
}

interface Fruit {
  id: number
  branchId: number | null
  leafId: number
  side: 'left' | 'right'
  scale: number
  swayOffset: number
  color: string
  size: number             // varied fruit radius
}

interface PlantState {
  height: number
  leaves: Leaf[]
  branches: Branch[]
  fruits: Fruit[]
  tick: number
  yield: number
  yieldRate: number
}

interface EnvironmentSettings {
  light: number
  water: number
}

// ─── Constants ───────────────────────────────────────────────────────────────

const MAX_HEIGHT = 280
const MAX_YIELD = 500
const SVG_W = 280
const SVG_H = 400
const STEM_X = SVG_W / 2
const BASE_Y = SVG_H - 24
const LEAF_INTERVAL_PX = 30
const MAX_LEAVES = 14
const MAX_BRANCHES = 6
const FRUIT_COLORS = ['#ef4444', '#f97316', '#eab308', '#f472b6', '#a855f7', '#22c55e']

// ─── Helper: compute growth speed multiplier from env settings ────────────────

function growthRate(env: EnvironmentSettings, speed: number): number {
  const lightFactor = 0.3 + (env.light / 100) * 0.7
  const waterFactor = 0.3 + (env.water / 100) * 0.7
  return speed * lightFactor * waterFactor
}

// Yield rate in g/s: leaves and height progress amplify yield production
function computeYieldRate(env: EnvironmentSettings, leafCount: number, heightProgress: number): number {
  const lightFactor = 0.2 + (env.light / 100) * 0.8
  const waterFactor = 0.2 + (env.water / 100) * 0.8
  const leafFactor = leafCount / MAX_LEAVES
  // yield only starts after 20% growth and accelerates with more leaves
  const maturityFactor = Math.max(0, (heightProgress - 0.2) / 0.8)
  return parseFloat((MAX_YIELD * 0.012 * lightFactor * waterFactor * leafFactor * maturityFactor).toFixed(3))
}

// ─── Helpers: quadratic bezier point / tangent at t ─────────────────────────

function qBez(p0: number, p1: number, p2: number, t: number) {
  return (1 - t) * (1 - t) * p0 + 2 * (1 - t) * t * p1 + t * t * p2
}

function qBezTan(p0: number, p1: number, p2: number, t: number) {
  return 2 * (1 - t) * (p1 - p0) + 2 * t * (p2 - p1)
}

// ─── Plant SVG Component ──────────────────────────────────────────────────────

function PlantSVG({ plant, tick, running }: { plant: PlantState; tick: number; running: boolean }) {
  const stemTop = BASE_Y - plant.height
  const progress = plant.height / MAX_HEIGHT
  const stemW = 6 + Math.min(progress * 7, 7)

  const sway = Math.sin(tick / 55) * 3

  // Stem control points — quadratic Bezier
  const s0x = STEM_X, s0y = BASE_Y
  const s1x = STEM_X + sway * 0.4, s1y = stemTop + plant.height * 0.5
  const s2x = STEM_X + sway, s2y = stemTop

  // Get point on main stem at fraction t (0=base, 1=top)
  const stemPt = (t: number) => ({
    x: qBez(s0x, s1x, s2x, t),
    y: qBez(s0y, s1y, s2y, t)
  })

  // Get angle on main stem at t
  const stemAngle = (t: number) => {
    const dx = qBezTan(s0x, s1x, s2x, t)
    const dy = qBezTan(s0y, s1y, s2y, t)
    return (Math.atan2(dy, dx) * 180) / Math.PI
  }

  // Get branch tip position
  const branchTip = (b: Branch) => {
    const base = stemPt(b.heightFraction)
    const dir = b.side === 'left' ? -1 : 1
    const bSway = Math.sin(tick / 30 + b.swayOffset) * 4 * b.scale
    const rad = ((b.angle + bSway) * Math.PI) / 180
    const len = b.length * b.scale
    return {
      bx: base.x,
      by: base.y,
      tx: base.x + Math.cos(rad) * len * dir,
      ty: base.y + Math.sin(rad) * len,
      cx: base.x + Math.cos(rad) * len * 0.5 * dir,
      cy: base.y + Math.sin(rad) * len * 0.35 - 8 * b.scale
    }
  }

  return (
    <svg width={SVG_W} height={SVG_H} viewBox={`0 0 ${SVG_W} ${SVG_H}`} className='drop-shadow-2xl'>
      <defs>
        <linearGradient id='sg' x1='0' y1='1' x2='0' y2='0'>
          <stop offset='0%' stopColor='#24462e' />
          <stop offset='50%' stopColor='#3d7a4f' />
          <stop offset='100%' stopColor='#6ab870' />
        </linearGradient>
        <linearGradient id='bg' x1='0' y1='0' x2='0' y2='1'>
          <stop offset='0%' stopColor='#4a8c5a' />
          <stop offset='100%' stopColor='#2e5a38' />
        </linearGradient>
        <radialGradient id='soilG' cx='50%' cy='40%' r='60%'>
          <stop offset='0%' stopColor='#b08030' />
          <stop offset='100%' stopColor='#4a2c0a' />
        </radialGradient>
        <filter id='fglow' x='-50%' y='-50%' width='200%' height='200%'>
          <feGaussianBlur stdDeviation='2' result='b' />
          <feMerge><feMergeNode in='b' /><feMergeNode in='SourceGraphic' /></feMerge>
        </filter>
        <filter id='lsh' x='-30%' y='-30%' width='160%' height='160%'>
          <feDropShadow dx='0.8' dy='1.2' stdDeviation='1.2' floodColor='#0a2010' floodOpacity='0.35' />
        </filter>
      </defs>

      {/* ── Floating pollen particles ── */}
      {running && progress > 0.35 && [0, 1, 2, 3, 4, 5].map(i => {
        const px = STEM_X + Math.sin(tick / 28 + i * 1.1) * 40
        const cycle = (tick * 0.35 + i * 30) % 80
        const py = stemTop - 12 - cycle
        return <circle key={`p${i}`} cx={px} cy={py} r={1.4} fill='#fde68a' opacity={Math.max(0, 0.55 - cycle / 160)} />
      })}

      {/* ── Soil mound ── */}
      <ellipse cx={STEM_X} cy={BASE_Y + 8} rx={58} ry={14} fill='url(#soilG)' opacity={0.9} />
      {[-24, -10, 4, 16, 28].map(dx => (
        <line key={dx} x1={STEM_X + dx} y1={BASE_Y + 5} x2={STEM_X + dx + 5} y2={BASE_Y + 10}
          stroke='#2a1400' strokeWidth={0.8} opacity={0.35} />
      ))}
      {/* Small grass tufts */}
      {[-30, -14, 18, 32].map((dx, i) => (
        <path key={`grass${i}`}
          d={`M${STEM_X + dx} ${BASE_Y + 3} q${2} ${-6} ${0} ${-10} M${STEM_X + dx + 3} ${BASE_Y + 3} q${-1} ${-5} ${1} ${-8}`}
          stroke='#5a9a5a' strokeWidth={0.8} fill='none' opacity={0.4} />
      ))}

      {/* ── Roots ── */}
      {plant.height > 15 && (
        <g opacity={0.4 + progress * 0.15}>
          {[
            { dx: -22, dy: 22, w: 2.2, cx: -10, cy: 8 },
            { dx: 18, dy: 20, w: 1.8, cx: 8, cy: 10 },
            { dx: -8, dy: 24, w: 1.2, cx: -4, cy: 12 },
            { dx: 12, dy: 18, w: 1, cx: 6, cy: 14 }
          ].map((r, i) => (
            <path key={`root${i}`}
              d={`M${STEM_X} ${BASE_Y} Q${STEM_X + r.cx} ${BASE_Y + r.cy} ${STEM_X + r.dx} ${BASE_Y + r.dy}`}
              stroke='#3b2a12' strokeWidth={r.w} fill='none' strokeLinecap='round' />
          ))}
        </g>
      )}

      {/* ── Main stem (quadratic bezier) ── */}
      {plant.height > 0 && (
        <>
          <path d={`M${s0x} ${s0y} Q${s1x} ${s1y} ${s2x} ${s2y}`}
            stroke='url(#sg)' strokeWidth={stemW} fill='none' strokeLinecap='round' />
          {/* Stem highlight vein */}
          <path d={`M${s0x + 1.5} ${s0y - 6} Q${s1x + 1.5} ${s1y} ${s2x + 1.5} ${s2y + 6}`}
            stroke='rgba(160,220,140,0.2)' strokeWidth={1.8} fill='none' strokeLinecap='round' />
          {/* Stem node bumps — small circles at branch attachment points */}
          {plant.branches.map(b => {
            const pt = stemPt(b.heightFraction)
            return <circle key={`node${b.id}`} cx={pt.x} cy={pt.y} r={stemW * 0.5 + 1}
              fill='#3a6a42' opacity={b.scale * 0.6} />
          })}
        </>
      )}

      {/* ── Branches (curved) ── */}
      {plant.branches.map(b => {
        const { bx, by, tx, ty, cx, cy } = branchTip(b)
        const bw = b.thickness * b.scale
        return (
          <g key={`br${b.id}`} opacity={b.scale}>
            <path d={`M${bx} ${by} Q${cx} ${cy} ${tx} ${ty}`}
              stroke='url(#bg)' strokeWidth={bw} fill='none' strokeLinecap='round' />
            {/* branch highlight */}
            <path d={`M${bx} ${by} Q${cx - 0.5} ${cy - 0.5} ${tx} ${ty}`}
              stroke='rgba(150,210,130,0.15)' strokeWidth={bw * 0.4} fill='none' strokeLinecap='round' />
            {/* small thorn/bud at tip */}
            <circle cx={tx} cy={ty} r={bw * 0.5 + 0.5} fill='#5a9a52' opacity={0.7} />
          </g>
        )
      })}

      {/* ── Leaves ── */}
      {plant.leaves.map(leaf => {
        let ax: number, ay: number
        if (leaf.branchId != null) {
          const branch = plant.branches.find(b => b.id === leaf.branchId)
          if (!branch) return null
          const tip = branchTip(branch)
          ax = tip.tx
          ay = tip.ty
        } else {
          const pt = stemPt(leaf.heightFraction)
          ax = pt.x
          ay = pt.y
        }

        const swayA = Math.sin(tick / 20 + leaf.swayOffset) * 6
        const dir = leaf.side === 'left' ? -1 : 1
        const rot = dir * 35 + swayA
        const lx = leaf.length * leaf.scale
        const ly = leaf.length * 0.4 * leaf.scale
        const hue = 110 + leaf.id * 3
        const lit = 30 + leaf.id * 1.8
        const c1 = `hsl(${hue},65%,${lit}%)`
        const c2 = `hsl(${hue},55%,${lit + 14}%)`

        return (
          <g key={`lf${leaf.id}`} transform={`translate(${ax},${ay}) rotate(${rot})`}
            filter='url(#lsh)' opacity={Math.min(leaf.scale * 1.4, 1)}>
            {/* Leaf shape — custom path for more natural look */}
            <path
              d={`M0,0 Q${dir * lx * 0.3},${-ly * 0.9} ${dir * lx},${-ly * 0.15}
                  Q${dir * lx * 0.55},${ly * 0.5} 0,0`}
              fill={c1} />
            {/* Midrib */}
            <line x1={0} y1={0} x2={dir * lx * 0.95} y2={-ly * 0.12}
              stroke={c2} strokeWidth={0.9} opacity={0.7} />
            {/* Side veins */}
            {[0.25, 0.45, 0.65, 0.8].map((t, vi) => {
              const vx = dir * lx * t * 0.95
              const vy = -ly * 0.12 * t
              return (
                <line key={vi} x1={vx} y1={vy}
                  x2={vx + dir * lx * 0.12} y2={vy - ly * (0.35 + vi * 0.08)}
                  stroke={c2} strokeWidth={0.55} opacity={0.45} />
              )
            })}
          </g>
        )
      })}

      {/* ── Fruits on branches and stem ── */}
      {plant.fruits.map(fruit => {
        const leaf = plant.leaves.find(l => l.id === fruit.leafId)
        if (!leaf) return null

        let ox: number, oy: number
        if (fruit.branchId != null) {
          const branch = plant.branches.find(b => b.id === fruit.branchId)
          if (!branch) return null
          const tip = branchTip(branch)
          ox = tip.tx
          oy = tip.ty
        } else {
          const pt = stemPt(leaf.heightFraction)
          ox = pt.x
          oy = pt.y
        }

        const fSway = Math.sin(tick / 25 + fruit.swayOffset) * 3
        const dir = fruit.side === 'left' ? -1 : 1
        const fr = fruit.size * fruit.scale
        const fx = ox + dir * (12 + fr) + fSway
        const fy = oy + 4 * fruit.scale

        return (
          <g key={`fr${fruit.id}`} filter='url(#fglow)' opacity={Math.min(fruit.scale * 1.3, 1)}>
            {/* Hanging stem */}
            <path d={`M${ox + dir * 3} ${oy} Q${(ox + fx) / 2} ${oy - 4} ${fx} ${fy - fr}`}
              stroke='#4a7c42' strokeWidth={1} fill='none' strokeLinecap='round' />
            {/* Fruit body */}
            <circle cx={fx} cy={fy} r={fr} fill={fruit.color} />
            {/* Depth gradient */}
            <circle cx={fx + fr * 0.15} cy={fy + fr * 0.15} r={fr * 0.7}
              fill='rgba(0,0,0,0.12)' />
            {/* Shine */}
            <circle cx={fx - fr * 0.25} cy={fy - fr * 0.3} r={fr * 0.3}
              fill='white' opacity={0.4} />
            {/* Calyx (small leaves on top) */}
            <ellipse cx={fx - 2} cy={fy - fr - 1} rx={fr * 0.35} ry={fr * 0.15}
              fill='#3d7a30' opacity={0.85} transform={`rotate(-15,${fx - 2},${fy - fr - 1})`} />
            <ellipse cx={fx + 2} cy={fy - fr - 1} rx={fr * 0.35} ry={fr * 0.15}
              fill='#4a8a3a' opacity={0.75} transform={`rotate(15,${fx + 2},${fy - fr - 1})`} />
          </g>
        )
      })}

      {/* ── Top bud → flower ── */}
      {progress > 0.55 && (() => {
        const bs = Math.min((progress - 0.55) / 0.3, 1)
        const tx = s2x
        const ty = s2y - 4
        const ps = Math.sin(tick / 32) * 5

        return (
          <g opacity={bs}>
            {/* Sepals (green base petals) */}
            {[0, 72, 144, 216, 288].map(deg => {
              const r = ((deg + ps * 0.5) * Math.PI) / 180
              return (
                <ellipse key={`sep${deg}`}
                  cx={tx + Math.cos(r) * 7 * bs} cy={ty + Math.sin(r) * 7 * bs}
                  rx={4.5 * bs} ry={2 * bs} fill='#4a8c42' opacity={0.6}
                  transform={`rotate(${deg},${tx + Math.cos(r) * 7 * bs},${ty + Math.sin(r) * 7 * bs})`} />
              )
            })}
            {/* Petals — larger, appear after 80% */}
            {progress > 0.8 && [0, 45, 90, 135, 180, 225, 270, 315].map(deg => {
              const petalScale = Math.min((progress - 0.8) / 0.15, 1)
              const r = ((deg + ps) * Math.PI) / 180
              const pd = 10 * petalScale * bs
              return (
                <ellipse key={`pet${deg}`}
                  cx={tx + Math.cos(r) * pd} cy={ty + Math.sin(r) * pd}
                  rx={5 * petalScale * bs} ry={2.8 * petalScale * bs}
                  fill={deg % 90 === 0 ? '#fde68a' : '#fcd34d'} opacity={0.9}
                  transform={`rotate(${deg + ps},${tx + Math.cos(r) * pd},${ty + Math.sin(r) * pd})`} />
              )
            })}
            {/* Centre */}
            <circle cx={tx} cy={ty} r={5.5 * bs} fill='#f9c74f' />
            <circle cx={tx} cy={ty} r={3 * bs} fill='#f3722c' />
            {/* Orbiting pollen */}
            {progress > 0.88 && [0, 1, 2, 3, 4, 5].map(i => {
              const a = (tick / 18 + i * 1.05) % (Math.PI * 2)
              const or = 13 * bs
              return <circle key={`pln${i}`} cx={tx + Math.cos(a) * or} cy={ty + Math.sin(a) * or}
                r={1.3} fill='#fde68a' opacity={0.65} />
            })}
          </g>
        )
      })()}
    </svg>
  )
}

// ─── Growth Chart ─────────────────────────────────────────────────────────────

const GrowthChart = memo(function GrowthChart({
  heightHistory,
  leafHistory,
  yieldHistory,
  yieldRateHistory
}: {
  heightHistory: number[]
  leafHistory: number[]
  yieldHistory: number[]
  yieldRateHistory: number[]
}) {
  const t = useTranslations('plantSimulator')

  const chartOptions = {
    responsive: true,
    maintainAspectRatio: false,
    animation: { duration: 0 },
    plugins: {
      legend: { labels: { font: { size: 11 } } },
      title: {
        display: true,
        text: t('chartTitle'),
        font: { size: 14 }
      }
    },
    scales: {
      x: {
        ticks: { maxTicksLimit: 8 }
      },
      yHeight: {
        type: 'linear' as const,
        position: 'left' as const,
        min: 0,
        max: MAX_HEIGHT,
        title: { display: true, text: t('chartHeight') }
      },
      yLeaf: {
        type: 'linear' as const,
        position: 'right' as const,
        min: 0,
        max: MAX_LEAVES,
        grid: { display: false },
        title: { display: true, text: t('chartLeaves') }
      },
      yYield: {
        type: 'linear' as const,
        position: 'left' as const,
        min: 0,
        max: MAX_YIELD,
        display: false,
        grid: { display: false }
      },
      yYieldRate: {
        type: 'linear' as const,
        position: 'right' as const,
        min: 0,
        display: false,
        grid: { display: false }
      }
    }
  }

  const labels = heightHistory.map((_, i) => `${i}s`)

  const data = {
    labels,
    datasets: [
      {
        label: t('chartHeightPx'),
        data: heightHistory,
        borderColor: '#4a7c59',
        backgroundColor: 'rgba(74,124,89,0.10)',
        fill: true,
        tension: 0.4,
        pointRadius: 0,
        yAxisID: 'yHeight'
      },
      {
        label: t('chartLeafCount'),
        data: leafHistory,
        borderColor: '#f9c74f',
        backgroundColor: 'rgba(249,199,79,0.10)',
        fill: true,
        tension: 0.4,
        pointRadius: 0,
        yAxisID: 'yLeaf'
      },
      {
        label: t('chartYield'),
        data: yieldHistory,
        borderColor: '#f97316',
        backgroundColor: 'rgba(249,115,22,0.10)',
        fill: true,
        tension: 0.4,
        pointRadius: 0,
        yAxisID: 'yYield'
      },
      {
        label: t('chartYieldRate'),
        data: yieldRateHistory,
        borderColor: '#a78bfa',
        backgroundColor: 'rgba(167,139,250,0.10)',
        fill: true,
        tension: 0.4,
        pointRadius: 0,
        borderDash: [4, 3],
        yAxisID: 'yYieldRate'
      }
    ]
  }

  return (
    <Box
      className='is-full'
      sx={{ minHeight: { xs: 380, sm: 340, md: 320 }, height: { xs: 380, sm: 340, md: 320 } }}
    >
      <Line data={data} options={chartOptions} />
    </Box>
  )
})

// ─── Main Component ───────────────────────────────────────────────────────────

const INIT_PLANT: PlantState = { height: 0, leaves: [], branches: [], fruits: [], tick: 0, yield: 0, yieldRate: 0 }

export default function PlantSimulator() {
  const [running, setRunning] = useState(false)
  const [speed, setSpeed] = useState(1.5)
  const [env, setEnv] = useState<EnvironmentSettings>({ light: 75, water: 65 })

  const [plant, setPlant] = useState<PlantState>(INIT_PLANT)
  const [heightHistory, setHeightHistory] = useState<number[]>([0])
  const [leafHistory, setLeafHistory] = useState<number[]>([0])
  const [yieldHistory, setYieldHistory] = useState<number[]>([0])
  const [yieldRateHistory, setYieldRateHistory] = useState<number[]>([0])

  const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null)
  const tickRef = useRef(0)
  const historyIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null)
  const plantRef = useRef<PlantState>(plant)
  plantRef.current = plant

  const reset = useCallback(() => {
    setPlant(INIT_PLANT)
    setHeightHistory([0])
    setLeafHistory([0])
    setYieldHistory([0])
    setYieldRateHistory([0])
    tickRef.current = 0
  }, [])

  // Stop simulation when plant reaches max height
  useEffect(() => {
    if (plant.height >= MAX_HEIGHT && running) setRunning(false)
  }, [plant.height, running])

  // Main simulation tick at ~20fps (reduced from 30fps to prevent browser overload)
  useEffect(() => {
    if (!running) {
      if (intervalRef.current) clearInterval(intervalRef.current)
      return
    }

    intervalRef.current = setInterval(() => {
      tickRef.current += 1
      const t = tickRef.current

      setPlant(prev => {
        const rate = growthRate(env, speed)
        const newHeight = Math.min(prev.height + rate * 0.4, MAX_HEIGHT)
        const hp = newHeight / MAX_HEIGHT

        // ── Branches: appear after 30% growth ──
        const newBranches = [...prev.branches]
        const expectedBranches = Math.min(Math.floor((hp - 0.3) / 0.12), MAX_BRANCHES)
        while (newBranches.length < Math.max(0, expectedBranches)) {
          const bid = newBranches.length
          newBranches.push({
            id: bid,
            side: bid % 2 === 0 ? 'left' : 'right',
            heightFraction: 0.25 + bid * 0.11,
            length: 30 + Math.random() * 25,
            angle: -(25 + Math.random() * 20),
            scale: 0,
            swayOffset: Math.random() * Math.PI * 2,
            thickness: 2.5 + Math.random() * 1.5
          })
        }
        const grownBranches = newBranches.map(b => ({
          ...b,
          scale: Math.min(b.scale + 0.012, 1)
        }))

        // ── Leaves: on main stem + on branch tips ──
        const newLeaves = [...prev.leaves]
        const expectedStemLeaves = Math.min(Math.floor(newHeight / LEAF_INTERVAL_PX), MAX_LEAVES)

        // Stem leaves (fixed: use 'added' counter; nextId-newLeaves.length was always 0 → infinite loop)
        const stemLeafCount = newLeaves.filter(l => l.branchId === null).length
        let nextId = newLeaves.length
        let added = 0
        while (stemLeafCount + added < expectedStemLeaves) {
          const idx = stemLeafCount + added
          newLeaves.push({
            id: nextId,
            side: idx % 2 === 0 ? 'left' : 'right',
            heightFraction: (idx + 1) / (expectedStemLeaves + 1),
            scale: 0,
            swayOffset: Math.random() * Math.PI * 2,
            length: 16 + Math.random() * 14,
            branchId: null
          })
          nextId++
          added++
        }

        // Branch-tip leaves (1 per mature branch, once branch scale > 0.6)
        for (const b of grownBranches) {
          if (b.scale > 0.6) {
            const hasLeaf = newLeaves.some(l => l.branchId === b.id)
            if (!hasLeaf) {
              newLeaves.push({
                id: nextId++,
                side: b.side,
                heightFraction: b.heightFraction,
                scale: 0,
                swayOffset: Math.random() * Math.PI * 2,
                length: 14 + Math.random() * 10,
                branchId: b.id
              })
            }
          }
        }

        const grownLeaves = newLeaves.map(l => ({
          ...l,
          scale: Math.min(l.scale + 0.018, 1)
        }))

        // ── Yield ──
        const currentYieldRate = computeYieldRate(env, grownLeaves.length, hp)
        const newYield = Math.min(prev.yield + currentYieldRate * 0.033, MAX_YIELD)

        // ── Fruits: appear after 45% on branches, then some on stem ──
        const newFruits = [...prev.fruits]
        const maxFruits = Math.min(Math.floor((hp - 0.45) / 0.08), grownBranches.length + 3)
        let fNextId = newFruits.length
        while (newFruits.length < Math.max(0, maxFruits)) {
          const fid = fNextId++
          // First fruits on branches, then on stem leaves
          const onBranch = fid < grownBranches.length
          const targetBranch = onBranch ? grownBranches[fid] : null
          const targetLeaf = onBranch
            ? grownLeaves.find(l => l.branchId === targetBranch!.id) || grownLeaves[fid]
            : grownLeaves[Math.min(fid, grownLeaves.length - 1)]
          if (!targetLeaf) break
          newFruits.push({
            id: fid,
            branchId: onBranch ? targetBranch!.id : null,
            leafId: targetLeaf.id,
            side: targetLeaf.side === 'left' ? 'right' : 'left',
            scale: 0,
            swayOffset: Math.random() * Math.PI * 2,
            color: FRUIT_COLORS[fid % FRUIT_COLORS.length],
            size: 5 + Math.random() * 4
          })
        }

        const grownFruits = newFruits.map(f => ({
          ...f,
          scale: Math.min(f.scale + 0.014, 1)
        }))

        return {
          height: newHeight,
          leaves: grownLeaves,
          branches: grownBranches,
          fruits: grownFruits,
          tick: t,
          yield: newYield,
          yieldRate: currentYieldRate
        }
      })
    }, 50)

    return () => {
      if (intervalRef.current) clearInterval(intervalRef.current)
    }
  }, [running, speed, env])

  // History logging every 1 second (reads from plantRef to avoid setPlant side-effects)
  useEffect(() => {
    if (!running) {
      if (historyIntervalRef.current) clearInterval(historyIntervalRef.current)
      return
    }

    historyIntervalRef.current = setInterval(() => {
      const p = plantRef.current
      setHeightHistory(h => [...h.slice(-59), Math.round(p.height)])
      setLeafHistory(l => [...l.slice(-59), p.leaves.length])
      setYieldHistory(y => [...y.slice(-59), parseFloat(p.yield.toFixed(1))])
      setYieldRateHistory(r => [...r.slice(-59), p.yieldRate])
    }, 1000)

    return () => {
      if (historyIntervalRef.current) clearInterval(historyIntervalRef.current)
    }
  }, [running])

  const t = useTranslations('plantSimulator')
  const isFinished = plant.height >= MAX_HEIGHT

  const statItems: { value: string | number; label: string; color: 'success' | 'warning' | 'error' | 'secondary' }[] = [
    { value: Math.round(plant.height), label: t('height'), color: 'success' },
    { value: plant.leaves.length, label: t('leaves'), color: 'warning' },
    { value: plant.branches.length, label: t('branches'), color: 'success' },
    { value: plant.fruits.length, label: t('fruits'), color: 'error' },
    { value: plant.yield.toFixed(1), label: t('yield'), color: 'warning' },
    { value: plant.yieldRate.toFixed(2), label: t('yieldRate'), color: 'secondary' }
  ]

  return (
    <Box className='flex flex-col gap-6 min-is-0 is-full'>
      <Typography variant='h4' className='text-center font-bold'>
        🌱 {t('title')}
      </Typography>

      <Grid container spacing={6} className='min-is-0 is-full'>
        {/* ── Left: Plant visualization ── */}
        <Grid size={{ xs: 12, lg: 4 }} className='flex flex-col items-center gap-4'>
          <Card className='is-full flex flex-col items-center p-6'>
            <CardContent className='flex flex-col items-center gap-4 is-full p-0'>
              <PlantSVG plant={plant} tick={plant.tick} running={running} />

              <Grid container spacing={2} className='is-full'>
                {statItems.map((item, idx) => (
                  <Grid key={idx} size={{ xs: 4 }}>
                    <Card variant='outlined' className='text-center p-2.5'>
                      <Typography variant='h6' color={item.color}>
                        {item.value}
                      </Typography>
                      <Typography variant='caption' color='text.secondary'>
                        {item.label}
                      </Typography>
                    </Card>
                  </Grid>
                ))}
              </Grid>

              {isFinished && (
                <Typography variant='body2' color='warning.main' className='font-medium animate-pulse'>
                  🌼 {t('maxGrowthReached')}
                </Typography>
              )}
            </CardContent>
          </Card>

          {/* Controls */}
          <Card className='is-full p-5'>
            <CardContent className='space-y-4 p-0'>
              <Typography variant='subtitle1' component='h2' className='font-semibold'>
                {t('controls')}
              </Typography>

              <Box className='flex gap-2'>
                <Button
                  variant='contained'
                  color={running ? 'error' : 'success'}
                  onClick={() => setRunning(r => !r)}
                  disabled={isFinished}
                  fullWidth
                >
                  {running ? `⏸ ${t('stop')}` : `▶ ${t('start')}`}
                </Button>
                <Button
                  variant='outlined'
                  color='secondary'
                  onClick={() => { setRunning(false); reset() }}
                >
                  ↺ {t('reset')}
                </Button>
              </Box>

              <Box>
                <Typography variant='body2' color='text.secondary' className='flex justify-between mbe-1'>
                  <span>{t('growthSpeed')}</span>
                  <span className='font-medium'>{speed.toFixed(1)}×</span>
                </Typography>
                <input
                  type='range'
                  min={0.5}
                  max={5}
                  step={0.5}
                  value={speed}
                  onChange={e => setSpeed(Number(e.target.value))}
                  className='w-full'
                />
              </Box>

              <Box>
                <Typography variant='body2' color='text.secondary' className='flex justify-between mbe-1'>
                  <span>☀️ {t('light')}</span>
                  <span className='font-medium'>{env.light}%</span>
                </Typography>
                <input
                  type='range'
                  min={0}
                  max={100}
                  step={5}
                  value={env.light}
                  onChange={e => setEnv(prev => ({ ...prev, light: Number(e.target.value) }))}
                  className='w-full'
                />
              </Box>

              <Box>
                <Typography variant='body2' color='text.secondary' className='flex justify-between mbe-1'>
                  <span>💧 {t('water')}</span>
                  <span className='font-medium'>{env.water}%</span>
                </Typography>
                <input
                  type='range'
                  min={0}
                  max={100}
                  step={5}
                  value={env.water}
                  onChange={e => setEnv(prev => ({ ...prev, water: Number(e.target.value) }))}
                  className='w-full'
                />
              </Box>

              <Card variant='outlined' className='p-3'>
                <Typography variant='caption' color='text.secondary'>
                  {t('effectiveRate')}{' '}
                  <Typography component='span' variant='caption' color='success.main' fontWeight='bold'>
                    {growthRate(env, speed).toFixed(2)}×
                  </Typography>
                </Typography>
              </Card>
            </CardContent>
          </Card>
        </Grid>

        {/* ── Right: Chart ── */}
        <Grid size={{ xs: 12, lg: 8 }}>
          <Card className='p-6'>
            <CardContent>
              <GrowthChart
                heightHistory={heightHistory}
                leafHistory={leafHistory}
                yieldHistory={yieldHistory}
                yieldRateHistory={yieldRateHistory}
              />

              <Grid container spacing={4} className='mt-6'>
                <Grid size={{ xs: 12, sm: 6, lg: 3 }}>
                  <Card variant='outlined' className='p-4'>
                    <Typography variant='body2' color='text.secondary' className='mbe-1'>
                      {t('progressGrowth')}
                    </Typography>
                    <Box className='w-full rounded-full overflow-hidden bg-action-hover mbe-1' sx={{ height: 8 }}>
                      <Box
                        className='bg-success rounded-full h-full transition-all'
                        sx={{ width: `${(plant.height / MAX_HEIGHT) * 100}%` }}
                      />
                    </Box>
                    <Typography variant='body2' color='success.main' fontWeight='bold'>
                      {Math.round((plant.height / MAX_HEIGHT) * 100)}%
                    </Typography>
                  </Card>
                </Grid>
                <Grid size={{ xs: 12, sm: 6, lg: 3 }}>
                  <Card variant='outlined' className='p-4'>
                    <Typography variant='body2' color='text.secondary' className='mbe-1'>
                      {t('lightStatus')}
                    </Typography>
                    <Box className='w-full rounded-full overflow-hidden bg-action-hover mbe-1' sx={{ height: 8 }}>
                      <Box
                        className='bg-warning rounded-full h-full transition-all'
                        sx={{ width: `${env.light}%` }}
                      />
                    </Box>
                    <Typography variant='body2' color='warning.main' fontWeight='bold'>
                      {env.light}%
                    </Typography>
                  </Card>
                </Grid>
                <Grid size={{ xs: 12, sm: 6, lg: 3 }}>
                  <Card variant='outlined' className='p-4'>
                    <Typography variant='body2' color='text.secondary' className='mbe-1'>
                      {t('waterStatus')}
                    </Typography>
                    <Box className='w-full rounded-full overflow-hidden bg-action-hover mbe-1' sx={{ height: 8 }}>
                      <Box
                        className='bg-info rounded-full h-full transition-all'
                        sx={{ width: `${env.water}%` }}
                      />
                    </Box>
                    <Typography variant='body2' color='info.main' fontWeight='bold'>
                      {env.water}%
                    </Typography>
                  </Card>
                </Grid>
                <Grid size={{ xs: 12, sm: 6, lg: 3 }}>
                  <Card variant='outlined' className='p-4'>
                    <Typography variant='body2' color='text.secondary' className='mbe-1'>
                      {t('yieldStatus')}
                    </Typography>
                    <Box className='w-full rounded-full overflow-hidden bg-action-hover mbe-1' sx={{ height: 8 }}>
                      <Box
                        className='bg-warning rounded-full h-full transition-all'
                        sx={{ width: `${(plant.yield / MAX_YIELD) * 100}%` }}
                      />
                    </Box>
                    <Box className='flex justify-between items-center'>
                      <Typography variant='body2' color='warning.main' fontWeight='bold'>
                        {plant.yield.toFixed(1)}g
                      </Typography>
                      <Typography variant='caption' color='secondary.main'>
                        {plant.yieldRate.toFixed(3)} g/s
                      </Typography>
                    </Box>
                  </Card>
                </Grid>
              </Grid>

              <Card variant='outlined' className='mt-6 p-4'>
                <Typography variant='body2' color='text.secondary' className='leading-6'>
                  {t('description')}
                </Typography>
              </Card>
            </CardContent>
          </Card>
        </Grid>
      </Grid>
    </Box>
  )
}
