package grib

import (
	"encoding/binary"
	"math"
	"os"

	mmap "github.com/edsrzf/mmap-go"
)

type cube struct {
	mm             mmap.MMap // read‑only, U followed by V (float32 LE)
	t, p, lat, lon int
	bytesPerVar    int64
	file           *os.File
}

func openCube(path string) (*cube, error) {
	f, err := os.Open(path)
	if err != nil {
		return nil, err
	}

	mm, err := mmap.Map(f, mmap.RDONLY, 0)
	if err != nil {
		f.Close()
		return nil, err
	}

	const (
		nT   = 17
		nP   = 34
		nLat = 361
		nLon = 720
	)

	return &cube{mm: mm, t: nT, p: nP, lat: nLat, lon: nLon, bytesPerVar: int64(nT * nP * nLat * nLon * 4), file: f}, nil
}

func (c *cube) val(varIdx, ti, pi, y, x int) float32 {
	idx := (((ti*c.p+pi)*c.lat + y) * c.lon) + x
	off := int64(varIdx)*c.bytesPerVar + int64(idx)*4
	bits := binary.LittleEndian.Uint32(c.mm[off : off+4])
	return math.Float32frombits(bits)
}

func (c *cube) Close() error {
	if c.mm != nil {
		c.mm.Unmap()
	}
	if c.file != nil {
		return c.file.Close()
	}
	return nil
}
