import sys
import os
import json
import requests
import traceback
import urllib3
from dotenv import load_dotenv
from datetime import datetime

# Desabilita avisos de certificados inseguros (opcional, conforme seu código original)
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
load_dotenv()

class Heartbeat():
    """Destinada a enviar atualizações via API para o painel de bots."""
    def __init__(self, bot_id, base_endpoint=None, token=None):
        
        self.bot_id = bot_id
        self.base_endpoint = base_endpoint or os.getenv('CYBERTRON_API_URL')
        self.token = token or os.getenv('CYBERTRON_API_TOKEN')

        if not self.base_endpoint:
            raise ValueError('❌ URL da API não configurada! Defina CYBERTRON_API_URL no .env')
        
        if not self.token:
            raise ValueError('⚠️ AVISO: CYBERTRON_API_TOKEN não encontrado no .env! As requisições podem falhar.')

        self.headers = {
            'Authorization': f'Token {self.token}'
        }

    def _post(self, endpoint, payload):
        """Método privado para centralizar a lógica de POST"""

        full_url = f"{self.base_endpoint.rstrip('/')}/{endpoint.lstrip('/')}"

        try:
            req = requests.post(full_url, json=payload, headers=self.headers, timeout=10)
            req.raise_for_status()
            print(f"✅ Sucesso [{endpoint}]: {req.status_code}")
            return req
        except requests.exceptions.RequestException as e:
            print(f"❌ Erro ao conectar em {endpoint}: {e}")
            print(req.text)
            return None
        
    def _put(self, endpoint, payload):
        """Método privado para centralizar a lógica de PUT"""

        full_url = f"{self.base_endpoint.rstrip('/')}/{endpoint.lstrip('/')}"

        try:
            req = requests.put(full_url, json=payload, headers=self.headers, timeout=10)
            req.raise_for_status()
            print(f"✅ Sucesso [{endpoint}]: {req.status_code}")
            return req
        except requests.exceptions.RequestException as e:
            print(f"❌ Erro ao conectar em {endpoint}: {e}")
            print(req.text)
            return None
        
        
    def _patch(self, endpoint, payload):
        """Método privado para centralizar a lógica de PATCH"""

        full_url = f"{self.base_endpoint.rstrip('/')}/{endpoint.lstrip('/')}"

        try:
            req = requests.patch(full_url, json=payload, headers=self.headers, timeout=10)
            req.raise_for_status()
            print(f"✅ Sucesso [{endpoint}]: {req.status_code}")
            return req
        except requests.exceptions.RequestException as e:
            print(f"❌ Erro ao conectar em {endpoint}: {e}")
            print(req.text)
            return None

    def _capture(self, exception):
        """
        Captura a exceção, extrai os detalhes técnicos e salva no banco.
        """
        try:
            exc_type, exc_value, exc_traceback = sys.exc_info()

            tipo_erro = exc_type.__name__
        
            mensagem = str(exc_value)
            
            stack = traceback.extract_tb(exc_traceback)
            last_frame = stack[-1]
            codigo_quebrou = last_frame.line

            tb_last_frame = traceback.extract_tb(exc_traceback)[-1]
            linha = tb_last_frame.lineno
        except Exception as e:
            raise ValueError('❌ Erro para capturar os dados da exceção.')

        return {
            'tipo_erro': tipo_erro,
            'mensagem': mensagem,
            'linha': linha,
            'traceback': codigo_quebrou
        }
        
    def registrar_ticket(self, ticket_id, pedido=None, protocolo=None, output_data=None):
        endpoint = '/transformers/bots-tickets/'

        payload = {
        'bot_id': self.bot_id,
        'created_at': datetime.now().isoformat(),
        'ticket_id': ticket_id,
        'pedido': pedido,
        'protocolo': protocolo,
        'output_data': output_data
        }
    
        self._post(endpoint, payload)

    def atualizar_fila(self, quantidade):
        endpoint = '/transformers/bots-queue/'

        payload = {
        'bot_id': self.bot_id,
        'quantidade': quantidade,
        'created_at': datetime.now().isoformat(),
        }
    
        self._post(endpoint, payload)

    def atualizar_computador(self, computador, cpu, memory, disk):
        endpoint = f'/transformers/bots-computer/{computador}/'

        payload = {
        'comp_id': computador,
        'cpu': cpu,
        'memory': memory,
        'disk': disk,
        'updated_at': datetime.now().isoformat(),
        }
    
        self._put(endpoint, payload)

    def atualizar_status(self, status):
        endpoint = '/transformers/bots-status/'

        payload = {
        'bot_id': self.bot_id,
        'updated_at': datetime.now().isoformat(),
        'current_status': status
        }
    
        self._post(endpoint, payload)

    def registrar_erro(self, exception, ticket_id=None, tipo_alerta='WARNING'):
        endpoint = '/transformers/bots-logs/'

        error_data = self._capture(exception)

        tipo_erro = error_data.get('tipo_erro')
        mensagem = error_data.get('mensagem')
        linha = error_data.get('linha')
        traceback = error_data.get('traceback')

        payload = {
        'codigo_erro': tipo_erro,
        'descricao': mensagem,
        'data_log': datetime.now().isoformat(),
        'bot_id': self.bot_id,
        'resolvido': False,
        'tipo_alerta': tipo_alerta,
        'linha': linha,
        'traceback': traceback,
        'ticket_id': ticket_id
        }
    
        self._post(endpoint, payload)

    def atualizar_liberarfrete(self, pedido):
        endpoint = f'/transformers/bots-liberarfrete/{pedido}/'

        payload = {
        'bot_realizado': True,
        'data_liberacao': datetime.now().isoformat()
        }
    
        self._patch(endpoint, payload) 