import os
import requests
import discord
from discord.ext import commands
from discord import app_commands
from dotenv import load_dotenv

load_dotenv()
TOKEN = os.getenv("DISCORD_TOKEN")
JELLYFIN_URL = os.getenv("JELLYFIN_URL")
JELLYFIN_API_KEY = os.getenv("JELLYFIN_API_KEY")

headers= {
    "X-Emby-Token": JELLYFIN_API_KEY
}

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

class JellyfinBot(commands.Bot):
    def __init__(self):
        super().__init__(command_prefix="/", intents=intents)

    async def setup_hook(self):
        await self.tree.sync()

bot = JellyfinBot()

@bot.event
async def on_ready():
    print(f"🪼 Logged in as {bot.user}")

@bot.tree.command(name="play", description="Play a song from Jellyfin")
@app_commands.describe(song="Song title to play")
async def play(interaction: discord.Interaction, song: str):
    await interaction.response.defer(ephemeral=False)

    if not interaction.user.voice:
        await interaction.response.send_message("You must be in a voice channel.")
        return

    url = f"{JELLYFIN_URL}/Items"
    params = {
        "searchTerm": song,
        "Recursive": True,
        "IncludeItemTypes": "Audio",
        "Limit": 5
    }

    try: 
        response = requests.get(url, headers=headers, params=params)
        response.raise_for_status()
        data = response.json().get("Items", [])

        if not data:
            await interaction.followup.send(f"❌ No song found matching `{song}`.")
            return
        
        print(f"Found {len(data)} items matching `{song}`.")
        item = data[0]
        item_id = item.get("Id")
        stream_url = f"{JELLYFIN_URL}/Audio/{item_id}/stream?static=True"

        print(f"Stream URL: {stream_url}")
        channel = interaction.user.voice.channel
        voice_client = interaction.guild.voice_client
        if voice_client is None:
            voice_client = await channel.connect()
        elif voice_client.channel != channel:
            await voice_client.move_to(channel)
            voice_client = await channel.connect()
        
        if voice_client.is_playing():
            voice_client.stop()
        
        headers_str = f"-headers \"X-Emby-Token: {JELLYFIN_API_KEY}\""
        source = discord.FFmpegPCMAudio(stream_url, before_options=f'{headers_str} -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', options="-vn")
        voice_client.play(source, after=lambda e: print(f"Finished playing: {e}"))
        await interaction.followup.send(f"🎶 Now playing: **{item.get('Name')}** by *{item.get('AlbumArtist', ['Unknown Artist'])}*")
    
    except requests.RequestException as e:
        await interaction.followup.send("⚠️ Failed to contact Jellyfin server.")
        print(f"Error: {e}")




@bot.tree.command(name="search", description="Search for a song on Jellyfin")
@app_commands.describe(title="Song title to search for")
async def search(interaction: discord.Interaction, title: str):
    await interaction.response.defer(ephemeral=False)
    url = f"{JELLYFIN_URL}/Items"
    params = {
        "searchTerm": title,
        "Recursive": True,
        "IncludeItemTypes": "Audio",
        "Limit": 5
    }
    try:
        response = requests.get(url, headers=headers, params=params)
        response.raise_for_status()
        data = response.json()
        items = data.get("Items", [])
        if not items:
            await interaction.followup.send(f"❌ No song found matching `{title}`.")
            return
        
        lines = []
        for item in items:
            title = item.get("Name")
            artist = item.get("AlbumArtist", ["Unknown Artist"])
            lines.append(f"✅ **{title}** by *{artist}*")
        await interaction.followup.send("\n".join(lines))
    
    except requests.RequestException as e:
        await interaction.followup.send("⚠️ Failed to contact Jellyfin server.")
        print(f"Error: {e}")


bot.run(TOKEN)
