import datetime
import re
from pathlib import PurePath

from src.config import Configuration
from src.lib.artist import get_artist
from src.lib.post import (
    get_fileserver_for_value,
    get_post,
    get_post_comments,
    get_post_revisions,
    get_posts_incomplete_rewards,
    is_post_flagged,
    patch_inline_img,
)
from src.lib.posts import Post
from src.utils.utils import images_pattern, sanitize_html

from flask import session

video_extensions = Configuration().webserver["ui"]["video_extensions"]


def ready_post_props(post: Post):
    service = post["service"]
    artist_id = post["user"]
    post_id = post["id"]

    if service in ("patreon",):

        if post["file"] and post["attachments"] and post["file"] == post["attachments"][0]:
            post["attachments"] = post["attachments"][1:]

    if service in ("fansly", "onlyfans"):
        posts_incomplete_rewards = get_posts_incomplete_rewards(post_id, artist_id, service)

        if posts_incomplete_rewards:
            post["incomplete_rewards"] = "This post is missing paid rewards from a higher tier or payment."

            if post["service"] == "onlyfans":
                try:
                    rewards_info_text = (
                        f"{posts_incomplete_rewards["incomplete_attachments_info"]["media_count"]} media, "
                        f"{posts_incomplete_rewards["incomplete_attachments_info"]["photo_count"]} photos, "
                        f"{posts_incomplete_rewards["incomplete_attachments_info"]["video_count"]} videos, "
                        f"for {posts_incomplete_rewards["incomplete_attachments_info"]["price"]}$."
                    )
                    post["incomplete_rewards"] += "\n" + rewards_info_text
                except Exception:
                    pass

            elif post["service"] == "fansly":
                try:
                    rewards_info_text = (
                        f"Downloaded:{posts_incomplete_rewards["incomplete_attachments_info"]["complete"]} "
                        f"Missing:{posts_incomplete_rewards["incomplete_attachments_info"]["incomplete"]}"
                    )
                    post["incomplete_rewards"] += "\n" + rewards_info_text
                except Exception:
                    pass
    previews = []
    attachments = []
    videos = []

    if "path" in post["file"]:

        if images_pattern.search(post["file"]["path"]):
            previews.append(
                {
                    "type": "thumbnail",
                    "server": get_fileserver_for_value(f"/data{post["file"]["path"]}"),
                    "name": post["file"].get("name"),
                    "path": post["file"]["path"],
                }
            )
        else:
            file_extension = PurePath(post["file"]["path"]).suffix
            name_extension = PurePath(post["file"].get("name") or "").suffix
            # filename without extension
            stem = PurePath(post["file"]["path"]).stem
            attachments.append(
                {
                    "server": get_fileserver_for_value(f"/data{post["file"]["path"]}"),
                    "name": post["file"].get("name"),
                    "extension": file_extension,
                    "name_extension": name_extension,
                    "stem": stem,
                    "path": post["file"]["path"],
                }
            )

    if len(post.get("embed") or []):
        previews.append(
            {
                "type": "embed",
                "url": post["embed"]["url"],
                "subject": post["embed"]["subject"],
                "description": post["embed"]["description"],
            }
        )

    for attachment in post["attachments"]:

        if images_pattern.search(attachment["path"]):
            previews.append(
                {
                    "type": "thumbnail",
                    "server": get_fileserver_for_value(f"/data{attachment["path"]}"),
                    "name": attachment["name"],
                    "path": attachment["path"],
                }
            )
        else:
            file_extension = PurePath(attachment["path"]).suffix
            name_extension = PurePath(attachment.get("name") or "").suffix
            # filename without extension
            stem = PurePath(attachment["path"]).stem
            attachments.append(
                {
                    "server": get_fileserver_for_value(f"/data{attachment["path"]}"),
                    "name": attachment.get("name"),
                    "extension": file_extension,
                    "name_extension": name_extension,
                    "stem": stem,
                    "path": attachment["path"],
                }
            )

    for i, attachment in enumerate(attachments):
        if attachment["extension"] in video_extensions:
            videos.append(
                {
                    "index": i,
                    "path": attachment["path"],
                    "name": attachment.get("name"),
                    "extension": attachment["extension"],
                    "name_extension": attachment["name_extension"],
                    "server": get_fileserver_for_value(f"/data{attachment["path"]}"),
                }
            )

    if post.get("poll") is not None:
        post["poll"]["total_votes"] = sum(choice["votes"] for choice in post["poll"]["choices"])
        post["poll"]["created_at"] = datetime.datetime.fromisoformat(post["poll"]["created_at"])
        if post["poll"]["closes_at"]:
            post["poll"]["closes_at"] = datetime.datetime.fromisoformat(post["poll"]["closes_at"])

    if (captions := post.get("captions")) is not None:
        for file_hash, caption_data in captions.items():
            for preview_data in [preview for preview in previews if preview.get("path") == file_hash]:
                if isinstance(caption_data, dict):
                    preview_data["caption"] = caption_data.get("text") or ""
                elif isinstance(caption_data, list):
                    preview_data["caption"] = " ".join(each.get("text") or "" for each in caption_data)
            for video in [video for video in videos if video["path"] == file_hash]:
                if isinstance(caption_data, dict):
                    video["caption"] = caption_data.get("text") or ""
                elif isinstance(caption_data, list):
                    video["caption"] = " ".join(each.get("text") or "" for each in caption_data)

    props = {
        "service": service,
        "artist": get_artist(service, artist_id),
        "flagged": is_post_flagged(service, artist_id, post_id),
        "revisions": get_post_revisions(service, artist_id, post_id),
    }
    real_post = post if not post.get("revision_id") else get_post(service, artist_id, post_id)
    all_revisions = [real_post] + props["revisions"]
    for set_prev_next_revision in (post, *props["revisions"]):
        set_prev_next_revision["prev"] = real_post["prev"]
        set_prev_next_revision["next"] = real_post["next"]

    if props["revisions"]:
        last_date = real_post["added"]
        for i, rev in enumerate(all_revisions[:-1]):
            rev["added"] = all_revisions[i + 1]["added"]
        props["revisions"][-1]["added"] = last_date

        if real_post["service"] == "fanbox":
            top_rev_stripped = all_revisions[0].copy()
            top_rev_stripped.pop("file")
            top_rev_stripped.pop("added")
            top_rev_stripped.pop("revision_id", None)
            for fanbox_attachment in top_rev_stripped["attachments"]:
                if 41 >= len(fanbox_attachment["name"]) >= 39:
                    fanbox_attachment.pop("name", None)
            for duplicated_check_rev in all_revisions[1:]:
                duplicated_check_rev_file_stripped = duplicated_check_rev.copy()
                duplicated_check_rev_file_stripped.pop("file")
                duplicated_check_rev_file_stripped.pop("added")
                duplicated_check_rev_file_stripped.pop("revision_id", None)
                for fanbox_attachment in duplicated_check_rev_file_stripped["attachments"]:
                    if 41 >= len(fanbox_attachment["name"]) >= 39:
                        fanbox_attachment.pop("name", None)
                if duplicated_check_rev_file_stripped == top_rev_stripped:
                    all_revisions.remove(duplicated_check_rev)
                else:
                    top_rev_stripped = duplicated_check_rev_file_stripped

    if isinstance(post["tags"], str):
        post["tags"] = [tag.strip('"') for tag in post["tags"][1:-1].split(",")]

    props["revisions"] = list(reversed([(i, rev) for i, rev in enumerate(reversed(all_revisions))]))
    comments = get_post_comments(post_id, service)
    if post["service"] == "fanbox":
        post["content"] = DOWNLOAD_URL_FANBOX_REGEX.sub("", post["content"])
    post["content"] = sanitize_html(post["content"], allow_iframe=post["service"] == "fanbox")
    if post["service"] == "boosty":
        post["content"] = patch_inline_img(post["content"])

    return attachments, comments, previews, videos, props


DOWNLOAD_URL_FANBOX_REGEX = re.compile(r"<img\s+src=[\"']https:\/\/downloads\.fanbox\.cc\/.*?['\"]\/>")
