from flask import Blueprint, render_template, make_response, request, jsonify
import datetime
import os
from functools import lru_cache
from tools import getHandshakeScript, error_response, isCLI
from curl import get_header, MAX_WIDTH
from bs4 import BeautifulSoup
import re

# Create blueprint
app = Blueprint("now", __name__, url_prefix="/")


@lru_cache(maxsize=16)
def list_page_files():
    now_pages = os.listdir("templates/now")
    now_pages = [
        page for page in now_pages if page != "template.html" and page != "old.html"
    ]
    now_pages.sort(reverse=True)
    return now_pages


@lru_cache(maxsize=16)
def list_dates():
    now_pages = list_page_files()
    now_dates = [page.split(".")[0] for page in now_pages]
    return now_dates


@lru_cache(maxsize=8)
def get_latest_date(formatted=False):
    if formatted:
        date = list_dates()[0]
        date = datetime.datetime.strptime(date, "%y_%m_%d")
        date = date.strftime("%A, %B %d, %Y")
        return date
    return list_dates()[0]


def render_latest(handshake_scripts=None):
    now_page = list_dates()[0]
    return render(now_page, handshake_scripts=handshake_scripts)


def render(date, handshake_scripts=None):
    # If the date is not available, render the latest page
    if date is None:
        return render_latest(handshake_scripts=handshake_scripts)
    # Remove .html
    date = date.removesuffix(".html")

    if date not in list_dates():
        return error_response(request)

    date_formatted = datetime.datetime.strptime(date, "%y_%m_%d")
    date_formatted = date_formatted.strftime("%A, %B %d, %Y")
    return render_template(
        f"now/{date}.html", DATE=date_formatted, handshake_scripts=handshake_scripts
    )


def render_curl(date=None):
    # If the date is not available, render the latest page
    if date is None:
        date = get_latest_date()

    # Remove .html if present
    date = date.removesuffix(".html")

    if date not in list_dates():
        return error_response(request)

    # Format the date nicely
    date_formatted = datetime.datetime.strptime(date, "%y_%m_%d")
    date_formatted = date_formatted.strftime("%A, %B %d, %Y")

    # Load HTML
    with open(f"templates/now/{date}.html", "r", encoding="utf-8") as f:
        raw_html = f.read().replace("{{ date }}", date_formatted)
    soup = BeautifulSoup(raw_html, "html.parser")

    posts = []

    # Find divs matching your pattern
    divs = soup.find_all("div", style=re.compile(r"max-width:\s*700px", re.IGNORECASE))
    if not divs:
        return error_response(request, message="No content found for CLI rendering.")

    for div in divs:
        # header could be h1/h2/h3 inside the div
        header_tag = div.find(["h1", "h2", "h3"])  # type: ignore
        # content is usually one or more <p> tags inside the div
        p_tags = div.find_all("p")  # type: ignore

        if header_tag and p_tags:
            header_text = header_tag.get_text(strip=True)  # type: ignore
            content_lines = []

            for p in p_tags:
                # Extract text
                text = p.get_text(strip=False)

                # Extract any <a> links in the paragraph
                links = [a.get("href") for a in p.find_all("a", href=True)]  # type: ignore
                # Set max width for text wrapping

                # Wrap text manually
                wrapped_lines = []
                for line in text.splitlines():
                    while len(line) > MAX_WIDTH:
                        # Find last space within max_width
                        split_at = line.rfind(" ", 0, MAX_WIDTH)
                        if split_at == -1:
                            split_at = MAX_WIDTH
                        wrapped_lines.append(line[:split_at].rstrip())
                        line = line[split_at:].lstrip()
                    wrapped_lines.append(line)
                text = "\n".join(wrapped_lines)

                if links:
                    text += "\nLinks: " + ", ".join(links)  # type: ignore

                content_lines.append(text)

            content_text = "\n\n".join(content_lines)
            posts.append({"header": header_text, "content": content_text})

    # Build final response
    response = ""
    for post in posts:
        response += f"[1m{post['header']}[0m\n\n{post['content']}\n\n"

    return render_template(
        "now.ascii", date=date_formatted, content=response, header=get_header()
    )


@app.route("/now", strict_slashes=False)
def index():
    if isCLI(request):
        return render_curl()
    return render_latest(handshake_scripts=getHandshakeScript(request.host))


@app.route("/now/<path:path>")
def path(path):
    if isCLI(request):
        return render_curl(path)

    return render(path, handshake_scripts=getHandshakeScript(request.host))


@app.route("/now/old", strict_slashes=False)
@app.route("/old", strict_slashes=False)
def old():
    now_dates = list_dates()[1:]
    if isCLI(request):
        response = ""
        for date in now_dates:
            link = date
            date_fmt = datetime.datetime.strptime(date, "%y_%m_%d")
            date_fmt = date_fmt.strftime("%A, %B %d, %Y")
            response += f"{date_fmt} - /now/{link}\n"
        return render_template(
            "now.ascii", date="Old Now Pages", content=response, header=get_header()
        )

    html = '<ul class="list-group">'
    html += f'<a style="text-decoration:none;" href="/now"><li class="list-group-item" style="background-color:#000000;color:#ffffff;">{get_latest_date(True)}</li></a>'

    for date in now_dates:
        link = date
        date = datetime.datetime.strptime(date, "%y_%m_%d")
        date = date.strftime("%A, %B %d, %Y")
        html += f'<a style="text-decoration:none;" href="/now/{link}"><li class="list-group-item" style="background-color:#000000;color:#ffffff;">{date}</li></a>'

    html += "</ul>"
    return render_template(
        "now/old.html",
        handshake_scripts=getHandshakeScript(request.host),
        now_pages=html,
    )


@app.route("/now.rss")
@app.route("/now.xml")
@app.route("/rss.xml")
def rss():
    host = "https://" + request.host
    path = request.path
    if ":" in request.host:
        host = "http://" + request.host
    # Generate RSS feed
    now_pages = list_page_files()
    rss = f'<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Nathan.Woodburn/</title><link>{host}</link><description>See what I\'ve been up to</description><language>en-us</language><lastBuildDate>{datetime.datetime.now(tz=datetime.timezone.utc).strftime("%a, %d %b %Y %H:%M:%S %z")}</lastBuildDate><atom:link href="{host}{path}" rel="self" type="application/rss+xml" />'
    for page in now_pages:
        link = page.strip(".html")
        date = datetime.datetime.strptime(link, "%y_%m_%d")
        pubdate = date.strftime("%a, %d %b %Y 00:00:00 +0000")
        date = date.strftime("%A, %B %d, %Y")
        rss += f"""
        <item>
          <title>What's Happening {date}</title>
          <link>{host}/now/{link}</link>
          <description>Latest updates for {date}</description>
          <pubDate>{pubdate}</pubDate>
          <guid isPermaLink="true">{host}/now/{link}</guid>
        </item>
        """
    rss += "</channel></rss>"
    return make_response(rss, 200, {"Content-Type": "application/rss+xml"})


@app.route("/now.json")
def json():
    now_pages = list_page_files()
    host = "https://" + request.host
    if ":" in request.host:
        host = "http://" + request.host
    now_pages = [
        {
            "url": host + "/now/" + page.strip(".html"),
            "date": datetime.datetime.strptime(
                page.strip(".html"), "%y_%m_%d"
            ).strftime("%A, %B %d, %Y"),
            "title": "What's Happening "
            + datetime.datetime.strptime(page.strip(".html"), "%y_%m_%d").strftime(
                "%A, %B %d, %Y"
            ),
        }
        for page in now_pages
    ]
    return jsonify(now_pages)
