import discord
from discord.commands import option

bot = discord.Bot(debug_guilds=[...])

COLORS = ["red", "orange", "yellow", "green", "blue", "indigo", "violet"]

LOTS_OF_COLORS = [
    "aliceblue",
    "antiquewhite",
    "aqua",
    "aquamarine",
    "azure",
    "beige",
    "bisque",
    "blueviolet",
    "brown",
    "burlywood",
    "cadetblue",
    "cornflowerblue",
    "cornsilk",
    "crimson",
    "cyan",
    "darkblue",
    "deepskyblue",
    "dimgray",
    "dimgrey",
    "dodgerblue",
    "firebrick",
    "floralwhite",
    "forestgreen",
    "fuchsia",
    "gainsboro",
    "ghostwhite",
    "gold",
    "goldenrod",
    "gray",
    "green",
    "greenyellow",
    "grey",
    "honeydew",
    "hotpink",
    "indianred",
    "indigo",
    "ivory",
    "khaki",
    "lavender",
    "lavenderblush",
    "lawngreen",
    "lightcoral",
    "maroon",
    "mediumaquamarine",
    "mediumblue",
    "mediumorchid",
    "midnightblue",
    "navajowhite",
    "navy",
    "oldlace",
    "olive",
    "olivedrab",
    "orange",
    "orangered",
    "orchid",
    "palegoldenrod",
    "palegreen",
    "plum",
    "powderblue",
    "purple",
    "red",
    "rosybrown",
    "royalblue",
    "saddlebrown",
    "sienna",
    "springgreen",
    "steelblue",
    "tan",
    "teal",
    "thistle",
    "tomato",
    "turquoise",
    "violet",
    "wheat",
    "white",
    "whitesmoke",
    "yellow",
    "yellowgreen",
]

BASIC_ALLOWED = [...]  # This would normally be a list of discord user IDs for the purpose of this example


async def color_searcher(ctx: discord.AutocompleteContext):
    """
    Returns a list of matching colors from the LOTS_OF_COLORS list.

    In this example, we've added logic to only display any results in the
    returned list if the user's ID exists in the BASIC_ALLOWED list.

    This is to demonstrate passing a callback in the discord.utils.basic_autocomplete function.
    """

    return [color for color in LOTS_OF_COLORS if ctx.interaction.user.id in BASIC_ALLOWED]


async def get_colors(ctx: discord.AutocompleteContext):
    """Returns a list of colors that begin with the characters entered so far."""
    return [color for color in COLORS if color.startswith(ctx.value.lower())]


async def get_animals(ctx: discord.AutocompleteContext):
    """Returns a list of animals that are (mostly) the color selected for the "color" option."""
    picked_color = ctx.options["color"]
    if picked_color == "red":
        return ["cardinal", "ladybug"]
    elif picked_color == "orange":
        return ["clownfish", "tiger"]
    elif picked_color == "yellow":
        return ["goldfinch", "banana slug"]
    elif picked_color == "green":
        return ["tree frog", "python"]
    elif picked_color == "blue":
        return ["blue jay", "blue whale"]
    elif picked_color == "indigo":
        return ["eastern indigo snake"]  # Needs to return an iterable even if only one item
    elif picked_color == "violet":
        return ["purple emperor butterfly", "orchid dottyback"]
    else:
        return ["rainbowfish"]


@bot.slash_command(name="ac_example")
@option("color", description="Pick a color!", autocomplete=get_colors)
@option("animal", description="Pick an animal!", autocomplete=get_animals)
async def autocomplete_example(
    ctx: discord.ApplicationContext,
    color: str,
    animal: str,
):
    """
    Demonstrates using ctx.options to create options
    that are dependent on the values of other options.

    For the `color` option, a callback is passed, where additional
    logic can be added to determine which values are returned.

    For the `animal` option, the callback uses the input
    from the color option to return an iterable of animals
    """

    await ctx.respond(f"You picked {color} for the color, which allowed you to choose {animal} for the animal.")


@bot.slash_command(name="ac_basic_example")
@option(
    "color",
    description="Pick a color from this big list!",
    autocomplete=discord.utils.basic_autocomplete(color_searcher),
    # Demonstrates passing a callback to discord.utils.basic_autocomplete
)
@option(
    "animal",
    description="Pick an animal from this small list",
    autocomplete=discord.utils.basic_autocomplete(["snail", "python", "cricket", "orca"]),
    # Demonstrates passing a static iterable discord.utils.basic_autocomplete
)
async def autocomplete_basic_example(
    ctx: discord.ApplicationContext,
    color: str,
    animal: str,
):
    """
    This demonstrates using the discord.utils.basic_autocomplete helper function.

    For the `color` option, a callback is passed, where additional
    logic can be added to determine which values are returned.

    For the `animal` option, a static iterable is passed.

    While a small amount of values for `animal` are used in this example,
    iterables of any length can be passed to discord.utils.basic_autocomplete

    Note that the basic_autocomplete function itself will still only return a maximum of 25 items.
    """

    await ctx.respond(f"You picked {color} as your color, and {animal} as your animal!")


bot.run("TOKEN")

[((4, 6, 4, 37), 'discord.Bot', 'discord.Bot', (), '', False, 'import discord\n'), ((132, 1, 132, 70), 'discord.commands.option', 'option', (), '', False, 'from discord.commands import option\n'), ((133, 1, 133, 74), 'discord.commands.option', 'option', (), '', False, 'from discord.commands import option\n'), ((157, 17, 157, 65), 'discord.utils.basic_autocomplete', 'discord.utils.basic_autocomplete', ({(157, 50, 157, 64): 'color_searcher'}, {}), '(color_searcher)', False, 'import discord\n'), ((163, 17, 163, 89), 'discord.utils.basic_autocomplete', 'discord.utils.basic_autocomplete', ({(163, 50, 163, 88): "['snail', 'python', 'cricket', 'orca']"}, {}), "(['snail', 'python', 'cricket', 'orca'])", False, 'import discord\n')]