import asyncio
import os
import gradio as gr
from api_clients import OpenRouterClient, ElevenLabsClient
from logger import setup_logger
from config import Config
from scraper import scrape_url

logger = setup_logger("app")

# Default choices for dropdowns
default_voices = [("", "Enter API key to load voices")]
default_models = [("", "Enter API key to load models")]

class PodcasterUI:
    def __init__(self, config: Config):
        self.config = config
        self.router_client = OpenRouterClient(os.getenv('OPENROUTER_API_KEY', ''))
        self.elevenlabs_client = ElevenLabsClient(os.getenv('ELEVENLABS_API_KEY', ''))
        # Store models and voices as instance variables
        self.models = default_models
        self.voices = default_voices

    async def initialize(self):
        """Initialize API clients and fetch models/voices"""
        try:
            self.models = await self.router_client.get_models()
            # Since get_voices() might not be async, remove await
            self.voices = self.elevenlabs_client.get_voices()
            logger.info(f"Initialized with {len(self.voices)} voices and {len(self.models)} models")
        except Exception as e:
            logger.error("Failed to initialize API clients", exc_info=True)
            raise

    async def on_submit(self, content: str, model_id: str, voice_id: str, prompt: str = "") -> tuple:
        """Handle form submission with async API calls"""
        try:
            # First scrape the webpage content
            webpage_content = scrape_url(content)
            if not webpage_content:
                return "Failed to extract content from URL", None

            # Generate script using the scraped content
            script = await self.router_client.generate_script(webpage_content, prompt, model_id)
            
            # Generate audio from the script (now synchronous)
            audio = self.elevenlabs_client.generate_audio(script, voice_id)
            return script, audio
        except Exception as e:
            logger.error("Failed to generate podcast", exc_info=True)
            return str(e), None

    def create_ui(self) -> gr.Interface:
        with gr.Blocks(title='URL to Podcast Generator', theme='huggingface') as interface:
            gr.Markdown('# URL to Podcast Generator')
            gr.Markdown('Enter a URL to generate a podcast episode based on its content.')

            with gr.Row():
                with gr.Column(scale=2):
                    url_input = gr.Textbox(
                        label="Website URL",
                        placeholder="Enter the URL of the website you want to convert to a podcast"
                    )
                    
                    with gr.Row():
                        with gr.Column():
                            openrouter_model = gr.Dropdown(
                                label='AI Model',
                                choices=self.models,  # Each choice now has same id/display value
                                value=self.models[0][0] if len(self.models) > 1 else None,
                            )
                            
                        with gr.Column():
                            voice_model = gr.Dropdown(
                                label='Voice',
                                choices=[(id, name) for id, name in self.voices],
                                value=self.voices[0][0] if len(self.voices) > 1 else None,
                            )
                    
                    prompt_input = gr.Textbox(
                        label="Custom Prompt",
                        placeholder="Enter a custom prompt to guide the podcast generation (optional)",
                        lines=3
                    )
                    
                    submit_btn = gr.Button('Generate Podcast', variant='primary')

                with gr.Column(scale=1):
                    script_output = gr.Textbox(label="Generated Script", interactive=False)
                    audio_output = gr.Audio(label="Generated Podcast")
                    status = gr.Textbox(label='Status', interactive=False)

            submit_btn.click(
                fn=self.on_submit,
                inputs=[url_input, openrouter_model, voice_model, prompt_input],
                outputs=[script_output, audio_output]
            )

        return interface

def main():
    config = Config()
    app = PodcasterUI(config)
    
    # Initialize before creating UI
    loop = asyncio.get_event_loop()
    loop.run_until_complete(app.initialize())
    
    # Create UI with populated data
    interface = app.create_ui()
    interface.launch(
        server_name="0.0.0.0",
        server_port=7860,
        share=True
    )

if __name__ == "__main__":
    main()