import discord
from discord import app_commands
from discord.ext import commands
from datetime import timedelta


def timeout_command():
    DURATION_CHOICES = [
        app_commands.Choice(name="60 secs", value="60s"),
        app_commands.Choice(name="5 mins", value="5m"),
        app_commands.Choice(name="10 mins", value="10m"),
        app_commands.Choice(name="1 hour", value="1h"),
        app_commands.Choice(name="1 day", value="1d"),
        app_commands.Choice(name="1 week", value="1w"),
    ]

    @commands.hybrid_command(
        name="timeout",
        description="Timeout a user for a specified duration.",
    )
    @app_commands.describe(
        user="The user that should be timed out.",
        duration="Duration",
        reason="The reason why the user should be timed out.",
    )
    @app_commands.choices(duration=DURATION_CHOICES)
    async def timeout(
        self,
        context,
        user: discord.User,
        duration: str,
        *,
        reason: str = "Not specified",
    ):
        try:
            member = context.guild.get_member(user.id)
            if not member:
                try:
                    member = await context.guild.fetch_member(user.id)
                except discord.NotFound:
                    embed = discord.Embed(
                        title="Error!",
                        description="This user is not in the server.",
                        color=0xE02B2B,
                    ).set_author(
                        name="Moderation",
                        icon_url="https://yes.nighty.works/raw/CPKHQd.png",
                    )
                    await context.send(embed=embed, ephemeral=True)
                    return

            if (
                not context.author.guild_permissions.moderate_members
                and context.author != context.guild.owner
            ):
                embed = discord.Embed(
                    title="Missing Permissions!",
                    description="You don't have the `Timeout Members` permission to use this command.",
                    color=0xE02B2B,
                ).set_author(
                    name="Moderation",
                    icon_url="https://yes.nighty.works/raw/CPKHQd.png",
                )
                await context.send(embed=embed, ephemeral=True)
                return

            if member and member.top_role >= context.guild.me.top_role:
                embed = discord.Embed(
                    title="Cannot Timeout User",
                    description="This user has a higher or equal role to me. Make sure my role is above theirs.",
                    color=0xE02B2B,
                ).set_author(
                    name="Moderation",
                    icon_url="https://yes.nighty.works/raw/CPKHQd.png",
                )
                await context.send(embed=embed, ephemeral=True)
                return

            if member and context.author != context.guild.owner:
                if member.top_role >= context.author.top_role:
                    embed = discord.Embed(
                        title="Cannot Timeout User",
                        description="You cannot timeout this user as they have a higher or equal role to you.",
                        color=0xE02B2B,
                    ).set_author(
                        name="Moderation",
                        icon_url="https://yes.nighty.works/raw/CPKHQd.png",
                    )
                    await context.send(embed=embed, ephemeral=True)
                    return

            seconds = _parse_duration_to_seconds(duration)
            if seconds is None or seconds <= 0:
                embed = discord.Embed(
                    title="Invalid Duration",
                    description="Choose one of: 60 secs, 5 mins, 10 mins, 1 hour, 1 day, 1 week.",
                    color=0xE02B2B,
                ).set_author(
                    name="Moderation",
                    icon_url="https://yes.nighty.works/raw/CPKHQd.png",
                )
                await context.send(embed=embed, ephemeral=True)
                return

            max_seconds = 28 * 24 * 60 * 60
            seconds = min(seconds, max_seconds)

            try:
                timeout_delta = timedelta(seconds=seconds)
                await member.timeout(timeout_delta, reason=reason)

                embed = discord.Embed(
                    title="Timeout",
                    description=f"**{user}** was timed out by **{context.author}**!",
                    color=0x7289DA,
                ).set_author(
                    name="Moderation",
                    icon_url="https://yes.nighty.works/raw/CPKHQd.png",
                )
                embed.add_field(name="Reason:", value=reason)
                embed.add_field(
                    name="Duration:", value=_format_duration(duration), inline=False
                )
                await context.send(embed=embed)

            except discord.Forbidden:
                embed = discord.Embed(
                    title="Error!",
                    description="I don't have permission to timeout this user. Make sure my role is above theirs.",
                    color=0xE02B2B,
                ).set_author(
                    name="Moderation",
                    icon_url="https://yes.nighty.works/raw/CPKHQd.png",
                )
                await context.send(embed=embed, ephemeral=True)
            except discord.HTTPException as e:
                embed = discord.Embed(
                    title="Error!",
                    description=f"Discord API error: {str(e)}",
                    color=0xE02B2B,
                ).set_author(
                    name="Moderation",
                    icon_url="https://yes.nighty.works/raw/CPKHQd.png",
                )
                await context.send(embed=embed, ephemeral=True)
            except Exception as e:
                embed = discord.Embed(
                    title="Debug Error!",
                    description=f"Error type: {type(e).__name__}\nError message: {str(e)}",
                    color=0xE02B2B,
                ).set_author(
                    name="Moderation",
                    icon_url="https://yes.nighty.works/raw/CPKHQd.png",
                )
                await context.send(embed=embed, ephemeral=True)

        except Exception:
            embed = discord.Embed(
                title="Error!",
                description="An unexpected error occurred.",
                color=0xE02B2B,
            ).set_author(
                name="Moderation", icon_url="https://yes.nighty.works/raw/CPKHQd.png"
            )
            await context.send(embed=embed, ephemeral=True)

    @timeout.autocomplete("duration")
    async def duration_autocomplete(interaction: discord.Interaction, current: str):
        query = (current or "").lower()
        filtered = [
            c
            for c in DURATION_CHOICES
            if query in c.name.lower() or query in c.value.lower()
        ]
        return filtered[:25]

    return timeout


def _parse_duration_to_seconds(duration: str):
    try:
        s = duration.strip().lower()
        if s.endswith("s"):
            return int(s[:-1])
        if s.endswith("m"):
            return int(s[:-1]) * 60
        if s.endswith("h"):
            return int(s[:-1]) * 60 * 60
        if s.endswith("d"):
            return int(s[:-1]) * 60 * 60 * 24
        if s.endswith("w"):
            return int(s[:-1]) * 60 * 60 * 24 * 7
        return int(s)
    except Exception:
        return None


def _format_duration(duration: str) -> str:
    mapping = {
        "s": "seconds",
        "m": "minutes",
        "h": "hours",
        "d": "days",
        "w": "weeks",
    }
    s = duration.strip().lower()
    for suffix, word in mapping.items():
        if s.endswith(suffix):
            try:
                value = int(s[:-1])
                return f"{value} {word}"
            except Exception:
                return duration
    try:
        value = int(s)
        return f"{value} seconds"
    except Exception:
        return duration
