from rich.console import Console
from rich.table import Table
from rich.columns import Columns
from rich.rule import Rule
console = Console()
hline = Rule(style="white")

import os
import subprocess
from slack_sdk import WebClient
import configuration
models = configuration.models

u_options = {
    "ENTER" : "Accept PDF as is. It gets marked as verified",
    "D" : "set languange to DE and set verified",
    "E" : "set languange to EN and set verified",
    "O" : "set other language (prompted)",
    "R" : "set related files (prompted multiple times)",
    "B" : "reject and move to folder BAD",
    "L" : "leave file as is, do not send reaction"
}


bot_client = WebClient(
    token = configuration.parsed["SLACK"]["auth_token"]
)





def file_overview(file_url: str, file_attributes: list, options: dict) -> None:
    """Prints a neat overview of the current article"""
    file_table = Table(
        title = file_url,
        row_styles = ["white", "bright_black"],
        min_width = 100
    )

    file_table.add_column("Attribute", justify = "right", no_wrap = True)
    file_table.add_column("Value set by auto_news")
    file_table.add_column("Status", justify = "right")
    for attr in file_attributes:
        file_table.add_row(attr["name"], attr["value"], attr["status"])

    
    option_key = "\n".join([f"[[bold]{k}[/bold]]" for k in options.keys()])
    option_action = "\n".join([f"[italic]{k}[/italic]" for k in options.values()])
    columns = Columns([option_key, option_action])

    console.print(file_table)
    console.print("Your options:")
    console.print(columns)


def send_reaction_to_slack_thread(article, reaction):
    """Sends the verification status as a reaction to the associated slack thread. This will significantly decrease load times of the bot"""
    thread = article.slack_thread
    messages = models.Message.select().where(models.Message.text.contains(article.article_url))
    # TODO rewrite this shit
    if len(messages) > 5:
        print("Found more than 5 messages. Aborting reactions...")
        return
    for m in messages:
        if not m.has_single_url:
            print("Found thread but won't send reaction because thread has multiple urls")
            pass
        else:
            ts = m.slack_ts
            bot_client.reactions_add(
                channel=configuration.parsed["SLACK"]["archive_id"],
                name=reaction,
                timestamp=ts
            )
            print("Sent reaction to message")


def prompt_language(query):
    not_set = True
    while not_set:
        uin = input("Set language (nation-code, 2 letters) ")
        if len(uin) != 2:
            print("Bad code, try again")
        else:
            not_set = False
            query.language = uin
            query.save()


def prompt_related(query):
    file_list = []
    finished = False
    while not finished:
        uin = input("Additional file for article? Type '1' to cancel ")
        if uin == "1":
            query.set_related(file_list)
            finished = True
        else:
            file_list.append(uin)


def prompt_new_fname(query):
    uin = input("New fname? ")
    old_fname =  query.file_name
    query.file_name = uin
    query.verified = 1
    if old_fname != "":
        os.remove(query.save_path + old_fname)
    query.save()    



def reject_article(article):
    article.verified = -1
    article.save()
    print("Article marked as bad")
    # also update the threads to not be monitored anymore
    send_reaction_to_slack_thread(article, "x")


def unreject_article(query):
    query.verified = 1
    query.save()
    # os.rename(badpdf, fname)
    print("File set to verified")


def accept_article(article, last_accepted):
    article.verified = 1
    article.save()
    print("Article accepted as GOOD")

    # also update the threads to not be monitored anymore
    send_reaction_to_slack_thread(article, "white_check_mark")

    return "" # linked






def verify_unchecked():
    query = models.ArticleDownload.select().where(models.ArticleDownload.verified == 0).execute()
    last_linked = None

    for article in query:
        console.print(hline)
        core_info = []
        for e, name in zip([article.save_path, article.file_name, article.title, article.language], ["Save path", "File name", "Title", "Language"]):
            entry = {
                "status" : "[red]██[/red]" if (len(e) == 0 or e == -1) else "[green]██[/green]",
                "value" : e if len(e) != 0 else "not set",
                "name" : name
            }
            core_info.append(entry)
        
        try:
            # close any previously opened windows:
            # subprocess.call(["kill", "`pgrep evince`"])
            os.system("pkill evince")
            # then open a new one
            subprocess.Popen(["evince", f"file://{os.path.join(article.save_path, article.file_name)}"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            # supress evince gtk warnings
        except Exception as e:
            print(e)
            continue

        

        file_overview(
            file_url = article.article_url, 
            file_attributes=core_info,
            options = u_options
        )


        proceed = False
        while not proceed:
            proceed = False
            uin = input("Choice ?").lower()
            if uin == "":
                last_linked = accept_article(article, last_linked) # last linked accelerates the whole process
                proceed = True
            elif uin == "d":
                article.language = "de"
                article.verified = 1
                article.save()
                proceed = True
            elif uin == "e":
                article.language = "en"
                article.verified = 1
                article.save()
                proceed = True
            elif uin == "o":
                prompt_language(article)
            elif uin == "r":
                prompt_related(article)
            elif uin == "b":
                reject_article(article)
                proceed = True
            elif uin == "l":
                # do nothing
                proceed = True
            else:
                print("Invalid input")