import os
import json
import time
from datetime import datetime
#from bs4 import BeautifulSoup
import requests
import lzma


urlKey = "BB3_d7m1ne4AWwzKUey6X"


def get_lista_ativos():
    html_txt = get_url_content(f"https://opcoes.oplab.com.br/mercado/_next/data/{urlKey}/pt-br/acoes/opcoes/{'PETR4'}.json")
    data = json.loads(html_txt)
    # 1. Acessa a lista de dicionários dentro de 'pageProps' -> 'assets'
    assets_list = data['pageProps']['assets']
    # 2. Usa uma list comprehension para extrair apenas o 'symbol' de cada dicionário
    symbol_list = [asset['symbol'] for asset in assets_list]
    # 3. Usa a função sorted() para ordenar a lista alfabeticamente
    sorted_symbols = sorted(symbol_list)
    return sorted_symbols


def get_url_content(url):
    response = requests.get(url)
    response.raise_for_status()
    return response.text


def process_page(url, nome):
    print(f"Processing: {url} | Ativo: {nome}")
    try:
        html_txt = get_url_content(url)
        data = json.loads(html_txt)
        # 1. Acessamos o dicionário aninhado 'pageProps' para facilitar
        page_props = data['pageProps']
        # 2. Verificamos se a chave 'assets' existe e, se sim, a removemos
        if 'assets' in page_props:
            del page_props['assets']
            print("A chave 'assets' foi removida com sucesso.")
        else:
            # Esta mensagem será exibida, pois 'filteredOptions' não está no seu exemplo
            print("A chave 'assets' não foi encontrada para remover.")
        # 3. Verificamos se a chave 'filteredOptions' existe e, se sim, a removemos
        if 'filteredOptions' in page_props:
            del page_props['filteredOptions']
            print("A chave 'filteredOptions' foi removida com sucesso.")
        else:
            # Esta mensagem será exibida, pois 'filteredOptions' não está no seu exemplo
            print("A chave 'filteredOptions' não foi encontrada para remover.")
        # 4. Imprimimos a estrutura final do dicionário para confirmar a remoção
        return json.dumps(data)
    except Exception as e:
        print(f"Error processing page for {nome}: {e}")
    return None


def format_bytes(size: int) -> str:
    """Formata um tamanho em bytes para uma string legível (KB, MB, GB)."""
    if size < 1024:
        return f"{size} B"
    elif size < 1024**2:
        return f"{size / 1024:.2f} KB"
    elif size < 1024**3:
        return f"{size / 1024**2:.2f} MB"
    else:
        return f"{size / 1024**3:.2f} GB"

def save_to_local(file_content: str, data: str, file_name: str, compress: bool = False):
    """
    Salva conteúdo em um arquivo local, com a opção de compressão LZMA2.
    Se a compressão for usada, calcula e exibe a taxa de compressão.

    Args:
        file_content (str): O conteúdo de texto a ser salvo.
        data (str): O nome da subpasta (geralmente uma data/hora).
        file_name (str): O nome base do arquivo (sem extensão).
        compress (bool): Se True, salva o arquivo em formato .json.xz. 
                         Se False (padrão), salva como .json.
    """
    folder = f"oplaboptions/{data}"
    os.makedirs(folder, exist_ok=True)
    # Calcula o tamanho original do conteúdo em bytes
    original_size_bytes = len(file_content.encode('utf-8'))
    if compress:
        file_path = os.path.join(folder, f"{file_name}.json.xz")
        with lzma.open(file_path, "wt", encoding="utf-8") as f:
            f.write(file_content)
        # Após salvar, obtém o tamanho do arquivo compactado
        compressed_size_bytes = os.path.getsize(file_path)
        print(f"Compressed file saved: {file_path}")
        # Calcula e exibe a taxa de compressão
        if original_size_bytes > 0:
            compression_ratio = compressed_size_bytes / original_size_bytes
            print(
                f"  -> Original: {format_bytes(original_size_bytes)} | "
                f"Compressed: {format_bytes(compressed_size_bytes)}"
            )
            print(
                f"  -> Compression Ratio: {compression_ratio:.2%} "
                f"(Saved {1 - compression_ratio:.2%})"
            )
        else:
            print("  -> Original content was empty. No compression ratio to calculate.")
    else: # Comportamento sem compressão
        file_path = os.path.join(folder, f"{file_name}.json")
        
        with open(file_path, "w", encoding="utf-8") as f:
            f.write(file_content)
            
        final_size_bytes = os.path.getsize(file_path)
        print(f"File saved: {file_path} ({format_bytes(final_size_bytes)})")


def main():
    start_time = time.time()
    lista_ativos = get_lista_ativos()
    data = datetime.now().strftime("%Y_%m_%d__%H_%M")
    #for i, ativo in enumerate(lista_ativos[0:5]):
    #for i, ativo in enumerate(lista_ativos[0:2]):
    for i, ativo in enumerate(lista_ativos):
        url = f"https://opcoes.oplab.com.br/mercado/_next/data/{urlKey}/pt-br/acoes/opcoes/{ativo}.json"
        file_content = process_page(url, ativo)
        if file_content:
            save_to_local(file_content, data, ativo, True)
        print(f"Progress: {i + 1}/{len(lista_ativos)}")
    end_time = time.time()
    print(f"Elapsed time: {end_time - start_time:.2f} seconds")


if __name__ == "__main__":
    main()