#!/usr/bin/env python
"""
Character Appearance Module

This module contains functions for generating character appearance attributes
including hair color, hair type, facial hair, accessories, and skin color.

These functions are used during character creation to generate realistic
and age-appropriate appearance characteristics based on demographics and
biological factors.
"""

import random
import numpy as np


def get_hair_color(person):
    """
    Determine hair color based on skin color and age.

    Args:
        person: A personClass instance with avatar_settings.skin_color and ageYears

    Returns:
        str: Hex color code for hair color

    Notes:
        - Hair color options are influenced by skin tone
        - Older characters (>50 years) have higher probability of blonde/grey hair
    """
    # Hair color reflecting skin color
    haircolors = [
        {"name": "Black", "hex": "2c1b18"},
        {"name": "Dark Brown", "hex": "4a312c"},
        {"name": "Chestnut Brown", "hex": "724133"},
        {"name": "Auburn", "hex": "a55728"},
        {"name": "Golden Brown", "hex": "b58143"},
        {"name": "Red", "hex": "c93305"},
        {"name": "Blonde", "hex": "d6b370"},
        {"name": "Light Grey", "hex": "e8e1e1"},
        {"name": "Dark Grey", "hex": "ecdcbf"},
        {"name": "Copper", "hex": "f59797"}
    ]

    # Helper function to get hex from name
    def get_hex(color_name):
        for color in haircolors:
            if color["name"] == color_name:
                return color["hex"]
        return None

    print(person)

    if person.avatar_settings.skin_color in ['PALE', 'LIGHT']:
        hair_colors = [get_hex('Auburn'), get_hex('Blonde'), get_hex('Chestnut Brown'), get_hex('Blonde')]
    elif person.avatar_settings.skin_color == 'BROWN':
        hair_colors = [get_hex('Black'), get_hex('Chestnut Brown'), get_hex('Dark Brown')]
    elif person.avatar_settings.skin_color in ['DARK_BROWN', 'BLACK']:
        hair_colors = [get_hex('Black'), get_hex('Dark Brown')]
    else:
        hair_colors = [get_hex('Auburn'), get_hex('Golden Brown'), get_hex('Red')]

    # Adjusting for older people to have a higher chance of light hair
    if person.ageYears > 50:
        if get_hex('Blonde') in hair_colors:
            hair_colors.extend([get_hex('Blonde')] * 2)    # Multiply chances of BLONDE
        if get_hex('Blonde') in hair_colors:
            hair_colors.extend([get_hex('Blonde')] * 2)    # Multiply chances of BLONDE

    return random.choice(hair_colors)


def get_hair_type(person):
    """
    Determine hair style/type based on sex and age.

    Args:
        person: A personClass instance with sex and ageYears attributes

    Returns:
        str: Hair type identifier (e.g., 'shortFlat', 'curly', 'NONE')

    Notes:
        - Infants (<1 year) have no hair
        - Older males (>50 years) have higher probability of balding
        - Different hair style options for male vs female characters
    """
    hair_types = ['NONE']
    if person.ageYears < 1:
        hair_type = 'NONE'
    elif person.ageYears > 50 and person.sex == "Male":
        hair_types = ['NONE','sides']
    else:
        if person.sex == "Male":
            hair_types = [ "dreads", "dreads01", "dreads02", "fro", "shaggy", "shaggyMullet", "shortFlat", "theCaesar", "theCaesarAndSidePart", "shavedSides", "sides", "shortWaved", "frizzle", "shortRound", "shortCurly"]
        else:
            hair_types = [ "bigHair", "bob", "bun", "curly", "fro", "curvy", "froBand", "longButNotTooLong", "miaWallace", "straight01", "straight02", "straightAndStrand" ]
    hair_type = random.choice(hair_types)

    return hair_type


def get_facial_hair(person):
    """
    Determine facial hair style based on sex and age.

    Args:
        person: A personClass instance with sex and ageYears attributes

    Returns:
        str: Facial hair type identifier or 'NONE'

    Notes:
        - Only males between 18-50 years can have facial hair
        - Options include light beard, medium beard, or magnum moustache
    """
    if person.sex == "Male" and person.ageYears >= 18 and person.ageYears <= 50:
        facial_hair = random.choice(['beardLight', 'beardMedium', 'moustacheMagnum'])
    else:
        facial_hair = 'NONE'

    return facial_hair


def get_accessory(person):
    """
    Determine if character wears glasses/accessories based on age.

    Args:
        person: A personClass instance with ageYears attribute

    Returns:
        str: Accessory type identifier (e.g., 'round', 'NONE')

    Notes:
        Age-based probabilities for wearing glasses:
        - Children (<18): 20% wear glasses
        - Young adults (18-39): 40% wear glasses/contacts
        - Older adults (40+): 60% wear glasses/contacts
    """
    accessories = ['NONE', 'round', 'round', 'round']

    # Probabilities based on age
    if person.ageYears < 18:
        # Assuming 20% of children wear glasses
        probs = [0.80, 0.067, 0.067, 0.067]
    elif 18 <= person.ageYears <= 39:
        # Assuming 40% of young adults wear glasses, considering contact lens usage
        probs = [0.60, 0.133, 0.133, 0.133]
    else:
        # Assuming 60% of older adults wear glasses, considering both glasses and contact lens usage
        probs = [0.40, 0.2, 0.2, 0.2]

    accessory = random.choices(accessories, weights=probs, k=1)[0]

    return accessory


def get_skin_color():
    """
    Generate skin color based on US demographic race distribution.

    Returns:
        str: Hex color code for skin tone

    Notes:
        - Uses US Census race probability distribution
        - Race categories: White, Black/African American, American Indian/Alaska Native,
          Asian, Native Hawaiian/Pacific Islander, Some Other Race
        - Returns hex value from predefined skin tone palette
        - Probabilities are normalized to ensure valid distribution
    """
    # Skin color dictionary
    skin_color_dict = {
        'PALE': 'ffdbb4',
        'LIGHT': 'edb98a',
        'BROWN': 'd08b5b',
        'DARK_BROWN': 'ae5d29',
        'BLACK': '614335',
        'ASIAN': 'ffdbb4',
        'PACIFIC_ISLANDER': 'ffdbb4'
    }

    races = ['White', 'Black or African American', 'American Indian or Alaska Native', 'Asian', 'Native Hawaiian or Other Pacific Islander', 'Some Other Race']
    race_probs = [0.603, 0.134, 0.009, 0.062, 0.002, 0.191]

    total_race_probs = sum(race_probs)
    race_probs = [x/total_race_probs for x in race_probs]  # Normalize

    # Updated skin colors to represent the names instead of hex values
    skin_colors = [['PALE', 'LIGHT'], ['BROWN', 'DARK_BROWN', 'BLACK'], ['PALE', 'LIGHT', 'BROWN'], ['PALE', 'LIGHT', 'BROWN'], ['PALE', 'LIGHT'], ['PALE', 'LIGHT', 'BROWN', 'DARK_BROWN', 'BLACK']]
    skin_color_probs = [[0.6, 0.4], [0.2, 0.4, 0.4], [0.4, 0.4, 0.2], [0.4, 0.4, 0.2], [0.6, 0.4], [0.3, 0.3, 0.2, 0.1, 0.1]]

    # Normalize skin color probabilities
    for i in range(len(skin_color_probs)):
        total = sum(skin_color_probs[i])
        skin_color_probs[i] = [x/total for x in skin_color_probs[i]]

    # Choose a race based on the US population probabilities
    race = np.random.choice(races, p=race_probs)

    # Choose a skin color name based on the normalized skin color probabilities for the chosen race
    skin_color_name = np.random.choice(skin_colors[races.index(race)], p=skin_color_probs[races.index(race)])

    # Return the hex value for the chosen skin color name
    return skin_color_dict[skin_color_name]
