import time
import shutil
import sys
import os
import hashlib
import urllib.parse
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from celery_tasks.celery import app
from base.utils.funcs import log_request, send_request, run_command, concat_ws
from base.utils import MovieoDatabase, RedisDatabase, SEND_QUALITY_REQUEST_TO_ADMIN, YOUR_REQUEST_ADDED, download_video, \
    get_video_duration_seconds, get_random_second, finding_best_quality_for_convert, resolve_2_part_request, \
    create_new_file_name, determine_encoding_settings
from config import LOGO_DIR, MOVIEO_TELEGRAM_API, MOVIEO_CLI, AUTO_SUB_CH, ARCHIVE_CHANNEL, TELEGRAM_API, DOWNLOAD_DIR, MOVIEO_ENCODES_DIR, QUALITIES_PYRAMID

@app.task(queue='qualities')
def preparing_file_and_convert_quality(sending_details: dict, requested_quality: str, movieo_file_id: int, file_name: str, file_id: str, title_id: int, title_type: int):
    api_url = sending_details['api_url']

    print(f'\n**********************\n--- download {file_name} has begun. \n**********************')
    server_file_name, _ = download_video(api_url,file_id,file_name)
    if server_file_name:
        print(f'\n**********************\n--- setting encoder params base on {requested_quality}. \n**********************')
        bit_rate, height, width, codec = determine_encoding_settings(requested_quality)

        if title_id:
            new_file_name, btn, release_type, season, ep = create_new_file_name(title_id, movieo_file_id, title_type, requested_quality)
            sending_details['api_url'] = MOVIEO_TELEGRAM_API
        else:
            new_file_name = file_name
            btn = release_type = season = ep = None
        print(f'\n**********************\n--- encoded file name: {new_file_name} \n**********************')

        print(f'\n**********************\n--- fetching duration and choosing random timestamp. \n**********************')
        sec = get_video_duration_seconds(f'{DOWNLOAD_DIR}{server_file_name}')
        random_sec = get_random_second(sec)

        print(f'\n**********************\n--- converting {file_name} to {requested_quality} with {codec} codec has started. \n**********************')
        command = f'ffmpeg  -i {DOWNLOAD_DIR}{server_file_name} -n -i {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'" -c:v {codec} -b:v {bit_rate} -c:a copy {MOVIEO_ENCODES_DIR}{new_file_name}'
        run_command(command, f'something went wrong when trying to convert file to {requested_quality}.')
        file_name = new_file_name

        upload_list = []
        upload_list.append({f'{MOVIEO_ENCODES_DIR}{file_name}': {'btn': btn, 'quality': requested_quality, 'release_type': release_type,'encoder': 'MVO', 'season': season, 'episode': ep}})
        qu = ' '.join([p for p in [requested_quality, release_type, "MVO"] if p])
        if title_type == 1:
            outer_concat = concat_ws('|', title_id, None, 1, qu)
        else:
            outer_concat = concat_ws('|', title_id, season, 1, qu)
        combo_hash = hashlib.sha256(outer_concat.encode('utf-8')).hexdigest().upper()
        result = {'status': True, 'qu': qu, 'combo_hash': combo_hash, 'upload_list': upload_list, 'title_id': title_id, 'title_type': title_type}
        result.update(sending_details)
        return result
    else:
        return {'status': False}

@app.task(queue='qualities')
def route_quality_conversion_request(search_result, title_id: int, title_type: int, en_name: str, request_id: int, requested_season: int, requested_quality: str):
    status = search_result['status']
    if status:
        search_result['title_id'] = title_id
        search_result['title_type'] = title_type
        search_result['en_name'] = en_name
        search_result['user_id'] = -1003065180861
        search_result['api_url'] = MOVIEO_TELEGRAM_API
    else:
        files_db = finding_best_quality_for_convert(title_id,requested_quality,requested_season)
        from celery_tasks.tasks.batch_sender import send_batch_message
        if files_db:
            for f in files_db:
                data = {
                    'chat_id': AUTO_SUB_CH,
                    'from_chat_id': ARCHIVE_CHANNEL,
                    'message_id': f[1],
                    'caption': f'Convert Quality,{request_id},{f[0]}',
                }
                send_batch_message.delay(MOVIEO_TELEGRAM_API, 'copyMessage', data)
            search_result['status'] = False
    return search_result

@app.task(queue='qualities')
def resolve_quality_conversion_request(third_step_res, admin_user_id: int, request_id: int, request_type_str: str, requested_season: int, requested_quality: str, title_type: int, title_name: str):
    status = third_step_res['status']
    qu = third_step_res['qu']
    combo_hash = third_step_res['combo_hash']

    if status:
        if len(request_type_str.split('+')) == 2:
            resolve_2_part_request(request_id, request_type_str, qu, combo_hash)
        else:
            chat_id, movieo_id, title_name = log_request(request_id, 2)
            data = {
                'chat_id': chat_id,
                'text': YOUR_REQUEST_ADDED(request_id, title_name, movieo_id)
            }
            send_request(MOVIEO_TELEGRAM_API, 'sendMessage', data)
    else:
        data = {
            'chat_id': admin_user_id,
            'text': SEND_QUALITY_REQUEST_TO_ADMIN(title_type, title_name, request_type_str, requested_quality, requested_season),
            'reply_markup': {
                'inline_keyboard': [
                    [{'text': '📥 دریافت فایل (های) سورس', 'callback_data': f'receive_source_files-{request_id}'}],
                    [{'text': '✅ تایید درخواست', 'callback_data': f'submit_request-{request_id}'}],
                    [{'text': '❌ بستن درخواست', 'callback_data': f'close_request-{request_id}'}],
                ]
            }
        }
        send_request(MOVIEO_TELEGRAM_API, 'sendMessage', data)

@app.task(queue='qualities')
def decrement_counter_and_submit_request(third_step_res, admin_user_id: int, request_id: int, request_type_str: str, requested_season: int, requested_quality: str, title_type: int, title_name: str):
    print(f'\n**********************\n--- considering the possibility of continuing process of submitting the request \n**********************')
    counter_key = f"request:active:{request_id}"
    lock_key = f"request:lock:{request_id}"

    with RedisDatabase() as r:
        remaining = r.decr(counter_key)

        if remaining > 0:
            print(f'\n**********************\n--- {remaining} tasks of request has left! \n**********************')
        elif r.get(lock_key):
            print(f'\n**********************\n--- request already handled. \n**********************')
        else:
            r.set(lock_key, "1")

            return resolve_quality_conversion_request.delay(third_step_res, admin_user_id, request_id, request_type_str, requested_season, requested_quality, title_type, title_name)