#!/usr/bin/env python3
"""
Site Grid — toprak ızgarasının SADAKAT ölçümü.

SORU: 250 m'lik yerel SoilGrids pikselini 0,01° (~1,1 km) hücrede ortalayınca
ne kaybediyoruz?

NEDEN REST ÖNBELLEĞİYLE DEĞİL: pilot bbox'ta mevcut REST önbelleğinde YALNIZ
2 nokta var (ölçüldü 2026-09-04); n=2 ile kayıp ölçülmez. Bunun yerine kayıp
DOĞRUDAN kaynağına karşı ölçülür: her 0,01° hücresinin ortalaması, o hücrenin
MERKEZİNE düşen yerel 250 m pikseliyle karşılaştırılır. Mevcut motor pratikte
parselin centroid'indeki tek pikseli okuduğu için karşılaştırma birebir yerinde.

n = ızgaradaki tüm hücreler (pilotta ~149 bin).
"""

from __future__ import annotations

import argparse
import sys

from config import OUT_DIR, PILOT_BBOX, TURKEY_BBOX

try:
    import numpy as np
    import pandas as pd
except ImportError:
    print("HATA: numpy/pandas gerekli.", file=sys.stderr)
    raise SystemExit(4) from None

# 04_build_soil_grid.py ile aynı sabitler
sys.path.insert(0, str((__import__("pathlib").Path(__file__).parent)))
from importlib import import_module  # noqa: E402

_b = import_module("04_build_soil_grid")


def main() -> int:
    ap = argparse.ArgumentParser()
    ap.add_argument("--full", action="store_true")
    args = ap.parse_args()
    bbox = TURKEY_BBOX if args.full else PILOT_BBOX

    grid_path = OUT_DIR / f"soil_grid_{bbox.name}.csv"
    if not grid_path.exists():
        print(f"HATA: {grid_path} yok. Önce 04_build_soil_grid.py çalıştır.", file=sys.stderr)
        return 3
    grid = pd.read_csv(grid_path)

    print(f"Izgara: {len(grid):,} hücre @ {_b.SOIL_GRID_STEP}°")
    print("Yerel 250 m piksel okunuyor (hücre merkezleri)...\n")

    rows = []
    for prop, col in (("phh2o", "ph"), ("sand", "sand"), ("clay", "clay")):
        arr, geo = _b.weighted_depth_mean(bbox, prop)
        lon0, lat0, dlon, dlat = geo
        ny, nx = arr.shape

        # Hücre merkezindeki yerel piksel indeksleri
        jx = np.round((grid["lng"].to_numpy() - lon0) / dlon - 0.5).astype(int)
        iy = np.round((lat0 - grid["lat"].to_numpy()) / dlat - 0.5).astype(int)
        ok = (jx >= 0) & (jx < nx) & (iy >= 0) & (iy < ny)

        native = np.full(len(grid), np.nan)
        native[ok] = arr[iy[ok], jx[ok]]
        cell = grid[col].to_numpy()

        m = np.isfinite(native) & np.isfinite(cell)
        d = cell[m] - native[m]
        rows.append(
            {
                "alan": col,
                "n": int(m.sum()),
                "MAE": round(float(np.mean(np.abs(d))), 3),
                "bias": round(float(np.mean(d)), 3),
                "P95_abs": round(float(np.percentile(np.abs(d), 95)), 3),
                "maks_abs": round(float(np.max(np.abs(d))), 3),
            }
        )

    out = pd.DataFrame(rows)
    print(out.to_string(index=False))
    print(
        "\nOkuma: 'bias' sistematik kayma, 'MAE' ortalama mutlak sapma.\n"
        "pH icin MAE < 0,10 ihmal edilebilir sayilir (SoilGrids'in kendi\n"
        "belirsizligi zaten bundan buyuk); kum/kil icin MAE < 1,0 puan."
    )
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
