import sys
import os
import boto3
import pandas as pd
import datetime
import json
import tempfile

# django
from django.core.files.base import ContentFile

# all external imports
from scriptAudit.models import States
from centralisedFileSystem.models import Script, File
from scriptAudit.models import ScriptAuditModel
from mnfapp.models import MNFScriptDatabase, SampleScript, ScriptTranslations
from users.models import UserCredentialsForBlockchain,BlockchainUserInfo
from lpp.models import LPPTASKDatabase

from centralizePayment.views import auto_refund
from juggernaut.views import update_juggernaut
from auto_email.views import sendmail
from lpp.views import task_assigner
from utils import filesystem, utilities
from conversion.translation.newconversion import ScriptTranslation
from scriptAudit.mnf_script_audit import NeutralAudit
from Blockchain2.DataStorage import uploadDataToIPFSNode
from Blockchain2.decryption import decryptionOfPrivate, decryptionOfUrl, download_file_System,viewDecryptionOfUrl,hash_decrypation
from Blockchain2.Conversion import UploadConversionData, getConversion, deleteConversion,scriptGetUserprojectIds
from Blockchain2.blockchainsetting import OWNER_KEY
from Blockchain2.block_user_info import user_info
from lpp.certificate.createCertificate import certificateGenrate
from MNF.settings import BasePath

basePath = BasePath()

"""Converts a screenplay file"""


class Conversion:

    def __init__(self, **conversion_params):
        self.user = conversion_params['user']
        self.file_path = conversion_params['file_path']
        self.original_script_object = MNFScriptDatabase.objects.get(
            script_id=conversion_params['original_script_id'])
        self.translated_script_object = ScriptTranslations.objects.get(
            translation_id=conversion_params['translated_script_id'])
        self.sample_id = conversion_params['sample_id']
        self.existing_script = conversion_params['existing_script']
        self.iteration_no = conversion_params['iteration_no']
        self.juggernaut_pages_deduction = conversion_params["juggernaut_pages_deduction"]
        self.language_set = conversion_params["language_set"]
        self.amount_without_subscrption = conversion_params["amount_without_subscrption"]
        self.response = {}

        print("Conversion Process Initializing")
        # original_stdout = sys.stdout

        """Initializing Variables"""
        # script_id = request.session["script_id"]
        # original_script = MNFScriptDatabase.objects.get(script_id=script_id)
        # translated_script = ScriptTranslations.objects.get(translation_id=request.session.get("translation_id", None))

        # Getting all choices of user regarding Full Dialogues Translation
        self.full_dialogue_option_choices = [True if value.strip() == "True" else False for value in
                                        str(self.translated_script_object.full_dialogue_option_choices).split(",")]

        # Getting all choices of user regarding Words of Dialogues Translation
        self.sentence_dialogue_option_choices = [True if value.strip() == "True" else False for value in
                                            str(self.translated_script_object.sentence_dialogue_option_choices).split(",")]

        # Getting all choices of user regarding translation and transliteration choices of slug, speaker, etc.
        self.other_option_choices = [True if value.strip() == "True" else False for value in
                                str(self.translated_script_object.other_option_choices).split(",")]

        self.name_script = (str(((self.original_script_object.script.name).split("/"))[-1]).split("."))[0]
        self.file_extension = (str(self.original_script_object.script.name).split("."))[-1]

    # Dual dialogue
    # if dual_dialogue_option := request.POST.get('dual_dialogue_option') == "on":

    #     dual_left_language = request.POST.get('dual_left_language')
    #     dual_left_script = request.POST.get('dual_left_script')

    # # lpp vetting
    # if lpp_vetting := request.POST.get('lpp_vetting') == "on":

    #     lpp_vetting_type = request.POST.get('radioGroup')

    #     if lpp_vetting_type == "radioOption1":

    #         pass

    #     elif lpp_vetting_type == "radioOption1":

    #         pass

    def convert(self):
        """Audit Code starts here"""

        print("Conversion Auditing is starting")
        original_stdout = sys.stdout
        # x = MNFScriptDatabase.objects.get(script_id=request.POST['script_id'])
        # scripttt = basePath + "/media/" + original_script.script.name
        # exten = (str(self.original_script_object.script.name).split("."))[-1]
        # name_script = str(((((scripttt).split("/"))[-1]).split("."))[0])
        print("name of script", self.name_script)
        print("sample script", self.sample_id)
        print("existing_script", self.existing_script)

        """if file is not a sample script and not a existing script then only audit it"""
        if not self.existing_script and not self.original_script_object.sample_script:
            print("----Auditing----")
            script1 = str(self.file_path)
            doc = open(script1, 'rb').read()
            file = ContentFile(
                doc,
                (script1.split("/"))[-1],
            )
            language_code = "en"
            result = filesystem.new_screenplay_without_audit_in_background(
                self.user,
                self.user.username,
                str(self.name_script),
                file,
                "script-original",
                language_code,
            )
            audit_id = result.get("script", {}).get("id")
            ScriptAuditModel.objects.update_or_create(
                script=Script.objects.get(
                    id=audit_id
                ),
                defaults={"status": States.STARTED}
            )
            audit = NeutralAudit(audit_id, True)
            status = ScriptAuditModel.objects.get(
                script=Script.objects.get(
                    id=audit_id
                )
            )
            try:
                if self.file_extension == "fdx":
                    audit.audit_fdx()
                else:
                    audit.audit()
                status.status = "SUCCESS"
                status.save()
                to_email = [self.user.email]
                email_code = 'SB1'
                sendmail(to_email=to_email, email_code=email_code,key_value={"script_name":self.name_script})
            except Exception as e:
                print("Error of Audit is:", e)
                status.status = "FAILURE"
                status.save()
                to_email = [self.user.email]
                email_code = 'SB2'
                sendmail(to_email=to_email, email_code=email_code,key_value={"script_name":self.name_script})
                print(
                    "Script Audit failed due to some internal error."
                    " If you have made any payment for conversion "
                    "that will be refunded")
                # email for failure
                to = self.user.email
                key_value = {
                    "User": self.user.username,
                }
                sendmail(to_email=[to], email_code="PP21", key_value=key_value)
                # auto refund code
                try:
                    auto_refund(self.translated_script_object.central_payment_id)
                except Exception as e:
                    print("No Refund -> ", e)
                return self.response

            file_path_ = filesystem.get_file_path(audit_id, "script-csv")
            script_data = MNFScriptDatabase.objects.get(script_id=self.original_script_object.script_id)
            script_data.audit_id = str(audit_id)
            script_data.save()
            to_email = [self.user.email]
            email_code = 'SB1'
            sendmail(to_email=to_email, email_code=email_code,key_value={"script_name":self.name_script})
            try:
                df = pd.read_csv(file_path_, encoding="utf-8")
            except UnicodeError:
                df = pd.read_csv(file_path_, encoding="utf-16")
            pd.set_option('display.max_rows', None)
            pd.set_option('display.max_columns', None)
            self.list_of_lists = df.values.tolist()
            print("Audit Done")



        elif self.original_script_object.sample_script:
            sample_script = SampleScript.objects.get(sample_id=self.original_script_object.sample_id.sample_id)
            if sample_script.audit_id:
                audit_id = sample_script.audit_id
                file_path_ = filesystem.get_file_path(audit_id, "script-csv")
                try:
                    df = pd.read_csv(file_path_, encoding="utf-8")
                except UnicodeError:
                    df = pd.read_csv(file_path_, encoding="utf-16")
                pd.set_option('display.max_rows', None)
                pd.set_option('display.max_columns', None)
                self.list_of_lists = df.values.tolist()
            else:
                print("----Auditing----")
                script1 = str(self.file_path)
                doc = open(script1, 'rb').read()
                file = ContentFile(
                    doc,
                    (script1.split("/"))[-1],
                )
                language_code = "en"
                result = filesystem.new_screenplay_without_audit_in_background(
                    self.user,
                    self.user.username,
                    str(self.name_script),
                    file,
                    "script-original",
                    language_code,
                )
                audit_id = result.get("script", {}).get("id")
                ScriptAuditModel.objects.update_or_create(
                    script=Script.objects.get(
                        id=audit_id
                    ),
                    defaults={"status": States.STARTED}
                )
                audit = NeutralAudit(audit_id, False)
                status = ScriptAuditModel.objects.get(
                    script=Script.objects.get(
                        id=audit_id
                    )
                )
                try:
                    if self.file_extension == "fdx":
                        audit.audit_fdx()
                    else:
                        audit.audit()
                    status.status = "SUCCESS"
                    status.save()
                    to_email = [self.user.email]
                    email_code = 'SB1'
                    sendmail(to_email=to_email, email_code=email_code,key_value={"script_name":self.name_script})
                except:
                    status.status = "FAILURE"
                    status.save()
                    to_email = [self.user.email]
                    email_code = 'SB2'
                    sendmail(to_email=to_email, email_code=email_code,key_value={"script_name":self.name_script})
                    print(
                        "Script Audit failed due to some internal error."
                        " If you have made any payment for conversion "
                        "that will be refunded")
                    # email for failure
                    to = self.user.email
                    key_value = {
                        "User": self.user.username,
                    }
                    sendmail(to_email=[to], email_code="PP21", key_value=key_value)
                    # auto refund code
                    try:
                        auto_refund(self.translated_script_object.central_payment_id)
                    except Exception as e:
                        print("No Refund -> ", e)
                    return self.response
                file_path_ = filesystem.get_file_path(
                    audit_id, "script-csv")
                sample_script.audit_id = str(audit_id)
                sample_script.save()
                try:
                    df = pd.read_csv(file_path_, encoding="utf-8")
                except UnicodeError:
                    df = pd.read_csv(file_path_, encoding="utf-16")
                pd.set_option('display.max_rows', None)
                pd.set_option('display.max_columns', None)
                dataframe = df
                self.list_of_lists = dataframe.values.tolist()


        elif self.existing_script:
            if MNFScriptDatabase.objects.get(script_id=self.original_script_object.script_id).audit_id:
                audit_id = MNFScriptDatabase.objects.get(script_id=self.original_script_object.script_id).audit_id
                file_path_ = filesystem.get_file_path(audit_id, "script-csv")
                try:
                    df = pd.read_csv(file_path_, encoding="utf-8")
                except UnicodeError:
                    df = pd.read_csv(file_path_, encoding="utf-16")
                pd.set_option('display.max_rows', None)
                pd.set_option('display.max_columns', None)
                dataframe = df
                self.list_of_lists = dataframe.values.tolist()
            else:
                print("----Auditing----")
                script1 = str(self.file_path)
                doc = open(script1, 'rb').read()
                file = ContentFile(
                    doc,
                    (script1.split("/"))[-1],
                )
                language_code = "en"
                result = filesystem.new_screenplay_without_audit_in_background(
                    self.user,
                    self.user.username,
                    str(self.name_script),
                    file,
                    "script-original",
                    language_code,
                )
                audit_id = result.get("script", {}).get("id")
                ScriptAuditModel.objects.update_or_create(
                    script=Script.objects.get(
                        id=audit_id
                    ),
                    defaults={"status": States.STARTED}
                )
                audit = NeutralAudit(audit_id, False)
                status = ScriptAuditModel.objects.get(
                    script=Script.objects.get(
                        id=audit_id
                    )
                )
                try:
                    if self.file_extension == "fdx":
                        audit.audit_fdx()
                    else:
                        audit.audit()
                    status.status = "SUCCESS"
                    status.save()
                    to_email = [self.user.email]
                    email_code = 'SB1'
                    sendmail(to_email=to_email, email_code=email_code,key_value={"script_name":self.name_script})
                except:
                    status.status = "FAILURE"
                    status.save()
                    to_email = [self.user.email]
                    email_code = 'SB2'
                    sendmail(to_email=to_email, email_code=email_code,key_value={"script_name":self.name_script})
                    print(
                        "Script Audit failed due to some internal error."
                        " If you have made any payment for conversion "
                        "that will be refunded")
                    # email for failure
                    to = self.user.email
                    key_value = {
                        "User": self.user.username,
                    }
                    sendmail(to_email=[to], email_code="PP21", key_value=key_value)
                    # auto refund code
                    try:
                        auto_refund(self.translated_script_object.central_payment_id)
                    except Exception as e:
                        print("No Refund -> ", e)
                    return self.response
                file_path_ = filesystem.get_file_path(
                    audit_id, "script-csv")
                script_data = MNFScriptDatabase.objects.get(script_id=self.original_script_object.script_id)
                script_data.audit_id = str(audit_id)
                script_data.save()
                to_email = [self.user.email]
                email_code = 'SB1'
                sendmail(to_email=to_email, email_code=email_code,key_value={"script_name":self.name_script})
                try:
                    df = pd.read_csv(file_path_, encoding="utf-8")
                except UnicodeError:
                    df = pd.read_csv(file_path_, encoding="utf-16")
                pd.set_option('display.max_rows', None)
                pd.set_option('display.max_columns', None)
                dataframe = df
                self.list_of_lists = dataframe.values.tolist()

        sys.stdout = original_stdout
        print("Audit Done")
        self.translated_script_object.status = "Audited"
        self.translated_script_object.save()


        """Translation Code Starts here"""
        print("list of lists -> ", self.list_of_lists)
        dataframe = self.list_of_lists

        args = [self.full_dialogue_option_choices, self.sentence_dialogue_option_choices, self.other_option_choices]

        kwargs = {
            "user": self.translated_script_object.user_id,
            "iteration_no": self.iteration_no,
            'dataframe': dataframe,
            "non_dial_src_lang": self.original_script_object.nondial_src_language,
            "non_dial_src_script": self.original_script_object.nondial_src_script,
            "non_dial_dest_lang": self.translated_script_object.nondial_dest_language,
            "non_dial_dest_script": self.translated_script_object.nondial_dest_script,
            "dial_src_lang": self.original_script_object.dial_src_language,
            "dial_src_script": self.original_script_object.dial_src_script,
            "dial_dest_lang": self.translated_script_object.dial_dest_language,
            "dial_dest_script": self.translated_script_object.dial_dest_script,
            "translation_id": self.translated_script_object.translation_id,
            "script_id": self.original_script_object.script_id
        }

        # original_stdout = sys.stdout

        try:
            ScriptTranslation(*args, **kwargs)

        except Exception as e:
            self.translated_script_object.status = "Failed"
            self.translated_script_object.error_desc = str(e)
            self.translated_script_object.save()
            print("Error in Conversion is:", e)
            print("Script translation failed due to some code error. If you have made any payment for conversion"
                  " that will be refunded")

            # email for failure
            to = self.user.email
            key_value = {
                "User": self.user.username,
            }
            sendmail(to_email=[to], email_code="PP21", key_value=key_value)
            # auto refund code
            try:
                auto_refund(self.translated_script_object.central_payment_id)
            except Exception as e:
                print("No Refund due to error", e)
            return self.response

        """Translation Code Ends Here"""



        sys.stdout = original_stdout

        self.translated_script_object = ScriptTranslations.objects.get(
            translation_id=self.translated_script_object.translation_id)

        """Juggernaut Payment Updation"""
        if self.juggernaut_pages_deduction:
            user_data = JuggernautPackage.objects.filter(user_id = self.user)
            if user_data.count() == 1:
                pass
            else:
                self.session = {}
                try:
                    if user_data.count() > 1:
                        max_beat = 0
                        for i in user_data:
                            if i.conversion_pages >= max_beat:
                                user_data = i
                                self.session['user_data'] = str(user_data.id)
                except:
                    max_beat = 0

                    self.session['user_data'] = str(user_data.id)
            update_juggernaut(self,
                              user_id=self.user.id,
                              service_name="conversion",
                              conversion_pages=self.juggernaut_pages_deduction,
                              associated_project=self.original_script_object,
                              translation_language=self.language_set)
            self.original_script_object.is_juggernaut_used = True
            # if script_original.languages_juggernaut != "":
            #     # script_original.languages_juggernaut = str(script_original.languages_juggernaut) + "," + str(
            #     #     script_translated.dial_dest_language)
            # else:
            # script_original.languages_juggernaut = str(script_translated.dial_dest_language)
            self.original_script_object.save()
        """Juggernaut Payment Updation Done"""



        """Translation Completion mail here"""

        to = self.user.email
        key_value = {
            "User": self.user.username,
            "title": self.original_script_object.script_title
        }
        sendmail(to_email=[to], email_code="PP18", key_value=key_value)

        """Translation Completion mail done"""



        """Vetting Process if Choosen"""
        # sys.stdout = original_stdout
        if self.translated_script_object.lpp:
            X = LPPTASKDatabase()
            X.user_id = self.translated_script_object.user_id
            X.usernote = "Kindly check if the translated file is correct as per the Uploaded Document!"
            X.translated_script = self.translated_script_object
            X.generated_from = "conversion"
            temp_amount = self.amount_without_subscrption
            X.amoutgiventolpp_action = round((temp_amount / 2), 2)
            X.amoutgiventolpp_dialogue = round((temp_amount / 2), 2)
            X.save()
            task_assigner(int(X.task_id), "conversion")
            

            # adding file to s3 output folder

            object_name = "OUTPUT/" + (self.translated_script_object.translated_script_path.split("/"))[-1]
            filee = basePath + self.translated_script_object.translated_script_path
            # Upload the file
            bucket = "conversion-kitchen"
            s3_client = boto3.client('s3',
                                    aws_access_key_id="AKIAQVLBBGCB45RMLKVW",
                                    aws_secret_access_key="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",
                                    region_name="ap-south-1"
                                    )
            try:
                response = s3_client.upload_file(filee, bucket, object_name)
                s3_url = f"https://{bucket}.s3.ap-south-1.amazonaws.com/{object_name}"
                
                print(response)
            except Exception as e:
                print("Error is", e)


        else:

            """Blockchain Upload Starts here"""
            # sys.stdout = original_stdout
            scriptconversion = {}
            try:
                print("trying blockchain 1")
                current_datetime = datetime.datetime.now()
                if UserCredentialsForBlockchain.objects.filter(user=self.user).exists():
                    obj = self.translated_script_object
                    obj2 = self.original_script_object
                    temp1 = str(obj2.script)
                    temp2 = str(obj.translated_script_path)
                    uploaded_script = f"{basePath}/media/{temp1}"
                    translated_scripttt = f"{basePath}{temp2}"
                    print("blockchain script conversion 3", uploaded_script, translated_scripttt)
                    with open(uploaded_script, 'rb') as f:
                        hash = uploadDataToIPFSNode(f)
                        scriptconversion["original_scriptFile_hash"] = hash
                    scriptconversion["original_scriptFile_path"] = uploaded_script
                    scriptconversion["date_at"] = current_datetime.strftime("%Y-%m-%d %H:%M:%S")
                    print("blockchain script conversion 4")
                    with open(translated_scripttt, 'rb') as f1:
                        hash = uploadDataToIPFSNode(f1)
                        scriptconversion["translated_scriptFile_hash"] = hash
                    scriptconversion["translated_scriptFile_path"] = translated_scripttt
                    print("blockchain script conversion 5")

                    print("audit blockchain")
                    print("blockchain script conversion 5.1")
                    # blockchain upload of csv-json data
                    adit_id = obj.converted_audit_id

                    file_to_audit = File.objects.get(
                        script=adit_id,
                        type="script-csv"
                    )
                    csv_script_path = file_to_audit.file.path
                    df = pd.read_csv(csv_script_path)
                    df = df.loc[:, ["content", "script_element"]]
                    script_json: dict = json.loads(utilities.csv_to_json(df))
                    with tempfile.TemporaryDirectory() as temp_dir:
                        print("Temporary directory created:", temp_dir)
                        temp_filename = os.path.join(temp_dir, 'script_json_file.json')
                        print(temp_filename)
                        with open(temp_filename, 'w') as json_file:
                            json.dump(script_json, json_file, indent=4)
                        script_json = {}
                        script_path1 = temp_filename
                        # script_size = file_to_audit_docx.file.size
                        with open(script_path1, 'rb') as _file:
                            hash2 = uploadDataToIPFSNode(_file)
                        script_json["script_file_path"] = script_path1
                        script_json["script_file"] = hash2
                        script_json["type"] = "script-json"
                        scriptconversion["script-json"] = script_json
                    print("blockchain script conversion 5.2")

                    blockchain_obj = UserCredentialsForBlockchain.objects.get(user=self.user)
                    UserId = blockchain_obj.user_id
                    Project = obj.translation_id
                    Data = str(scriptconversion)
                    userPrivateKey = blockchain_obj.privateKey
                    userkey = decryptionOfPrivate(userPrivateKey)
                    tx_id, tx_gas_fee = UploadConversionData(OWNER_KEY, blockchain_obj.publicKey, UserId, str(Project),
                                                        Data)
                                                    
                    print("Tx id -> ", tx_id,tx_gas_fee)
                    print(type(tx_id))
                    
                # user_infos = user_info(tx_hash=tx_id, service="Conversion", gas_fee=2345432345123456)
                # addition_result = user_infos.update_info(request)
                    try:
                        user_infos = user_info(tx_hash=tx_id, service="Conversion", gas_fee=tx_gas_fee,
                                        script_name=self.name_script)
                        addition_result = user_infos.update_info(self)
                        print("Blockchain Result -> ",addition_result)
                    except Exception as e:
                        print("Error:", e)

                    print("blockchain script conversion 6")
                    certificatepath = certificateGenrate(self.user.username, "script conversion", hash)
                    hash = hash_decrypation(hash)
                    to_email = [self.user.email]
                    email_code = 'BL1'
                    key_value = {
                        "service": "script conversion",
                        "hash": hash,
                        "public key": blockchain_obj.publicKey,
                        "private key": userkey.decode('utf-8'),
                        "Transaction Hash": tx_id
                    }
                    sendmail(to_email=to_email, email_code=email_code,key_value=key_value, filePath=certificatepath)
            except Exception as e:
                print("Error in blockchain is", e)

            """Blockchain Upload Ends here"""

    

        """Process Completed"""
        self.translated_script_object.status = "Completed"
        try:
            self.translated_script_object.blockchain_txhash = tx_id
        except:
            self.translated_script_object.translated_script_pdf = s3_url
        self.translated_script_object.save()

        return self.response




# from pathlib import Path
# basePath = Path(__file__).resolve().parent.parent
# translation_script = ScriptTranslations.objects.get(translation_id="")
#
# conversion_params = {
#     "user": translation_script.user_id,
#     "file_path": str(basePath) + "/media/" + translation_script.script_link_id.script.name,
#     "original_script_object": translation_script.script_link_id,
#     "translated_script_object": translation_script,
#     "sample_id": None,
#     "existing_scrip": None
# }

# obj = Conversion(**conversion_params)