# -*- coding: utf-8 -*-
"""
INTERFACE GRÁFICA - ROBÔ DE BALANCEAMENTO
Gerencia o portfólio e exibe informações em tempo real
"""

import tkinter as tk
from tkinter import messagebox, scrolledtext, ttk
import subprocess
import json
import os
import threading
import time
from datetime import datetime
import pytz

class BalanceamentoApp:
    def __init__(self, root):
        self.root = root
        self.root.title("Robô de Balanceamento de Portfólio")
        self.root.geometry("1200x700")
        
        self.balanceamento_process = None
        self.timezone = pytz.timezone("America/Sao_Paulo")
        
        self.config_file = 'configuracoes_balanceamento.json'
        self.estado_file = 'portfolio_estado.json'
        self.log_file = 'log_balanceamento.log'
        
        self.criar_interface()
        self.carregar_configuracoes()
        self.iniciar_atualizar_interface()
    
    def criar_interface(self):
        """Cria os elementos da interface"""
        
        # Frame Principal
        main_frame = ttk.Frame(self.root)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        
        # ====== SECTION: CONTROLES ======
        controle_frame = ttk.LabelFrame(main_frame, text="Controles", padding=10)
        controle_frame.pack(fill=tk.X, padx=0, pady=5)
        
        btn_iniciar = ttk.Button(controle_frame, text="Iniciar Robô", command=self.iniciar_robo)
        btn_iniciar.pack(side=tk.LEFT, padx=5)
        
        btn_parar = ttk.Button(controle_frame, text="Parar Robô", command=self.parar_robo)
        btn_parar.pack(side=tk.LEFT, padx=5)
        
        btn_recarregar = ttk.Button(controle_frame, text="Recarregar Config", command=self.recarregar_config)
        btn_recarregar.pack(side=tk.LEFT, padx=5)
        
        btn_relatorio = ttk.Button(controle_frame, text="Atualizar Relatório", command=self.atualizar_relatorio)
        btn_relatorio.pack(side=tk.LEFT, padx=5)
        
        # ====== SECTION: CONFIGURAÇÃO ======
        config_frame = ttk.LabelFrame(main_frame, text="Configuração", padding=10)
        config_frame.pack(fill=tk.X, padx=0, pady=5)
        
        # Capital Inicial
        ttk.Label(config_frame, text="Capital Inicial ($):").grid(row=0, column=0, sticky=tk.W, padx=5)
        self.capital_var = tk.StringVar()
        ttk.Entry(config_frame, textvariable=self.capital_var, width=15).grid(row=0, column=1, sticky=tk.W, padx=5)
        
        # Variação Balanceamento
        ttk.Label(config_frame, text="Variação Balanceamento (%):").grid(row=0, column=2, sticky=tk.W, padx=5)
        self.variacao_var = tk.StringVar()
        ttk.Entry(config_frame, textvariable=self.variacao_var, width=15).grid(row=0, column=3, sticky=tk.W, padx=5)
        
        # Testnet
        self.testnet_var = tk.BooleanVar()
        ttk.Checkbutton(config_frame, text="Usar Testnet", variable=self.testnet_var).grid(row=0, column=4, padx=5)
        
        btn_salvar_config = ttk.Button(config_frame, text="Salvar Configuração", command=self.salvar_configuracao)
        btn_salvar_config.grid(row=0, column=5, padx=5)
        
        # ====== SECTION: PORTFOLIO ======
        portfolio_frame = ttk.LabelFrame(main_frame, text="Portfólio", padding=10)
        portfolio_frame.pack(fill=tk.BOTH, expand=True, padx=0, pady=5)
        
        # Notebook com abas
        notebook = ttk.Notebook(portfolio_frame)
        notebook.pack(fill=tk.BOTH, expand=True)
        
        # Aba: Moedas
        moedas_tab = ttk.Frame(notebook)
        notebook.add(moedas_tab, text="Moedas")
        
        # Treeview para moedas
        columns = ('Moeda', 'Percentual %', 'Preço Compra', 'Ativa')
        self.moedas_tree = ttk.Treeview(moedas_tab, columns=columns, height=8)
        self.moedas_tree.column('#0', width=0, stretch=tk.NO)
        self.moedas_tree.column('Moeda', anchor=tk.W, width=100)
        self.moedas_tree.column('Percentual %', anchor=tk.CENTER, width=100)
        self.moedas_tree.column('Preço Compra', anchor=tk.CENTER, width=150)
        self.moedas_tree.column('Ativa', anchor=tk.CENTER, width=80)
        
        self.moedas_tree.heading('#0', text='', anchor=tk.W)
        self.moedas_tree.heading('Moeda', text='Moeda', anchor=tk.W)
        self.moedas_tree.heading('Percentual %', text='Percentual %', anchor=tk.CENTER)
        self.moedas_tree.heading('Preço Compra', text='Preço Compra', anchor=tk.CENTER)
        self.moedas_tree.heading('Ativa', text='Ativa', anchor=tk.CENTER)
        
        self.moedas_tree.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        
        # Botões para adicionar/remover moedas
        botoes_moedas = ttk.Frame(moedas_tab)
        botoes_moedas.pack(fill=tk.X, padx=5, pady=5)
        
        ttk.Button(botoes_moedas, text="Adicionar Moeda", command=self.adicionar_moeda).pack(side=tk.LEFT, padx=5)
        ttk.Button(botoes_moedas, text="Remover Moeda", command=self.remover_moeda).pack(side=tk.LEFT, padx=5)
        ttk.Button(botoes_moedas, text="Editar Moeda", command=self.editar_moeda).pack(side=tk.LEFT, padx=5)
        
        # Aba: Status
        status_tab = ttk.Frame(notebook)
        notebook.add(status_tab, text="Status")
        
        # Text widget para status
        self.status_text = scrolledtext.ScrolledText(status_tab, height=15, wrap=tk.WORD)
        self.status_text.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        
        # Aba: Log
        log_tab = ttk.Frame(notebook)
        notebook.add(log_tab, text="Log")
        
        # Text widget para log
        self.log_text = scrolledtext.ScrolledText(log_tab, height=15, wrap=tk.WORD)
        self.log_text.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        
        # Status bar
        self.status_var = tk.StringVar(value="Pronto")
        status_bar = ttk.Label(self.root, textvariable=self.status_var, relief=tk.SUNKEN)
        status_bar.pack(fill=tk.X, side=tk.BOTTOM)
    
    def carregar_configuracoes(self):
        """Carrega configurações do arquivo"""
        try:
            with open(self.config_file, 'r', encoding='utf-8') as f:
                config = json.load(f)
            
            self.capital_var.set(str(config.get('capital_inicial', 1000)))
            self.variacao_var.set(str(config.get('variacao_balanceamento', 2.0)))
            self.testnet_var.set(config.get('testnet', False))
            
            # Carregar moedas
            self.moedas_tree.delete(*self.moedas_tree.get_children())
            for moeda in config.get('portfolio', []):
                self.moedas_tree.insert('', 'end', values=(
                    moeda['moeda'],
                    moeda['percentual'],
                    moeda['preco_compra'],
                    "Sim" if moeda.get('ativa', True) else "Não"
                ))
            
            self.atualizar_status("Configurações carregadas")
        except Exception as e:
            messagebox.showerror("Erro", f"Erro ao carregar configurações: {e}")
    
    def salvar_configuracao(self):
        """Salva a configuração"""
        try:
            with open(self.config_file, 'r', encoding='utf-8') as f:
                config = json.load(f)
            
            config['capital_inicial'] = float(self.capital_var.get())
            config['variacao_balanceamento'] = float(self.variacao_var.get())
            config['testnet'] = self.testnet_var.get()
            
            with open(self.config_file, 'w', encoding='utf-8') as f:
                json.dump(config, f, indent=2, ensure_ascii=False)
            
            messagebox.showinfo("Sucesso", "Configuração salva com sucesso!")
            self.atualizar_status("Configuração salva")
        except Exception as e:
            messagebox.showerror("Erro", f"Erro ao salvar configuração: {e}")
    
    def adicionar_moeda(self):
        """Adiciona uma nova moeda ao portfólio"""
        dialog = tk.Toplevel(self.root)
        dialog.title("Adicionar Moeda")
        dialog.geometry("400x250")
        
        ttk.Label(dialog, text="Moeda:").pack(padx=10, pady=5)
        moeda_entry = ttk.Entry(dialog)
        moeda_entry.pack(padx=10, pady=5, fill=tk.X)
        
        ttk.Label(dialog, text="Percentual (%):").pack(padx=10, pady=5)
        percentual_entry = ttk.Entry(dialog)
        percentual_entry.pack(padx=10, pady=5, fill=tk.X)
        
        ttk.Label(dialog, text="Preço de Compra:").pack(padx=10, pady=5)
        preco_entry = ttk.Entry(dialog)
        preco_entry.pack(padx=10, pady=5, fill=tk.X)
        
        ativa_var = tk.BooleanVar(value=True)
        ttk.Checkbutton(dialog, text="Ativa", variable=ativa_var).pack(padx=10, pady=5)
        
        def salvar():
            try:
                with open(self.config_file, 'r', encoding='utf-8') as f:
                    config = json.load(f)
                
                config['portfolio'].append({
                    'moeda': moeda_entry.get().upper(),
                    'percentual': float(percentual_entry.get()),
                    'preco_compra': float(preco_entry.get()),
                    'ativa': ativa_var.get()
                })
                
                with open(self.config_file, 'w', encoding='utf-8') as f:
                    json.dump(config, f, indent=2, ensure_ascii=False)
                
                self.carregar_configuracoes()
                dialog.destroy()
                messagebox.showinfo("Sucesso", "Moeda adicionada!")
            except Exception as e:
                messagebox.showerror("Erro", f"Erro ao adicionar: {e}")
        
        ttk.Button(dialog, text="Salvar", command=salvar).pack(padx=10, pady=10, fill=tk.X)
    
    def remover_moeda(self):
        """Remove a moeda selecionada"""
        selecionado = self.moedas_tree.selection()
        if not selecionado:
            messagebox.showwarning("Aviso", "Selecione uma moeda para remover")
            return
        
        item = self.moedas_tree.item(selecionado[0])
        moeda = item['values'][0]
        
        if messagebox.askyesno("Confirmar", f"Remover {moeda}?"):
            try:
                with open(self.config_file, 'r', encoding='utf-8') as f:
                    config = json.load(f)
                
                config['portfolio'] = [m for m in config['portfolio'] if m['moeda'] != moeda]
                
                with open(self.config_file, 'w', encoding='utf-8') as f:
                    json.dump(config, f, indent=2, ensure_ascii=False)
                
                self.carregar_configuracoes()
                messagebox.showinfo("Sucesso", "Moeda removida!")
            except Exception as e:
                messagebox.showerror("Erro", f"Erro ao remover: {e}")
    
    def editar_moeda(self):
        """Edita a moeda selecionada"""
        selecionado = self.moedas_tree.selection()
        if not selecionado:
            messagebox.showwarning("Aviso", "Selecione uma moeda para editar")
            return
        
        item = self.moedas_tree.item(selecionado[0])
        moeda = item['values'][0]
        percentual = item['values'][1]
        preco = item['values'][2]
        
        dialog = tk.Toplevel(self.root)
        dialog.title(f"Editar {moeda}")
        dialog.geometry("400x200")
        
        ttk.Label(dialog, text=f"Moeda: {moeda}").pack(padx=10, pady=5)
        
        ttk.Label(dialog, text="Percentual (%):").pack(padx=10, pady=5)
        percentual_entry = ttk.Entry(dialog)
        percentual_entry.insert(0, str(percentual))
        percentual_entry.pack(padx=10, pady=5, fill=tk.X)
        
        ttk.Label(dialog, text="Preço de Compra:").pack(padx=10, pady=5)
        preco_entry = ttk.Entry(dialog)
        preco_entry.insert(0, str(preco))
        preco_entry.pack(padx=10, pady=5, fill=tk.X)
        
        def salvar():
            try:
                with open(self.config_file, 'r', encoding='utf-8') as f:
                    config = json.load(f)
                
                for m in config['portfolio']:
                    if m['moeda'] == moeda:
                        m['percentual'] = float(percentual_entry.get())
                        m['preco_compra'] = float(preco_entry.get())
                        break
                
                with open(self.config_file, 'w', encoding='utf-8') as f:
                    json.dump(config, f, indent=2, ensure_ascii=False)
                
                self.carregar_configuracoes()
                dialog.destroy()
                messagebox.showinfo("Sucesso", "Moeda atualizada!")
            except Exception as e:
                messagebox.showerror("Erro", f"Erro ao editar: {e}")
        
        ttk.Button(dialog, text="Salvar", command=salvar).pack(padx=10, pady=10, fill=tk.X)
    
    def iniciar_robo(self):
        """Inicia o robô"""
        if self.balanceamento_process is None:
            self.balanceamento_process = subprocess.Popen(["python", "robo_balanceamento.py"])
            messagebox.showinfo("Sucesso", "Robô iniciado!")
            self.atualizar_status("Robô em execução")
        else:
            messagebox.showwarning("Aviso", "Robô já está em execução")
    
    def parar_robo(self):
        """Para o robô"""
        if self.balanceamento_process is not None:
            self.balanceamento_process.terminate()
            self.balanceamento_process = None
            messagebox.showinfo("Sucesso", "Robô parado!")
            self.atualizar_status("Robô parado")
        else:
            messagebox.showwarning("Aviso", "Robô não está em execução")
    
    def recarregar_config(self):
        """Recarrega as configurações"""
        self.carregar_configuracoes()
        messagebox.showinfo("Sucesso", "Configurações recarregadas!")
    
    def atualizar_relatorio(self):
        """Atualiza o relatório do portfólio"""
        try:
            if os.path.exists(self.estado_file):
                with open(self.estado_file, 'r', encoding='utf-8') as f:
                    estado = json.load(f)
                
                info = f"""
ESTADO DO PORTFÓLIO
{"=" * 50}
Fase: {estado.get('fase', 'N/A').upper()}
Data de Início: {estado.get('data_inicio', 'N/A')}
Capital Inicial: {estado.get('capital_inicial', 'N/A')}

Moedas Compradas: {', '.join(estado.get('moedas_compradas', []))}
Moedas Pendentes: {', '.join(estado.get('moedas_pendentes', []))}

Percentuais Alvo: {estado.get('percentuais_alvo', {})}
Preços de Compra: {estado.get('precos_compra', {})}

Total de Trades: {len(estado.get('historico_trades', []))}
"""
                
                self.status_text.delete(1.0, tk.END)
                self.status_text.insert(tk.END, info)
                self.atualizar_status("Relatório atualizado")
            else:
                self.status_text.delete(1.0, tk.END)
                self.status_text.insert(tk.END, "Portfólio não inicializado ainda")
        except Exception as e:
            messagebox.showerror("Erro", f"Erro ao atualizar relatório: {e}")
    
    def atualizar_status(self, mensagem):
        """Atualiza a barra de status"""
        timestamp = datetime.now(self.timezone).strftime("%H:%M:%S")
        self.status_var.set(f"[{timestamp}] {mensagem}")
    
    def iniciar_atualizar_interface(self):
        """Atualiza a interface periodicamente"""
        def atualizar():
            try:
                if os.path.exists(self.log_file):
                    with open(self.log_file, 'r', encoding='utf-8') as f:
                        log_content = f.read()
                    
                    self.log_text.delete(1.0, tk.END)
                    self.log_text.insert(tk.END, log_content)
                    self.log_text.see(tk.END)
            except Exception:
                pass
            
            self.root.after(2000, atualizar)
        
        atualizar()

def main():
    root = tk.Tk()
    app = BalanceamentoApp(root)
    root.mainloop()

if __name__ == "__main__":
    main()
