import discord
import datetime

from discord.ext import commands, tasks
from utils.sql_commands import DatabaseManager
from dotenv import dotenv_values




def check(author):
    def inner_check(message):
        return message.author == author

    return inner_check


class Birthday(commands.Cog):
    def __init__(self, client):
        self.client = client        
        self.db = DatabaseManager("")
        self.birthday_checks = {}

    async def cog_load(self):
        self.check_birthdays.start()

    async def cog_unload(self):
        self.check_birthdays.cancel()

    @tasks.loop(seconds=60*60*24) # daily
    async def check_birthdays(self):
        today = datetime.date.today()
        for guild in self.client.guilds:
            guild_id = guild.id
            for member in guild.members:
                user_id = member.id
                user_data = self.db.fetch_one("SELECT * FROM users WHERE ID = %s", (user_id,))
                if user_data is None or user_data.get("birthday") is None:
                    continue

                birthday = datetime.datetime.strptime(user_data.get("birthday"), "%Y-%m-%d").date()
                if birthday.month == today.month and birthday.day == today.day:
                    # send birthday message
                    try:
                        channel = guild.text_channels[0]
                        await channel.send(f"Happy birthday, {member.mention}! 🎉")
                    except discord.Forbidden:
                        continue
                    except discord.HTTPException:
                        continue
                    # give birthday reward
                    reward = self.db.fetch_one("SELECT * FROM rewards WHERE type = 'birthday'")
                    if reward is not None:
                        try:
                            await self.client.get_cog("Economy").add_points(user_id, guild_id, reward.get("amount"), "birthday reward")
                        except Exception as e:
                            print(f"Error giving birthday reward: {e}")
                    # give birthday star role
                    role = discord.utils.get(guild.roles, name="Birthday Star")
                    if role is not None:
                        try:
                            await member.add_roles(role)
                        except discord.Forbidden:
                            continue
                        except discord.HTTPException:
                            continue
                    # log birthday reward
                    try:
                        self.db.execute_query("INSERT INTO logs (guild_id, user_id, type, message) VALUES (%s, %s, 'birthday_reward', 'claimed birthday reward')", (guild_id, user_id))
                    except Exception as e:
                        print(f"Error logging birthday reward: {e}")

    @check_birthdays.before_loop
    async def before_check_birthdays(self):
        await self.client.wait_until_ready()

    @commands.command(name="setbirthday", aliases=["sb"])
    async def setbirthday(self, ctx, month: int, day: int):
        if month < 1 or month > 12 or day < 1 or day > 31:
            return await ctx.send("Invalid date")

        user_id = ctx.author.id
        user_data = self.db.fetch_one("SELECT * FROM users WHERE ID = %s", (user_id,))

        if user_data is not None and user_data.get("birthday") is not None:
            return await ctx.send("You've already set your birthday")

        self.db.execute_query("UPDATE users SET birthday = %s WHERE ID = %s", (f"{datetime.date.today().year}-{month}-{day}", user_id))
        await ctx.send("Your birthday has been set")

    @commands.command(name="claimbirthday", aliases=["cb"])
    async def claimbirthday(self, ctx):
        user_id = ctx.author.id
        user_data = self.db.fetch_one("SELECT * FROM users WHERE ID = %s", (user_id,))

        if user_data is None or user_data.get("birthday") is None:
            return await ctx.send("You haven't set your birthday")

        today = datetime.date.today()
        birthday = datetime.datetime.strptime(user_data.get("birthday"), "%Y-%m-%d").date()
        if birthday.month != today.month or birthday.day != today.day:
            return await ctx.send("It's not your birthday")

        reward = self.db.fetch_one("SELECT * FROM rewards WHERE type = 'birthday'")
        if reward is None:
            return await ctx.send("No birthday reward set")

        await self.client.get_cog("Economy").add_points(user_id, ctx.guild.id, reward.get("amount"), "birthday reward")
        await ctx.send("You've claimed your birthday reward")

    @commands.command(name="listbirthdays", aliases=["lb"])
    async def listbirthdays(self, ctx):
        today = datetime.date.today()
        birthdays = []
        for guild in self.client.guilds:
            for member in guild.members:
                user_id = member.id
                user_data = self.db.fetch_one("SELECT * FROM users WHERE ID = %s", (user_id,))
                if user_data is None or user_data.get("birthday") is None:
                    continue

                birthday = datetime.datetime.strptime(user_data.get("birthday"), "%Y-%m-%d").date()
                if birthday.month == today.month and birthday.day == today.day:
                    birthdays.append(member.mention)

        if not birthdays:
            await ctx.send("No birthdays today")
        else:
            await ctx.send(f"Happy birthday to {', '.join(birthdays)}! 🎉")
