import discord
from discord.ext import commands
import os
import re
import random
from datetime import datetime
import pytz
from dotenv import load_dotenv
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError

load_dotenv()

intents = discord.Intents.default()
intents.message_content = True

bot = commands.Bot(command_prefix='!', intents=intents)

# Initialize Slack client
slack_client = WebClient(token=os.getenv('SLACK_BOT_TOKEN'))
SLACK_CHANNEL = os.getenv('SLACK_CHANNEL', '#discord-bot-reports')

# Channel IDs to monitor for bug reports
MONITORED_CHANNELS = [
    1082775596767117312,  # bugs-web
    1258072243963957288,  # bugs-ios
    1314280428181520435   # bugs-android
]

# Test channel - always respond here
TEST_CHANNEL_ID = 1417577605980356792

# Bug-related keywords to detect
BUG_KEYWORDS = [ 'bug', 'error' ]

# Moderator role name
MODERATOR_ROLE = "Moderator"

@bot.event
async def on_ready():
    print(f'{bot.user} has connected to Discord!')

def detect_bug_complaint(message_content):
    """Check if message contains bug-related keywords"""
    message_lower = message_content.lower()
    return any(keyword in message_lower for keyword in BUG_KEYWORDS)

class BugReportView(discord.ui.View):
    def __init__(self, original_message):
        super().__init__(timeout=3600)  # 1 hour timeout
        self.original_message = original_message
        self.bot_response = None  # Will store the bot's response message
        self.slack_message_ts = None  # Will store Slack message timestamp for editing
        self.slack_channel_id = None  # Will store the actual channel ID used for Slack

    @discord.ui.button(label='🚨 Ping Moderator for Help', style=discord.ButtonStyle.secondary, emoji='🚨')
    async def ping_moderator(self, interaction: discord.Interaction, button: discord.ui.Button):
        # Find the moderator role
        moderator_role = discord.utils.get(interaction.guild.roles, name=MODERATOR_ROLE)

        if not moderator_role:
            await interaction.response.send_message(
                "❌ Moderator role not found. Please contact support directly.",
                ephemeral=True
            )
            return

        # Create compact moderator ping embed
        mod_embed = discord.Embed(
            description=f"🚨 User assistance requested for a potential bug report! [Jump to message]({self.original_message.jump_url})",
            color=0xff9500
        )

        # Send as a regular message to trigger notifications properly
        await interaction.response.defer()  # Acknowledge the interaction
        await interaction.channel.send(
            f"{moderator_role.mention}",
            embed=mod_embed
        )

        # Disable the button after use and update the original message
        button.disabled = True
        button.label = "✅ Moderator Notified"
        button.style = discord.ButtonStyle.success

        # Update the original bot response to show the disabled button
        if self.bot_response:
            try:
                await self.bot_response.edit(view=self)
            except Exception as e:
                print(f"Could not update original message: {e}")

        # Update Slack message to show moderator has been notified
        if self.slack_message_ts:
            await self.update_slack_message_moderator_status(True)

    async def update_slack_message_moderator_status(self, moderator_notified):
        """Update the Slack message to show moderator notification status"""
        try:
            # Get channel name mapping
            channel_names = {
                1082775596767117312: "bugs-web",
                1258072243963957288: "bugs-ios",
                1314280428181520435: "bugs-android",
                1417577605980356792: "test-channel"
            }

            channel_name = channel_names.get(self.original_message.channel.id, f"#{self.original_message.channel.name}")

            # Create updated Slack message with moderator status
            slack_message = {
                "text": "🐛 New Bug Report Detected in Discord",
                "blocks": [
                    {
                        "type": "header",
                        "text": {
                            "type": "plain_text",
                            "text": "🐛 Bug Report Detected"
                        }
                    },
                    {
                        "type": "section",
                        "fields": [
                            {
                                "type": "mrkdwn",
                                "text": f"*User:* {self.original_message.author.display_name} (@{self.original_message.author.name})"
                            },
                            {
                                "type": "mrkdwn",
                                "text": f"*Channel:* {channel_name}"
                            },
                            {
                                "type": "mrkdwn",
                                "text": f"*Server:* {self.original_message.guild.name}"
                            },
                            {
                                "type": "mrkdwn",
                                "text": f"*Time:* {self.original_message.created_at.replace(tzinfo=pytz.UTC).astimezone(pytz.timezone('US/Eastern')).strftime('%Y-%m-%d %H:%M:%S EST')}"
                            },
                            {
                                "type": "mrkdwn",
                                "text": f"*Moderator Notified?* {'✅ Yes' if moderator_notified else '❌ No'}"
                            }
                        ]
                    },
                    {
                        "type": "section",
                        "text": {
                            "type": "mrkdwn",
                            "text": f"*Message:*\n```{self.original_message.content}```"
                        }
                    },
                    {
                        "type": "section",
                        "text": {
                            "type": "mrkdwn",
                            "text": f"*Discord Link:* <https://discord.com/channels/{self.original_message.guild.id}/{self.original_message.channel.id}/{self.original_message.id}|Jump to message>"
                        }
                    }
                ]
            }

            # Update the Slack message using the stored channel ID
            slack_client.chat_update(
                channel=self.slack_channel_id or SLACK_CHANNEL,
                ts=self.slack_message_ts,
                **slack_message
            )

        except Exception as e:
            print(f"Error updating Slack message: {e}")

async def send_slack_notification(message, view):
    """Send bug report notification to Slack"""
    try:
        # Get channel name mapping
        channel_names = {
            1082775596767117312: "bugs-web",
            1258072243963957288: "bugs-ios",
            1314280428181520435: "bugs-android",
            1417577605980356792: "test-channel"
        }

        channel_name = channel_names.get(message.channel.id, f"#{message.channel.name}")

        # Create Slack message
        slack_message = {
            "text": "🐛 New Bug Report Detected in Discord",
            "blocks": [
                {
                    "type": "header",
                    "text": {
                        "type": "plain_text",
                        "text": "🐛 Bug Report Detected"
                    }
                },
                {
                    "type": "section",
                    "fields": [
                        {
                            "type": "mrkdwn",
                            "text": f"*User:* {message.author.display_name} (@{message.author.name})"
                        },
                        {
                            "type": "mrkdwn",
                            "text": f"*Channel:* {channel_name}"
                        },
                        {
                            "type": "mrkdwn",
                            "text": f"*Server:* {message.guild.name}"
                        },
                        {
                            "type": "mrkdwn",
                            "text": f"*Time:* {message.created_at.replace(tzinfo=pytz.UTC).astimezone(pytz.timezone('US/Eastern')).strftime('%Y-%m-%d %H:%M:%S EST')}"
                        },
                        {
                            "type": "mrkdwn",
                            "text": f"*Moderator Notified?* ❌ No"
                        }
                    ]
                },
                {
                    "type": "section",
                    "text": {
                        "type": "mrkdwn",
                        "text": f"*Message:*\n```{message.content}```"
                    }
                },
                {
                    "type": "section",
                    "text": {
                        "type": "mrkdwn",
                        "text": f"*Discord Link:* <https://discord.com/channels/{message.guild.id}/{message.channel.id}/{message.id}|Jump to message>"
                    }
                }
            ]
        }

        # Send to Slack
        response = slack_client.chat_postMessage(
            channel=SLACK_CHANNEL,
            unfurl_links=False,
            unfurl_media=False,
            **slack_message
        )

        # Store the message timestamp and channel ID in the view for later updates
        view.slack_message_ts = response['ts']
        view.slack_channel_id = response['channel']

        print(f"Slack notification sent successfully: {response['ts']}")

    except SlackApiError as e:
        print(f"Error sending Slack notification: {e.response['error']}")
    except Exception as e:
        print(f"Unexpected error sending Slack notification: {e}")

@bot.event
async def on_message(message):
    # Ignore messages from bots
    if message.author.bot:
        return
    
    # Only monitor specific channels
    if message.channel.id not in MONITORED_CHANNELS and message.channel.id != TEST_CHANNEL_ID:
        return

    # Check if message contains bug complaint
    if detect_bug_complaint(message.content):
        # Always respond in test channel, otherwise 10% chance
        if message.channel.id != TEST_CHANNEL_ID and random.random() > 0.05:
            return
            
        embed = discord.Embed(
            title="🐛 Bug Report Detected",
            description="It looks like you might be experiencing a bug! Please help us improve by submitting a detailed report.\n\n**Pro tip:** If you have exact steps to replicate the issue, that will help us fix it sooner! 🚀",
            color=0xff6b6b
        )
        embed.add_field(
            name="Submit Feedback",
            value="[Click here to report the issue](https://suno.com/feedback)",
            inline=False
        )
        embed.add_field(
            name="Need Help?",
            value="Use the button below to get assistance from a moderator who can help reproduce and verify the issue.",
            inline=False
        )
        embed.set_thumbnail(url="attachment://sunoimg.png")
        embed.set_footer(text="Thank you for helping us make Suno better! 🎵")
        
        file = discord.File("sunoimg.png")
        view = BugReportView(message)
        bot_response = await message.reply(embed=embed, file=file, view=view, mention_author=True)
        view.bot_response = bot_response  # Store reference to the bot's response

        # Send notification to Slack
        await send_slack_notification(message, view)
    
    # Process commands
    await bot.process_commands(message)

if __name__ == '__main__':
    bot.run(os.getenv('DISCORD_TOKEN'))
