import os
import requests
import json
import gzip
import time
import subprocess

BASE_API = "https://api.sync.so"
S3_BUCKET = "https://prod-public-sync-user-assets.s3.us-east-1.amazonaws.com"

def leer_respuesta(response):
    """Lee la respuesta, descomprime si es gzip."""
    content = response.content
    if response.headers.get('Content-Encoding') == 'gzip':
        try:
            return gzip.decompress(content).decode('utf-8')
        except Exception as e:
            print(f"Error descomprimiendo gzip: {e}")
            return content.decode('utf-8', errors='ignore')
    try:
        return content.decode('utf-8')
    except:
        return content.decode('latin1', errors='ignore')

def obtener_url_carga(nombre_archivo, content_type="video/mp4"):
    """Obtiene la URL para cargar el video directamente a S3."""
    session_token = os.environ.get("ACCESS_TOKEN")
    headers = {
        "Host": "api.sync.so",
        "Connection": "keep-alive",
        "sec-ch-ua-platform": '"Windows"',
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
        "sec-ch-ua": '"Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"',
        "x-sync-source": "web",
        "sec-ch-ua-mobile": "?0",
        "Accept": "*/*",
        "Origin": "https://sync.so",
        "Sec-Fetch-Site": "same-site",
        "Sec-Fetch-Mode": "cors",
        "Sec-Fetch-Dest": "empty",
        "Referer": "https://sync.so/",
        "Accept-Language": "es-ES,es;q=0.9",
        "Accept-Encoding": "gzip, deflate",
        "Cookie": f"__Secure-sync.session_token={session_token}"
    }

    input_data = {
        "json": {
            "fileName": nombre_archivo,
            "contentType": content_type,
            "isPublic": True
        }
    }
    url = f"{BASE_API}/trpc/fileStorage.getUploadUrl?input={requests.utils.quote(json.dumps(input_data))}"

    print("📤 Solicitando URL de carga...")
    response = requests.get(url, headers=headers)

    if response.status_code != 200:
        raise Exception(f"Error {response.status_code}: {response.text}")

    content = leer_respuesta(response)
    data = json.loads(content)

    upload_url = data["result"]["data"]["json"]["uploadUrl"]
    public_url = data["result"]["data"]["json"]["publicUrl"].strip()

    print("✅ URL de carga obtenida.")
    return upload_url, public_url

def subir_video_a_s3(upload_url, archivo_path):
    """Sube el video al bucket S3 usando la URL presignada."""
    with open(archivo_path, 'rb') as f:
        contenido = f.read()

    headers = {
        "Content-Type": "video/mp4",
        "Content-Length": str(len(contenido))
    }

    print("📤 Subiendo video a S3...")
    response = requests.put(upload_url, data=contenido, headers=headers)

    if response.status_code != 200:
        raise Exception(f"Error en PUT: {response.status_code}, {response.text}")

    etag = response.headers.get('ETag', '').strip('"')
    print("✅ Video subido a S3.")
    return etag

def crear_recurso(public_url, project_id="a449159c-7efa-4db6-8100-a408db68a538", nombre_video=None):
    """Crea el recurso de tipo VIDEO."""
    session_token = os.environ.get("ACCESS_TOKEN")
    headers = {
        "Host": "api.sync.so",
        "Connection": "keep-alive",
        "sec-ch-ua-platform": '"Windows"',
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
        "sec-ch-ua": '"Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"',
        "trpc-accept": "application/jsonl",
        "content-type": "application/json",
        "x-sync-source": "web",
        "sec-ch-ua-mobile": "?0",
        "Accept": "*/*",
        "Origin": "https://sync.so",
        "Sec-Fetch-Site": "same-site",
        "Sec-Fetch-Mode": "cors",
        "Sec-Fetch-Dest": "empty",
        "Referer": "https://sync.so/",
        "Accept-Language": "es-ES,es;q=0.9",
        "Accept-Encoding": "gzip, deflate",
        "Cookie": f"__Secure-sync.session_token={session_token}"
    }

    if nombre_video is None:
        nombre_video = os.path.basename(public_url).split('?')[0]

    data = {
        "0": {
            "json": {
                "visibility": "USER",
                "projectId": project_id,
                "url": public_url.strip(),
                "type": "VIDEO",
                "name": nombre_video
            }
        }
    }

    url = f"{BASE_API}/trpc/assets.create?batch=1"
    print("🎨 Creando recurso de video...")
    response = requests.post(url, headers=headers, json=data)

    if response.status_code != 200:
        raise Exception(f"Error {response.status_code}: {response.text}")

    content = leer_respuesta(response)
    for line in content.split('\n'):
        line = line.strip()
        if not line:
            continue
        try:
            j = json.loads(line)
            if isinstance(j, dict) and 'json' in j:
                json_data = j['json']
                if isinstance(json_data, list) and len(json_data) >= 3 and json_data[0] == 2:
                    payload = json_data[2]
                    if isinstance(payload, list) and len(payload) > 0:
                        inner = payload[0]
                        if isinstance(inner, list) and len(inner) > 0:
                            obj = inner[0]
                            if isinstance(obj, dict) and 'id' in obj:
                                asset_id = obj['id']
                                print("✅ Recurso de video creado.")
                                return asset_id
        except Exception as e:
            print(f"⚠️ Error al parsear línea: {e}")
            continue

    raise Exception("No se creó el recurso de video.")

def obtener_recurso(asset_id):
    """Obtiene el recurso creado."""
    session_token = os.environ.get("ACCESS_TOKEN")
    headers = {
        "Host": "api.sync.so",
        "Connection": "keep-alive",
        "sec-ch-ua-platform": '"Windows"',
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
        "sec-ch-ua": '"Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"',
        "trpc-accept": "application/jsonl",
        "content-type": "application/json",
        "x-sync-source": "web",
        "sec-ch-ua-mobile": "?0",
        "Accept": "*/*",
        "Origin": "https://sync.so",
        "Sec-Fetch-Site": "same-site",
        "Sec-Fetch-Mode": "cors",
        "Sec-Fetch-Dest": "empty",
        "Referer": "https://sync.so/",
        "Accept-Language": "es-ES,es;q=0.9",
        "Accept-Encoding": "gzip, deflate",
        "Cookie": f"__Secure-sync.session_token={session_token}"
    }

    input_data = json.dumps({"0": {"json": {"id": asset_id}}})
    query = f"?batch=1&input={requests.utils.quote(input_data)}"
    url = f"{BASE_API}/trpc/assets.get{query}"

    print("🔍 Obteniendo recurso de video...")
    response = requests.get(url, headers=headers)

    if response.status_code != 200:
        raise Exception(f"Error {response.status_code}: {response.text}")

    content = leer_respuesta(response)
    for line in content.split('\n'):
        line = line.strip()
        if not line:
            continue
        try:
            j = json.loads(line)
            if isinstance(j, dict) and 'json' in j:
                json_data = j['json']
                if isinstance(json_data, list) and len(json_data) >= 3 and json_data[0] == 2:
                    payload = json_data[2]
                    if isinstance(payload, list) and len(payload) > 0:
                        inner = payload[0]
                        if isinstance(inner, list) and len(inner) > 0:
                            obj = inner[0]
                            if isinstance(obj, dict) and 'id' in obj and obj['id'] == asset_id:
                                print("✅ Recurso obtenido.")
                                return obj
        except Exception as e:
            print(f"⚠️ Error al parsear línea: {e}")
            continue

    raise Exception("No se encontró el recurso solicitado.")

# === FUNCIÓN PRINCIPAL PARA VIDEO ===
def subir_video_a_sync_so(ruta_video, project_id="a449159c-7efa-4db6-8100-a408db68a538", nombre_video=None):
    """
    Sube un archivo de video a sync.so usando el nuevo flujo.
    """
    if not os.path.exists(ruta_video):
        raise FileNotFoundError(f"Archivo no encontrado: {ruta_video}")

    nombre_archivo = os.path.basename(ruta_video)

    try:
        upload_url, public_url = obtener_url_carga(nombre_archivo, "video/mp4")
        etag = subir_video_a_s3(upload_url, ruta_video)
        asset_id = crear_recurso(public_url, project_id, nombre_video or nombre_archivo)
        info = obtener_recurso(asset_id)

        return info['id'], info['name'], info['url']

    except Exception as e:
        print(f"❌ Error: {str(e)}")
        return None

# === FUNCIONES AUXILIARES ===
def agregar_franja_negra(video_entrada, video_salida):
    """Agrega una franja negra de 70 píxeles en la parte superior del video."""
    if not os.path.exists(video_entrada):
        print(f"⚠️ El archivo no existe.")
        return

    comando = [
        "ffmpeg",
        "-y",
        "-i", video_entrada,
        "-vf", "pad=iw:ih+70:0:70:black",
        "-c:a", "copy",
        video_salida
    ]

    try:
        subprocess.run(comando, check=True, stderr=subprocess.STDOUT)
        print(f"✅ Franja negra agregada: {video_salida}")
    except subprocess.CalledProcessError as e:
        print(f"⚠️ Error al procesar el video:\n{e.output.decode()}")

def recortar_franja_negra(video_entrada, video_salida):
    """Recorta una franja negra de 70 píxeles en la parte superior del video."""
    if not os.path.exists(video_entrada):
        print(f"⚠️ El archivo no existe.")
        return

    comando = [
        "ffmpeg",
        "-y",
        "-i", video_entrada,
        "-vf", "crop=iw:ih-70:0:70",
        "-c:a", "copy",
        video_salida
    ]

    try:
        subprocess.run(comando, check=True, stderr=subprocess.STDOUT)
        print(f"✅ Franja negra recortada: {video_salida}")
    except subprocess.CalledProcessError as e:
        print(f"⚠️ Error al procesar el video:\n{e.output.decode()}")

# === FUNCIÓN DE USO ===
def up_video(VIDEO_PATH):
    print("VIDEO_PATH", VIDEO_PATH)
    # Asegúrate de que el archivo exista
    if not os.path.exists(VIDEO_PATH):
        raise FileNotFoundError(f"Archivo no encontrado: {VIDEO_PATH}")

    # Agregar franja negra si es necesario
    video_con_franja = "/tmp/video_f.mp4"
    agregar_franja_negra(VIDEO_PATH, video_con_franja)

    # Subir el video
    project_id = os.environ.get("PROJECT_ID")
    asset_id_video, info_name_video, info_url_video = subir_video_a_sync_so(video_con_franja, project_id)

    if asset_id_video:
        print("✅ Video subido exitosamente!")
        os.environ["ASSET_ID_VIDEO"] = asset_id_video
        os.environ["INFO_NAME_VIDEO"] = info_name_video
        os.environ["INFO_URL_VIDEO"] = info_url_video