import gradio as gr
import requests
from datetime import datetime, timezone

API_URL = "https://huggingface.co/api/daily_papers"

class PaperManager:
    def __init__(self, papers_per_page=10):
        self.papers_per_page = papers_per_page
        self.current_page = 1
        self.papers = []
        self.total_pages = 1

    def fetch_papers(self):
        try:
            response = requests.get(f"{API_URL}?limit=50")
            response.raise_for_status()
            data = response.json()
            
            # Sort papers primarily by 'publishedAt' descending, then by 'upvotes' descending
            self.papers = sorted(
                data,
                key=lambda x: (
                    datetime.fromisoformat(
                        x.get('publishedAt', datetime.now(timezone.utc).isoformat()).replace('Z', '+00:00')
                    ),
                    x.get('paper', {}).get('upvotes', 0)
                ),
                reverse=True  # Ensures descending order
            )
            
            self.total_pages = (len(self.papers) + self.papers_per_page - 1) // self.papers_per_page
            self.current_page = 1
            return True
        except requests.RequestException as e:
            print(f"Error fetching papers: {e}")
            return False
        except Exception as e:
            print(f"Unexpected error: {e}")
            return False

    def format_paper(self, paper):
        title = paper.get('title', 'No title')
        paper_id = paper.get('paper', {}).get('id', '')
        url = f"https://huggingface.co/papers/{paper_id}"
        authors = ', '.join([author.get('name', '') for author in paper.get('paper', {}).get('authors', [])])
        upvotes = paper.get('paper', {}).get('upvotes', 0)
        comments = paper.get('numComments', 0)
        published_time = datetime.fromisoformat(
            paper.get('publishedAt', datetime.now(timezone.utc).isoformat()).replace('Z', '+00:00')
        )
        time_ago_days = (datetime.now(timezone.utc) - published_time).days

        return f"""
        <div class="paper-item">
            <h3><a href="{url}" target="_blank">{title}</a></h3>
            <p class="paper-meta">
                <span class="upvotes">{upvotes} ▲</span> 
                <span class="comments">{comments}💬</span>
                <span class="authors">{authors}</span>
                <span class="time-ago">{time_ago_days}d</span>
            </p>
        </div>
        """

    def render_papers(self):
        start = (self.current_page - 1) * self.papers_per_page
        end = start + self.papers_per_page
        current_papers = self.papers[start:end]
        
        if not current_papers:
            return "<div class='no-papers'>No papers available for this page.</div>"
        
        return "".join([self.format_paper(paper) for paper in current_papers])

    def next_page(self):
        if self.current_page < self.total_pages:
            self.current_page += 1
        return self.render_papers(), f"Page {self.current_page} of {self.total_pages}"

    def prev_page(self):
        if self.current_page > 1:
            self.current_page -= 1
        return self.render_papers(), f"Page {self.current_page} of {self.total_pages}"

css = """
/* Your existing CSS */
body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
    background-color: #f0f2f5;
    margin: 0;
    padding: 0;
}
.container {
    max-width: 100%;
    margin: 0 auto;
    background-color: white;
    padding: 1rem;
}
.title {
    text-align: center;
    color: #1a202c;
    font-size: 1.5rem;
    margin-bottom: 1rem;
}
.paper-list {
    max-height: 60vh;
    overflow-y: auto;
    border: 1px solid #e2e8f0;
    border-radius: 8px;
    padding: 0.5rem;
}
.paper-item {
    border-bottom: 1px solid #e2e8f0;
    padding: 0.5rem 0;
}
.paper-item:last-child {
    border-bottom: none;
}
.paper-item h3 {
    margin: 0 0 0.25rem 0;
    font-size: 1rem;
}
.paper-item a {
    color: #2b6cb0;
    text-decoration: none;
    font-weight: 600;
}
.paper-item a:hover {
    text-decoration: underline;
}
.paper-meta {
    font-size: 0.75rem;
    color: #4a5568;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}
.footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 0.5rem;
    position: relative;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* Target Gradio button elements more specifically */
#component-5, #component-7, #component-9 {
    background-color: #3498db !important;  /* Mobile-friendly blue */
    color: white !important;
    border: none !important;
    padding: 0.5rem 1rem !important;
    border-radius: 4px !important;
    cursor: pointer !important;
    transition: background-color 0.3s !important;
    font-size: 0.875rem !important;
    line-height: 1.25rem !important;
    width: auto !important;
    max-width: 100% !important;
}

#component-5:hover, #component-7:hover, #component-9:hover {
    background-color: #2980b9 !important;  /* Darker blue on hover */
}

/* Style for the refresh button */
#component-11 {
    background-color: #2ecc71 !important;  /* More visible green */
    color: white !important;
    border: none !important;
    padding: 0.5rem !important;
    border-radius: 4px !important;
    cursor: pointer !important;
    transition: background-color 0.3s !important;
    font-size: 1rem !important;
    width: auto !important;
    max-width: 100% !important;
    height: auto !important;
    line-height: 1 !important;
}

#component-11:hover {
    background-color: #27ae60 !important;  /* Darker green on hover */
}

/* Make sure the page info doesn't break the layout */
#component-8 {
    flex: 1;
    text-align: center;
    min-width: 100px;
}

.no-papers {
    text-align: center;
    color: #718096;
    padding: 1rem;
}

/* Responsive adjustments */
@media (max-width: 640px) {
    #component-5, #component-7, #component-9, #component-11 {
        font-size: 0.75rem !important;
        padding: 0.4rem 0.8rem !important;
    }
    
    .footer {
        justify-content: center;
    }
}

@media (min-width: 640px) {
    .container {
        max-width: 640px;
        padding: 1.5rem;
    }
    .title {
        font-size: 1.75rem;
    }
    .paper-item h3 {
        font-size: 1.125rem;
    }
    .paper-meta {
        font-size: 0.875rem;
    }
}

@media (min-width: 768px) {
    .container {
        max-width: 768px;
    }
    .footer {
        position: sticky;
        bottom: 0;
        background-color: white;
    }
}
"""

paper_manager = PaperManager()

def initialize_app():
    if paper_manager.fetch_papers():
        return paper_manager.render_papers(), f"Page {paper_manager.current_page} of {paper_manager.total_pages}"
    else:
        return "<div class='no-papers'>Failed to fetch papers. Please try again later.</div>", "Error"

def refresh_papers():
    if paper_manager.fetch_papers():
        return paper_manager.render_papers(), f"Page {paper_manager.current_page} of {paper_manager.total_pages}"
    else:
        return "<div class='no-papers'>Failed to refresh papers. Please try again later.</div>", "Error"

demo = gr.Blocks(css=css)

with demo:
    with gr.Column(elem_classes=["container"]):
        gr.Markdown("# Daily Papers - Hacker News Style", elem_classes=["title"])
        refresh_button = gr.Button("↻ Refresh", variant="primary", elem_classes=["refresh-btn"])
        with gr.Row(elem_classes=["footer"]):
            prev_button = gr.Button("← Prev")
            page_info = gr.Markdown(elem_classes=["page-info"])
            next_button = gr.Button("Next →")
        
        paper_list = gr.HTML(elem_classes=["paper-list"])

    demo.load(initialize_app, outputs=[paper_list, page_info])
    refresh_button.click(refresh_papers, outputs=[paper_list, page_info])
    prev_button.click(paper_manager.prev_page, outputs=[paper_list, page_info])
    next_button.click(paper_manager.next_page, outputs=[paper_list, page_info])

demo.launch()