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

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')
    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 == 3:
            with Database() as db:
                db.update_media_task(task_id, 'status', 4)
            reply_markup = {
                'inline_keyboard': [
                    [{'text': '❌ انصراف', 'callback_data': f'cancel,{task_id}'}]
                ]
            }
            data = {
                'chat_id': chat_id,
                'message_id': message_id,
                'text': '📥 درحال دانلود صوت دوبله...',
                'reply_markup': reply_markup
            }
            send_request('editMessageText', data)
            with Database() as db:
                media_task_db = db.get_media_task(task_id, 'id', 'sub_or_audio')
            audio = media_task_db[0][0]
            audio_name = audio.split('/')[-1]
            command = f'wget -O "{config.DUBBED_DIR}{audio_name}" "{audio}"'
            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()
            process.communicate()
            monitor_thread.join()
            if os.path.exists(f'{config.DUBBED_DIR}{audio_name}'):
                reply_markup = {
                    'inline_keyboard': [
                        [{'text': '❌ انصراف', 'callback_data': f'cancel,{task_id}'}]
                    ]
                }
                data = {
                    'chat_id': chat_id,
                    'message_id': message_id,
                    'text': '📥 درحال اضافه کردن صوت دوبله به فایل...',
                    '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])
                    random_sec = random.randint(300, sec - 300)
                    name, file_format = os.path.splitext(f'{file_name}')
                    if file_format != '.mp4':
                        command = f"ffmpeg  -i {config.DOWNLOAD_DIR}{file_name} -n -c copy {config.DOWNLOAD_DIR}{file_name.replace(file_format, '.mp4')}"
                        subprocess.run(command, shell=True, capture_output=True, text=True)
                        file_name = file_name.replace(file_format, ".mp4")
                    command = f'ffmpeg  -i "{config.DOWNLOAD_DIR}{file_name}" -n -i "{config.DUBBED_DIR}{audio_name}"  -map 0:v -map 1:a -c:v copy -c:a copy -map 0:s? -disposition:a:0 default -disposition:a:1 none "{config.DUBBED_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()
                    process.communicate()
                    monitor_thread.join()
                    if os.path.exists(f'{config.DUBBED_DIR}{file_name}'):
                        # remove mp4 format
                        command = f'rm "{config.DOWNLOAD_DIR}{file_name}"'
                        subprocess.run(command, shell=True, capture_output=True, text=True)
                        # convert and return to mkv format because mp4 can not support srt
                        command = f'ffmpeg -i "{config.DUBBED_DIR}{file_name}" -n -c copy "{config.DUBBED_DIR}{file_name.replace(".mp4", ".mkv")}"'
                        subprocess.run(command, shell=True, capture_output=True, text=True)
                        # remove mp4 format form dubbed dir
                        command = f'rm {config.DUBBED_DIR}{file_name}'
                        subprocess.run(command, shell=True, capture_output=True, text=True)
                        file_name = file_name.replace(".mp4", ".mkv")
                        movieo_subtitle = create_movieo_subtitle(sec)
                        command = f"ffmpeg  -i '{config.DUBBED_DIR}{file_name}' -n -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.DUBBED_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.DUBBED_DIR}{file_name}'))
                        monitor_thread.start()
                        process.communicate()
                        monitor_thread.join()
                        if os.path.exists(f'{config.DUBBED_DIR}temp_{file_name}'):
                            command = f'rm {config.DUBBED_DIR}{file_name}'
                            subprocess.run(command, shell=True, capture_output=True, text=True)
                            command = f'mv {config.DUBBED_DIR}temp_{file_name} {config.DUBBED_DIR}{file_name}'
                            subprocess.run(command, shell=True, capture_output=True, text=True)
                            try:
                                os.remove(f"{config.DOWNLOAD_DIR}{file_name}")
                            except:
                                pass
                            os.remove(f"{config.DUBBED_DIR}{audio_name}")
                            os.remove(f"{config.SUBTITLE_DIR}{movieo_subtitle}.srt")
                            with Database() as db:
                                db.update_media_task(task_id, 'status', 5)
                                db.update_media_task(task_id, 'file_name', file_name)
                            break
except Exception as e:
        if os.path.exists(f'{config.DUBBED_DIR}{file_name}'):
            with Database() as db:
                db.update_media_task(task_id, 'status', 5)
        data = {
            'chat_id': 689423806,
            'text': f'ERROR: {e}',
        }
        send_request('sendMessage', data)