import aiohttp
import discord
from redbot.core import Config

#
# Misc. functions
#

def construct_embed(interaction: discord.Interaction, fields: list[discord.Embed.fields], color: str):
    embed = discord.Embed(title="Issue Request", color=color)
    for item in fields:
        title = item.label
        value = item.value
        if value is not None:
            if len(value) > 1024:
                words = value.split()
                split_value = []
                current_part = ""
                for word in words:
                    if len(current_part) + len(word) + 1 <= 1024:
                        current_part += word + " "
                    else:
                        split_value.append(current_part.strip())
                        current_part = word + " "
                if current_part:
                    split_value.append(current_part.strip())
                for i, part in enumerate(split_value):
                    embed.add_field(
                        name=title if i == 0 else "\u200b", value=part, inline=False
                    )
            else:
                embed.add_field(name=title, value=value, inline=False)
    if interaction.user.discriminator == "0":
        username = interaction.user.name
    else:
        username = f"{interaction.user.name}#{interaction.user.discriminator}"
    embed.set_footer(
        text=f"Submitted by {username} ({interaction.user.id})",
        icon_url=interaction.user.display_avatar.url,
    )
    return embed

#
# Modals for the core '/issues' command.
#

class BotBugModal(discord.ui.Modal, title="Creating issue..."):
    def __init__(self, color, cog_instance, original_interaction):
        super().__init__()
        self.color = color
        self.cog_instance = cog_instance
        self.original_interaction = original_interaction

    bug_description = discord.ui.TextInput(
        label="Describe the bug",
        placeholder="A clear and concise description of what the bug is.",
        style=discord.TextStyle.paragraph,
        required=True,
        max_length=2048
    )
    reproduction_steps = discord.ui.TextInput(
        label="To Reproduce",
        placeholder="What caused the bug?",
        style=discord.TextStyle.paragraph,
        required=True,
        max_length=2048
    )
    expected_behavior = discord.ui.TextInput(
        label="Expected Behavior",
        placeholder="A clear and concise description of what you expected to happen.",
        style=discord.TextStyle.paragraph,
        required=True,
        max_length=2048
    )
    additional_context = discord.ui.TextInput(
        label="Additional Context",
        placeholder="Add any other context about the problem here.",
        style=discord.TextStyle.paragraph,
        required=False,
        max_length=2048
    )

    async def on_submit(self, interaction: discord.Interaction):
        fields = [self.bug_description, self.reproduction_steps, self.expected_behavior, self.additional_context]
        embed = construct_embed(interaction, fields, self.color)
        embed.set_author(name="Bot Bug Report")
        await self.cog_instance.submit_issue_request(interaction=interaction, original_interaction=self.original_interaction, embed=embed)

class CogBugModal(discord.ui.Modal, title="Creating issue..."):
    def __init__(self, color, cog_instance, original_interaction):
        super().__init__()
        self.color = color
        self.cog_instance = cog_instance
        self.original_interaction = original_interaction

    cog_name = discord.ui.TextInput(
        label="What cog is causing this error?",
        placeholder="If unsure, put \"GalaxyCogs\".",
        style=discord.TextStyle.short,
        required=True,
        max_length=50
    )
    bug_description = discord.ui.TextInput(
        label="Describe the bug",
        placeholder="A clear and concise description of what the bug is.",
        style=discord.TextStyle.paragraph,
        required=True,
        max_length=2048
    )
    reproduction_steps = discord.ui.TextInput(
        label="To Reproduce",
        placeholder="What caused the bug?",
        style=discord.TextStyle.paragraph,
        required=True,
        max_length=2048
    )
    expected_behavior = discord.ui.TextInput(
        label="Expected Behavior",
        placeholder="A clear and concise description of what you expected to happen.",
        style=discord.TextStyle.paragraph,
        required=True,
        max_length=2048
    )
    additional_context = discord.ui.TextInput(
        label="Additional Context",
        placeholder="Add any other context about the problem here.",
        style=discord.TextStyle.paragraph,
        required=False,
        max_length=2048
    )

    async def on_submit(self, interaction: discord.Interaction):
        fields = [self.cog_name, self.bug_description, self.reproduction_steps, self.expected_behavior, self.additional_context]
        embed = construct_embed(interaction, fields, self.color)
        embed.set_author(name="Cog Bug Report")
        await self.cog_instance.submit_issue_request(interaction=interaction, original_interaction=self.original_interaction, embed=embed)

class BotSuggestionModal(discord.ui.Modal, title="Creating issue..."):
    def __init__(self, color, cog_instance, original_interaction):
        super().__init__()
        self.color = color
        self.cog_instance = cog_instance
        self.original_interaction = original_interaction

    suggestion_description = discord.ui.TextInput(
        label="Describe your suggestion.",
        placeholder="A clear and concise description of what your suggestion is.",
        style=discord.TextStyle.paragraph,
        required=True,
        max_length=2048
    )
    alternatives = discord.ui.TextInput(
        label="Describe alternatives you've considered.",
        placeholder="A clear and concise description of any alternative solutions or features you've cnosidered.",
        style=discord.TextStyle.paragraph,
        required=True,
        max_length=2048
    )
    additional_context = discord.ui.TextInput(
        label="Additional Context",
        placeholder="Add any other context about your suggestion here.",
        style=discord.TextStyle.paragraph,
        required=False,
        max_length=2048
    )

    async def on_submit(self, interaction: discord.Interaction):
        fields = [self.suggestion_description, self.alternatives, self.additional_context]
        embed = construct_embed(interaction, fields, self.color)
        embed.set_author(name="Cog Suggestion")
        await self.cog_instance.submit_issue_request(interaction=interaction, original_interaction=self.original_interaction, embed=embed)

class CogSuggestionModal(discord.ui.Modal, title="Creating issue..."):
    def __init__(self, color, cog_instance, original_interaction):
        super().__init__()
        self.color = color
        self.cog_instance = cog_instance
        self.original_interaction = original_interaction

    cog_name = discord.ui.TextInput(
        label="What cog is your suggestion for?",
        placeholder="If unsure, put \"GalaxyCogs\".",
        style=discord.TextStyle.short,
        required=True,
        max_length=50
    )
    suggestion_description = discord.ui.TextInput(
        label="Describe your suggestion.",
        placeholder="A clear and concise description of what your suggestion is.",
        style=discord.TextStyle.paragraph,
        required=True,
        max_length=2048
    )
    alternatives = discord.ui.TextInput(
        label="Describe alternatives you've considered.",
        placeholder="A clear and concise description of any alternative solutions or features you've cnosidered.",
        style=discord.TextStyle.paragraph,
        required=True,
        max_length=2048
    )
    additional_context = discord.ui.TextInput(
        label="Additional Context",
        placeholder="Add any other context about your suggestion here.",
        style=discord.TextStyle.paragraph,
        required=False,
        max_length=2048
    )

    async def on_submit(self, interaction: discord.Interaction):
        fields = [self.cog_name, self.suggestion_description, self.alternatives, self.additional_context]
        embed = construct_embed(interaction, fields, self.color)
        embed.set_author(name="Cog Suggestion")
        await self.cog_instance.submit_issue_request(interaction=interaction, original_interaction=self.original_interaction, embed=embed)

#
# Response modal
#

class IssueResponseModal(discord.ui.Modal, title="Sending response message..."):
    def __init__(self, channel, message_id, user, approved):
        super().__init__()
        self.channel = channel
        self.message_id = message_id
        self.user = user
        self.approved = approved
        self.config = Config.get_conf(None, cog_name="Issues", identifier=4285273314713)

    issue_title_input = discord.ui.TextInput(
        label="Title",
        placeholder="Only use this if you're accepting the issue request.",
        style=discord.TextStyle.short,
        required=False,
        max_length=200,
    )
    response = discord.ui.TextInput(
        label="Response",
        placeholder="",
        style=discord.TextStyle.paragraph,
        required=False,
        max_length=1024,
    )

    async def on_submit(self, interaction: discord.Interaction):
        message: discord.Message = await self.channel.fetch_message(self.message_id)
        embed = message.embeds[0]
        field_values = []
        field_names = []

        if self.approved:
            embed.color = 1226519
            embed.title = "Issue Request Approved"
            status = "accepted"
        else:
            embed.color = 15671552
            embed.title = "Issue Request Denied"
            status = "denied"
            await interaction.response.send_message(content=f"Issue request {status}.", ephemeral=True)

        if self.response.value != "":
            embed.add_field(
                name=f"Response from {interaction.user.name}",
                value=self.response.value,
                inline=False,
            )

        if self.approved:
            for field in embed.fields:
                field_names.append(f"**{field.name}**")
                field_values.append(field.value)

            if self.issue_title_input.value != "":
                _issue_title = self.issue_title_input.value
            else:
                _issue_title = "Automatically generated issue"

            if embed.author.name == "Bot Bug Report":
                issue_title = f"[BOT BUG] {_issue_title}"
                # desired_labels = ["bot", "bug"]
            elif embed.author.name == "Bot Suggestion":
                issue_title = f"[BOT SUGGESTION] {_issue_title}"
                # desired_labels = ["bot", "enhancement"]
            elif embed.author.name == "Cog Bug Report":
                issue_title = f"[{field_values[0]}] {_issue_title}"
                # desired_labels = ["cog", "bug"]
            elif embed.author.name == "Cog Suggestion":
                issue_title = f"[{field_values[0]}] {_issue_title}"
                # desired_labels = ["cog", "enhancement"]

            headers = {
                "Authorization": f"Bearer {await self.config.gitea_token()}",
                "Accept": "application/json",
            }

            url = f"{await self.config.gitea_root_url()}/api/v1/repos/{await self.config.gitea_repository_owner()}/{await self.config.gitea_repository()}/issues"

            issue_body = "\n".join(
                [f"{name}\n{value}" for name, value in zip(field_names, field_values)]
            )

            # async def fetch_labels():
            #     async with aiohttp.ClientSession(headers=headers) as session:
            #         async with session.post(url=f"{await self.config.gitea_root_url()}/api/v1/repos/{await self.config.gitea_repository_owner()}/{await self.config.gitea_repository()}/labels") as response:
            #             label_list = []
            #             for label in response.json():
            #                 if label["name"] in desired_labels:
            #                     label_list.append(label["id"])
            #             if label_list is None:
            #                 print("Error! Labels are not properly configured on the target repository.")
            #             return await label_list

            issue_labels = None

            if issue_labels is None:
                issue_data = {"title": issue_title, "body": issue_body}
            else:
                issue_data = {"title": issue_title, "body": issue_body, "labels": issue_labels}

            async def create_issue():
                async with aiohttp.ClientSession(headers=headers) as session:
                    async with session.post(url, json=issue_data) as response:
                        return await response.json(), response.status

            response_json, status_code = await create_issue()
            if status_code == 201:
                await interaction.response.send_message(
                    content=f"Issue request {status}.\n[Issue successfully created.]({response_json.get('html_url')})",
                    ephemeral=True,
                )
                embed.url = response_json.get("html_url")

        await message.edit(embed=embed, view=None)
        await self.user.send(embed=embed)

#
# Configuration modal
#

class IssuesConfigurationModal(discord.ui.Modal, title="Modifying configuration..."):
    def __init__(self, config, ctx):
        super().__init__()
        self.config = config
        self.ctx = ctx

    gitea_root_url = discord.ui.TextInput(
        label="Gitea Root URL",
        placeholder="https://try.gitea.io",
        style=discord.TextStyle.short,
        required=False,
        max_length=200
    )
    gitea_repository_owner = discord.ui.TextInput(
        label="Gitea Repository Owner",
        placeholder="foo",
        style=discord.TextStyle.short,
        required=False,
        max_length=200
    )
    gitea_repository = discord.ui.TextInput(
        label="Gitea Repository Name",
        placeholder="bar",
        style=discord.TextStyle.short,
        required=False,
        max_length=200
    )
    gitea_token = discord.ui.TextInput(
        label="Gitea User Access Token",
        placeholder="Generate one from your user settings page.",
        style=discord.TextStyle.short,
        required=False,
        max_length=200
    )

    async def on_submit(self, interaction: discord.Interaction):
        if self.gitea_token.value != "":
            await self.config.gitea_token.set(self.gitea_token.value)
        if self.gitea_root_url.value != "":
            await self.config.gitea_root_url.set(self.gitea_root_url.value)
        if self.gitea_repository_owner.value != "":
            await self.config.gitea_repository_owner.set(self.gitea_repository_owner.value)
        if self.gitea_repository.value != "":
            await self.config.gitea_repository.set(self.gitea_repository.value)
        await interaction.response.send_message(content="Configuration changed!")
