import os
import sys
import requests
import json
import threading
import multiprocessing
import random
import re
import psutil
import time as t
import subprocess

sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
import config
from base.utils.database import Database
from base.utils.subtitle_editor import create_movieo_subtitle
from asyncio import create_task
from traceback import format_exc

def send_request(method, data):
    if method == 'getFile':
        response = requests.post(f'{config.TELEGRAM_API}{method}', json=data)
    else:
        response = requests.post(f'{config.TELEGRAM_API}{method}', json=data)
    return response

def monitor_file(process, input_file):
    while (True):
        if process.poll() is None:
            if not os.path.exists(input_file):
                parent = psutil.Process(process.pid)
                for child in parent.children(recursive=True):
                    child.kill()
                parent.kill()
                break
            t.sleep(1)
        else:
            break

try:
    with Database() as db:
        media_task_db = db.get_media_task(3, 'status', 'id,message_id,file_name,package_id')
    if media_task_db:
        for task in media_task_db:
            task_id = task[0]
            message_id = task[1]
            file_name = task[2]
            package_id = task[3]
            with Database() as db:
                package_db = db.get_package(package_id,'id','chat_id,type')
            chat_id = package_db[0][0]
            task_type = package_db[0][1]
            if task_type == 4:
                with Database() as db:
                    db.update_media_task(task_id, 'status', 4)
                for quality in config.DEFAULT_QUALITIES:
                    if re.search(r'\b' + quality + r'\b', file_name):
                        quality = quality
                        break
                    else:
                        quality = None
                if quality != None:
                    reply_markup = {
                        'inline_keyboard': [
                            [{'text': '❌ انصراف', 'callback_data': f'cancel,{task_id}'}]
                        ]
                    }
                    data = {
                        'chat_id': chat_id,
                        'message_id': message_id,
                        'text': f'در حال تبدیل فایل به کیفیت {quality}...',
                        'reply_markup': reply_markup
                    }
                    send_request('editMessageText', data)
                    command = f"ffprobe -i {config.DOWNLOAD_DIR}'{file_name}' -v quiet -show_entries format=duration -hide_banner -of default=noprint_wrappers=1:nokey=1 -sexagesimal"
                    res = subprocess.run(command, shell=True, capture_output=True, text=True)
                    if res.returncode == 0:
                        duration = res.stdout.split('.')[0].split(':')
                        sec = 0
                        if int(duration[0]) != 0:
                            sec = int(duration[0]) * 60
                            sec = sec * 60
                        sec += int(duration[1]) * 60
                        sec += int(duration[2])
                        try:
                            random_sec = random.randint(300, sec - 300)
                        except:
                            random_sec = random.randint(0, sec - 60)
                        if quality == '360p':
                            bit_rate = '360k'
                            height = 640
                            width = 360
                        elif quality == '480p':
                            bit_rate = '480k'
                            height = 854
                            width = 480
                        elif quality == '540p':
                            bit_rate = '540k'
                            height = 960
                            width = 540
                        elif quality == '720p':
                            bit_rate = '720k'
                            height = 1280
                            width = 720
                        elif quality == '1080p':
                            bit_rate = '1080k'
                            height = 1920
                            width = 1080
                        command = f'ffmpeg  -i {config.DOWNLOAD_DIR}{file_name} -n -i {config.LOGO_DIR} -filter_complex "[0:v]scale={height}:{width},setsar=1[v];[1:v]scale=iw/9:-1[logo];[v][logo]overlay=W-w-5:H-h-5:enable=' + f"'between(t,{random_sec},{random_sec + 60})'" + f'" -b:v {bit_rate} -c:a copy {config.MOVIEO_ENCODES_DIR}{file_name}'
                        process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                        monitor_thread = threading.Thread(target=monitor_file,args=(process, f'{config.DOWNLOAD_DIR}{file_name}'))
                        monitor_thread.start()
                        a, b = process.communicate()
                        monitor_thread.join()
                        movieo_subtitle = create_movieo_subtitle(sec)
                        command = f"ffmpeg  -i {config.MOVIEO_ENCODES_DIR}{file_name} -sub_charenc 'UTF-8' -f srt -i {config.SUBTITLE_DIR}{movieo_subtitle}.srt -map 0:0 -map 0:1 -map 1:0 -disposition:s:0 default -c:v copy -c:a copy -c:s srt {config.MOVIEO_ENCODES_DIR}temp_{file_name}"
                        process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                        monitor_thread = threading.Thread(target=monitor_file,args=(process, f'{config.MOVIEO_ENCODES_DIR}{file_name}'))
                        monitor_thread.start()
                        process.communicate()
                        monitor_thread.join()
                    try:
                        command = f'rm {config.MOVIEO_ENCODES_DIR}{file_name}'
                        subprocess.run(command, shell=True, capture_output=True, text=True)
                        command = f'mv {config.MOVIEO_ENCODES_DIR}temp_{file_name} {config.MOVIEO_ENCODES_DIR}{file_name}'
                        subprocess.run(command, shell=True, capture_output=True, text=True)
                        os.remove(f"{config.DOWNLOAD_DIR}{file_name}")
                        os.remove(f"{config.SUBTITLE_DIR}{movieo_subtitle}.srt")
                    except:
                        pass
                    with Database() as db:
                        db.update_media_task(task_id, 'status', 5)
                    break
except Exception as e:
    try:
        data = {
            'chat_id': 689423806,
            'text': f'ERROR: {e}',
        }
        send_request('sendMessage', data)
    except:
        pass