import aiohttp
import os
import asyncio
import json
import ssl

class TurboviplayAPI:
    def __init__(self, api_key):
        self.api_key = api_key
        self.base_url = "https://api.turboviplay.com"
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
        }

    async def validate_key(self):
        url = f"{self.base_url}/uploadserver?keyApi={self.api_key}"
        try:
            async with aiohttp.ClientSession(headers=self.headers, connector=aiohttp.TCPConnector(ssl=False)) as session:
                async with session.get(url, ssl=False) as response:
                    text_response = await response.text()
                    try:
                        data = json.loads(text_response)
                    except json.JSONDecodeError:
                        return False, f"Server returned HTML: {text_response[:100]}"
                    
                    # SAFETY CHECK: Ensure data is a dictionary
                    if not isinstance(data, dict):
                        return False, f"Server returned unexpected format: {str(data)[:100]}"

                    if data.get('status') == 200 or data.get('msg') == 'ok':
                        return True, "Valid"
                        
                    return False, f"API Error: {text_response[:100]}"
        except Exception as e:
            return False, f"Connection Error: {str(e)}"

    async def get_upload_server(self):
        url = f"{self.base_url}/uploadserver?keyApi={self.api_key}"
        async with aiohttp.ClientSession(headers=self.headers, connector=aiohttp.TCPConnector(ssl=False)) as session:
            async with session.get(url, ssl=False) as response:
                try:
                    data = await response.json(content_type=None)
                    
                    # SAFETY CHECK
                    if not isinstance(data, dict):
                        return None, f"Server returned non-dict JSON: {str(data)[:100]}"

                    if response.status == 200 and data.get('msg') == 'ok':
                        return data.get('result'), None
                    return None, f"API Error: {data}"
                except Exception as e:
                    text = await response.text()
                    return None, f"Failed to get server: {text[:100]}"

    async def upload_file(self, file_path, upload_url, progress_callback=None):
        file_name = os.path.basename(file_path)
        file_size = os.path.getsize(file_path)
        
        try:
            with open(file_path, 'rb') as f:
                async with aiohttp.ClientSession(headers=self.headers, connector=aiohttp.TCPConnector(ssl=False)) as session:
                    data = aiohttp.FormData()
                    data.add_field('keyapi', self.api_key)
                    
                    async def file_sender(file_object, callback, total_size):
                        chunk_size = 64 * 1024
                        bytes_read = 0
                        while True:
                            chunk = file_object.read(chunk_size)
                            if not chunk:
                                break
                            bytes_read += len(chunk)
                            if callback:
                                try:
                                    await callback(bytes_read, total_size)
                                except:
                                    pass
                            yield chunk

                    data.add_field('file', 
                                   file_sender(f, progress_callback, file_size),
                                   filename=file_name)
                    data.add_field('folder_id', 'single videos')

                    timeout = aiohttp.ClientTimeout(total=3600) 
                    
                    async with session.post(upload_url, data=data, timeout=timeout, ssl=False) as response:
                        try:
                            res_text = await response.text()
                            parsed = json.loads(res_text)
                            return parsed
                        except:
                            return {"status": 0, "msg": f"Upload raw response: {res_text[:100]}"}
        except Exception as e:
            return {"status": 0, "msg": str(e)}