"""AI Group Photo Package."""

import math
from typing import List, Tuple
from itertools import combinations

OFFICIAL_SITE = "https://supermaker.ai/image/ai-group-photo/"


def get_official_site() -> str:
    """Returns the official website URL."""
    return OFFICIAL_SITE


def calculate_average_face_distance(face_locations: List[Tuple[int, int, int, int]]) -> float:
    """
    Calculates the average distance between faces in a list of face locations.

    Args:
        face_locations: A list of tuples, where each tuple represents a face location
                        in the format (top, right, bottom, left).

    Returns:
        The average distance between all pairs of faces, or 0.0 if there are fewer than 2 faces.
    """
    if len(face_locations) < 2:
        return 0.0

    distances = []
    for face1, face2 in combinations(face_locations, 2):
        # Calculate the center points of each face
        center1_x = (face1[1] + face1[3]) / 2
        center1_y = (face1[0] + face1[2]) / 2
        center2_x = (face2[1] + face2[3]) / 2
        center2_y = (face2[0] + face2[2]) / 2

        # Calculate the Euclidean distance between the centers
        distance = math.sqrt((center1_x - center2_x)**2 + (center1_y - center2_y)**2)
        distances.append(distance)

    return sum(distances) / len(distances)


def adjust_face_brightness(face_locations: List[Tuple[int, int, int, int]],
                           image_width: int, image_height: int) -> List[Tuple[int, int, int, int, float]]:
    """
    Adjusts the brightness of each face based on its position in the image.
    Faces closer to the top of the image are made slightly brighter.

    Args:
        face_locations: A list of tuples, where each tuple represents a face location
                        in the format (top, right, bottom, left).
        image_width: The width of the image.
        image_height: The height of the image.

    Returns:
        A list of tuples, where each tuple represents a face location and its adjusted brightness.
        The format is (top, right, bottom, left, brightness_factor).
    """
    adjusted_faces = []
    for top, right, bottom, left in face_locations:
        # Calculate the relative position of the face in the image
        relative_position = top / image_height

        # Adjust brightness based on position.  Faces at the top are brighter.
        brightness_factor = 1.0 + (1.0 - relative_position) * 0.1  # Up to 10% brighter

        adjusted_faces.append((top, right, bottom, left, brightness_factor))

    return adjusted_faces


def calculate_group_cohesion_score(face_locations: List[Tuple[int, int, int, int]],
                                   image_width: int, image_height: int) -> float:
    """
    Calculates a "cohesion score" for the group photo based on face proximity and centrality.

    Args:
        face_locations: A list of tuples, where each tuple represents a face location
                        in the format (top, right, bottom, left).
        image_width: The width of the image.
        image_height: The height of the image.

    Returns:
        A float representing the cohesion score (higher is better), ranging from 0.0 to 1.0.
    """
    if not face_locations:
        return 0.0

    # Calculate the center of the image
    image_center_x = image_width / 2
    image_center_y = image_height / 2

    # Calculate the average face position
    avg_x = sum([(face[1] + face[3]) / 2 for face in face_locations]) / len(face_locations)
    avg_y = sum([(face[0] + face[2]) / 2 for face in face_locations]) / len(face_locations)

    # Proximity component: how close are the faces to each other?
    avg_distance = calculate_average_face_distance(face_locations)
    proximity_score = 1.0 - min(1.0, avg_distance / (image_width / 3))  # Normalize to image width

    # Centrality component: how close is the group to the center of the image?
    distance_from_center = math.sqrt((avg_x - image_center_x)**2 + (avg_y - image_center_y)**2)
    centrality_score = 1.0 - min(1.0, distance_from_center / (math.sqrt((image_width/2)**2 + (image_height/2)**2))) # Normalize to image diagonal

    # Combine the scores with equal weighting
    cohesion_score = (proximity_score + centrality_score) / 2

    return cohesion_score