from pathlib import Path
import gradio as gr
from datetime import datetime, timedelta
from fetch_paper import fetch_papers_with_daterange
from sorter import sort_by_upvotes, sort_by_comments, sort_by_date
from date import Date
import assets


def format_author(author):
    """Format author information"""
    if not author:
        return ""
    hidden_status = " (hidden)" if author.hidden else ""
    if author.name:
        return f"<a href='https://scholar.google.com/citations?view_op=search_authors&mauthors={author.name.replace(' ', '+')}' target='_blank'>{author.name}</a>"
    return "Anonymous author"


# 底部论文介绍
def format_paper_info(article):
    """Generate HTML content for paper display"""
    if not article.paper:
        return "Paper information missing"

    info = []
    # Title section
    info.append(f"<h2 class='sf-paper-title' id='sf-flag'>{article.title or 'Untitled Paper'}</h2>")
    info.append(f"<p style='text-align: center'>")
    info.append(f"<a href='https://huggingface.co/papers/{article.paper.id}' target='_blank' class='sf-button'>Hugging Face{assets.SVG_LINK}</a>")
    info.append(f"<a href='https://arxiv.org/abs/{article.paper.id}' target='_blank' class='sf-button'>arXiv{assets.SVG_LINK}</a>")
    info.append(f"<a href='https://arxiv.org/pdf/{article.paper.id}' target='_blank' class='sf-button'>PDF{assets.SVG_LINK}</a>")
    info.append(f"</p>")

    # Thumbnail
    if article.thumbnail:
        info.append(f"<p><img src='{article.thumbnail}' style='max-width: 30em; width: 100%; margin: auto'/></p>")

    # Basic information
    info.append(
        f"<p><strong>Paper ID</strong>: <a href='https://huggingface.co/papers/{article.paper.id}' target='_blank'>{article.paper.id or 'Unknown'}</a></p>")
    info.append(
        f"<p><strong>Published At</strong>: {article.paper.publishedAt.strftime('%Y-%m-%d %H:%M') if article.paper.publishedAt else 'Unknown'}</p>")

    # Author information
    authors = ", ".join([format_author(a) for a in article.paper.authors]) if article.paper.authors else "Author information not available"
    info.append(f"<p><strong>Authors</strong>: {authors}</p>")

    # Summary
    if article.paper.summary:
        summary = article.paper.summary.replace('{{', '{').replace('}}', '}').replace('\n', ' ')
        info.append(f"<h3>Summary</h3><p>{summary}</p>")

    # Discussion information
    info.append(f"<p><strong>Upvotes</strong>: {article.paper.upvotes or 0}<span style='margin-left: .5rem'></span>")
    info.append(f"<strong>Comments</strong>: {article.numComments or 0}</p>")
    if article.paper.discussionId:
        info.append(
            f"<a href='https://huggingface.co/papers/{article.paper.id}#community' target='_blank' class='sf-button'>Join Discussion{assets.SVG_LINK}</a></p>")

    # Submitter information
    if article.submittedBy:
        submitter = article.submittedBy
        info.append(f"<hr><p><strong>Submitter</strong>: ")
        avatar_url = submitter.avatarUrl if submitter.avatarUrl.startswith("http") else f"https://huggingface.co{submitter.avatarUrl}"
        profile_url = f"https://huggingface.co/{submitter.name}"
        info.append(
            f"<span><img src='{avatar_url}' class='sf-author' /></span>{submitter.fullname}(<a href='{profile_url}' target='_blank'>@{submitter.name}</a>)  ")
        info.append(f"Followers: {submitter.followerCount or 0}</p>")

    return "".join(info)


def generate_table_html(papers):
    """Generate table HTML with clickable titles and an extra column for arXiv abs link"""
    html = ['<table class="paper-table"><thead><tr>'
            '<th>Title</th>'
            '<th>👍 Upvotes</th>'
            '<th>💬 Comments</th>'
            '<th>📅 Date</th>'
            # '<th>Label</th>'
            '<th></th>'
            '</tr></thead><tbody>']

    for article in papers:
        title = article.title or "Untitled"
        upvotes = article.paper.upvotes or 0
        comments = article.numComments or 0
        date = article.paper.publishedAt.strftime("%Y-%m-%d") if article.paper.publishedAt else "Unknown"
        paper_id = article.paper.id
        # label = ", ".join(article.paper.label) or ""

        # 构造 arXiv abs 链接
        arxiv_abs_link = f"https://huggingface.co/papers/{paper_id}"

        row = f"""
        <tr>
            <td><a class="paper-title" href="{arxiv_abs_link}" target="_blank">{title}{assets.SVG_LINK}</a></td>
            <td>{upvotes}</td>
            <td>{comments}</td>
            <td>{date}</td>
            
            <td><a href="javascript:void(0)" onclick="showDetail('{paper_id}')" class="sf-button" style="margin: 0">Details{assets.SVG_LINK}</a></td>
        </tr>
        """  # <td>{label}</td>
        html.append(row)

    html.append("</tbody></table>")
    return "".join(html)


def build_html(papers):
    # Convert all papers to an HTML string, each paper wrapped in a div, with the div containing the paper's information, and the div's id being the paper's id
    html = ""
    for index, article in enumerate(papers):
        article_html = format_paper_info(article)
        html += f"<div id='smartflow-paper-{article.paper.id.replace('.', '-')}' style='{'' if index == 0 else 'display: none'}'>{article_html}</div>"
    return html


def query_papers(start_date_str: str, end_date_str: str, sort_method: str):  # Added sort_method parameter
    """Handle date range query"""
    try:
        start_date = Date(start_date_str)
        end_date = Date(end_date_str)
        papers = fetch_papers_with_daterange(start_date, end_date)

        # Sort papers based on the selected sorting method
        if sort_method == "Sort by upvotes ascending":
            papers = sort_by_upvotes(papers, reverse=False)
        elif sort_method == "Sort by upvotes descending":
            papers = sort_by_upvotes(papers, reverse=True)
        elif sort_method == "Sort by comments ascending":
            papers = sort_by_comments(papers, reverse=False)
        elif sort_method == "Sort by comments descending":
            papers = sort_by_comments(papers, reverse=True)
        elif sort_method == "Sort by date ascending":
            papers = sort_by_date(papers, reverse=False)
        elif sort_method == "Sort by date descending":
            papers = sort_by_date(papers, reverse=True)
        # elif sort_method == "Sort by label":
        #     papers = sorted(papers, key=lambda x: ", ".join(x.paper.label))

        return generate_table_html(papers), build_html(papers)
    except Exception as e:
        print(f"Query error: {e}")
        return "<p>⚠️ Query failed, please check the date format (YYYY-MM-DD)</p>", "<p>⚠️ Query failed, please check the date format (YYYY-MM-DD)</p>"


# CSS 样式(可放入单独文件)
custom_css = """
.detail-area { margin-top: 20px; padding: 20px; border: 1px solid #ddd; border-radius: 5px; }
.sf-paper-title { text-align: center; }

img.sf-author {
    height: 1.3rem;
    border: 1px solid #000;
    vertical-align: middle;
    border-radius: 50%;
    display: inline;
    margin: 0 0.1rem;
}

#paper-detail-area {
  display: none;
}

#paper-detail-area:has(#sf-flag) {
  display: block;
}

#query-results-html { min-height: 100px; }
"""

# 遍历./css文件夹下的所有文件,将文件内容作为CSS样式添加到页面中
for css_file in Path("./css").glob("*.css"):
    with open(css_file, "r") as f:
        custom_css += "\n" + f.read() + "\n"

custom_js = """"""

# 遍历./css文件夹下的所有文件,将文件内容作为CSS样式添加到页面中
for js_file in Path("./js").glob("*.js"):
    with open(js_file, "r") as f:
        custom_js += "\n" + f.read() + "\n"


def create_interface():
    """Create a new interface layout"""
    with gr.Blocks(title="Hugging Face Daily Paper", css=custom_css, head=f"<script>{custom_js}</script>") as app:

        # Main interface
        gr.HTML("<div style='text-align: center'><h1>📚 Hugging Face Weekly Paper</h1></div>")
        gr.HTML("""<div style='text-align: center'>
            <span style="">
                🔗 <a href='https://larkcommunity.feishu.cn/wiki/HSSTwsq7JiDur0kJrvjcnFZfnTe'>Contribute to this project</a>
            </span>
            <span style="margin-left: 1rem">
                Sponsor: <a href='https://internlm.intern-ai.org.cn/api/document'>InternLM</a>
            </span>
            </div>""")

        # Query control area
        with gr.Row():
            with gr.Column():
                with gr.Row():
                    start_date = gr.Textbox(elem_id="start_date", label="Start Date", placeholder="YYYY-MM-DD", value=str(Date() + (-7)))
                    end_date = gr.Textbox(elem_id="end_date", label="End Date", placeholder="YYYY-MM-DD", value=str(Date()))
            with gr.Column():
                with gr.Row():
                    today_btn = gr.Button("Today")
                    last_week_btn = gr.Button("Last Week")
                    last_month_btn = gr.Button("Last Month")

                query_btn = gr.Button("🔍 Query", variant="primary", elem_id="query_button")

        with gr.Row():

            # Add sorting method selection
            sort_method = gr.Radio(
                label="Sort Method",
                choices=[
                    "Sort by upvotes descending",
                    "Sort by comments descending",
                    "Sort by date descending",
                    "Sort by upvotes ascending",
                    "Sort by comments ascending",
                    "Sort by date ascending",
                    # "Sort by label",
                ],
                value="Sort by upvotes descending",
            )

        # Results display area
        with gr.Column(visible=True):
            results_html = gr.HTML(label="Query Results", elem_id="query-results-html")

        # Paper details area
        with gr.Column(visible=True, elem_classes="detail-area", elem_id="paper-detail-area"):
            gr.Markdown("## Paper Details")
            detail_html = gr.HTML(elem_id="detail-html")

        # Event handling
        query_btn.click(
            fn=query_papers,
            inputs=[start_date, end_date, sort_method],
            outputs=[results_html, detail_html]
        )

        sort_method.change(
            fn=query_papers,
            inputs=[start_date, end_date, sort_method],
            outputs=[results_html, detail_html]
        )

        # Add button event handling
        today_btn.click(
            fn=lambda: (str(Date()), str(Date())),
            outputs=[start_date, end_date]
        ).then(
            fn=query_papers,
            inputs=[start_date, end_date, sort_method],
            outputs=[results_html, detail_html]
        )

        last_week_btn.click(
            fn=lambda: (str(Date() + (-7)), str(Date())),
            outputs=[start_date, end_date]
        ).then(
            fn=query_papers,
            inputs=[start_date, end_date, sort_method],
            outputs=[results_html, detail_html]
        )

        last_month_btn.click(
            fn=lambda: (str(Date() + (-30)), str(Date())),
            outputs=[start_date, end_date]
        ).then(
            fn=query_papers,
            inputs=[start_date, end_date, sort_method],
            outputs=[results_html, detail_html]
        )

    return app