from __future__ import annotations

from typing import Sequence

import numpy as np


def get_largest_bbox_indices(bboxes: Sequence[Sequence[float]], num_bboxes: int = 2) -> list[int]:
    """Return indices of the largest bboxes by area (normalized coords are fine)."""
    if num_bboxes <= 0:
        return []

    bboxes_with_area: list[tuple[int, float]] = []
    for i, bbox in enumerate(bboxes):
        try:
            x1, y1, x2, y2 = bbox
        except Exception:
            continue
        area = max(0.0, float(x2) - float(x1)) * max(0.0, float(y2) - float(y1))
        bboxes_with_area.append((i, area))

    bboxes_with_area.sort(key=lambda x: x[1], reverse=True)
    return [idx for idx, _area in bboxes_with_area[: min(num_bboxes, len(bboxes_with_area))]]


def change_poses_to_limit_num(poses, bboxes, num_bboxes: int = 2):
    """Trim DWpose outputs to the top-N bboxes per frame (SCAIL-Pose multi-human helper)."""
    bboxes = list(bboxes)
    for frame_idx, (pose, bbox_list) in enumerate(zip(poses, bboxes)):
        if not bbox_list:
            continue

        largest_indices = get_largest_bbox_indices(bbox_list, num_bboxes)
        if not largest_indices:
            continue

        bodies = pose.get("bodies", {})
        if "candidate" in bodies:
            bodies["candidate"] = bodies["candidate"][largest_indices]
        if "subset" in bodies:
            bodies["subset"] = bodies["subset"][largest_indices]
        pose["bodies"] = bodies

        faces = pose.get("faces", None)
        if isinstance(faces, np.ndarray):
            pose["faces"] = faces[largest_indices]
        elif isinstance(faces, list):
            pose["faces"] = [faces[i] for i in largest_indices if i < len(faces)]

        hands = pose.get("hands", None)
        hand_indices = [j for i in largest_indices for j in (2 * i, 2 * i + 1)]
        if isinstance(hands, np.ndarray):
            pose["hands"] = hands[hand_indices]
        elif isinstance(hands, list):
            pose["hands"] = [hands[i] for i in hand_indices if i < len(hands)]

        bboxes[frame_idx] = [bbox_list[i] for i in largest_indices if i < len(bbox_list)]

    return poses, bboxes

