import numpy as np

from scipy.spatial import ConvexHull
from shapely.geometry import Polygon

from kinematic_tracker.types import FVT

from .poly_area import get_poly_area


def giou_3d_shapely(cuboid1: FVT, poly1: Polygon, cuboid2: FVT, poly2: Polygon) -> float:
    ha, hb = cuboid1[-1], cuboid2[-1]
    za, zb = cuboid1[2], cuboid2[2]
    za_m_zb = za - zb
    h_ab2 = (ha + hb) / 2
    diff1 = h_ab2 + za_m_zb
    diff2 = h_ab2 - za_m_zb
    over_height = max(0, min(diff1, diff2, ha, hb))
    union_height = max(diff1, diff2, ha, hb)

    inter_vol = poly1.intersection(poly2).area * over_height
    union_vol = cuboid1[-3:].prod() + cuboid2[-3:].prod() - inter_vol
    merged = np.concatenate((poly1.exterior.coords, poly2.exterior.coords))
    convex_hull = ConvexHull(merged)
    convex_corners = merged[convex_hull.vertices]
    convex_area = get_poly_area(convex_corners)
    convex_vol = convex_area * union_height
    giou_101 = inter_vol / union_vol - (convex_vol - union_vol) / convex_vol
    return (giou_101 + 1.0) / 2.0
