"""Kontrola integrity vygenerovaných meshů."""
from __future__ import annotations

import numpy as np

from .raster import mesh_volume


def check_mesh(vertices: np.ndarray, faces: np.ndarray) -> dict:
    n_f = int(faces.shape[0])
    res = {
        "n_vertices": int(vertices.shape[0]),
        "n_faces": n_f,
        "watertight": False,
        "manifold": False,
        "consistent_orientation": False,
        "n_boundary_edges": 0,
        "n_nonmanifold_edges": 0,
        "n_degenerate_faces": 0,
        "volume_mm3": 0.0,
        "euler": None,
    }
    if n_f == 0:
        return res

    v0 = vertices[faces[:, 0]]
    v1 = vertices[faces[:, 1]]
    v2 = vertices[faces[:, 2]]
    area = 0.5 * np.linalg.norm(np.cross(v1 - v0, v2 - v0), axis=1)
    res["n_degenerate_faces"] = int((area <= 0.0).sum())

    e = np.concatenate([faces[:, [0, 1]], faces[:, [1, 2]], faces[:, [2, 0]]],
                       axis=0).astype(np.int64)
    nv = int(vertices.shape[0]) + 1
    lo = e.min(axis=1)
    hi = e.max(axis=1)
    key = lo * nv + hi                      # neorientovaná hrana
    ukey, counts = np.unique(key, return_counts=True)
    res["n_boundary_edges"] = int((counts == 1).sum())
    res["n_nonmanifold_edges"] = int((counts > 2).sum())
    res["watertight"] = bool(res["n_boundary_edges"] == 0)
    res["manifold"] = bool(res["n_nonmanifold_edges"] == 0 and res["watertight"])

    # konzistentní orientace: každá orientovaná hrana se vyskytne právě jednou
    dkey = e[:, 0] * nv + e[:, 1]
    dc = np.unique(dkey, return_counts=True)[1]
    res["consistent_orientation"] = bool(dc.max() == 1) if dc.size else False

    res["volume_mm3"] = mesh_volume(vertices, faces)
    res["euler"] = int(vertices.shape[0] - ukey.size + n_f)
    return res
