import serial
import pandas as pd
import plotly.graph_objects as go
from dash import Dash, dcc, html
from dash.dependencies import Input, Output
import threading
import time
import os

# Configurações da Porta Serial (Ajuste conforme necessário)
SERIAL_PORT = '/dev/ttyACM0'  # No Windows seria 'COM3', etc.
BAUD_RATE = 9600
CSV_FILENAME = 'dados_resfriamento.csv'

# Inicializa o CSV com cabeçalho se não existir
if not os.path.exists(CSV_FILENAME):
    with open(CSV_FILENAME, 'w') as f:
        f.write("Tempo(min),Temperatura(C)\n")

# Variável global para armazenar dados em memória
data_buffer = []

def serial_reader():
    """Thread para ler dados da serial e salvar no CSV"""
    global data_buffer
    try:
        ser = serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=1)
        print(f"Conectado à porta {SERIAL_PORT}...")
        
        while True:
            if ser.in_waiting > 0:
                line = ser.readline().decode('utf-8').strip()
                if ',' in line:
                    try:
                        # Salva no arquivo CSV
                        with open(CSV_FILENAME, 'a') as f:
                            f.write(line + '\n')
                        
                        # Atualiza buffer interno
                        parts = line.split(',')
                        data_buffer.append({
                            'Tempo': float(parts[0]),
                            'Temperatura': float(parts[1])
                        })
                        print(f"Recebido: {line}")
                    except ValueError:
                        pass
            time.sleep(0.1)
    except Exception as e:
        print(f"\n[ERRO] Não foi possível conectar à porta {SERIAL_PORT}.")
        print(f"Detalhes: {e}")
        if "Permission denied" in str(e):
            print(f"\n>>> DICA: Tente liberar a permissão da porta com o comando:")
            print(f"    sudo chmod 666 {SERIAL_PORT}\n")
        elif "No such file or directory" in str(e):
            print(f"\n>>> DICA: Verifique se o Arduino está conectado corretamente.")
            print(f"    Use 'ls /dev/ttyACM*' para confirmar a porta.\n")

# Inicia a thread de leitura serial
thread = threading.Thread(target=serial_reader, daemon=True)
thread.start()

# Configuração da Aplicação Dash (Plotly Interativo)
app = Dash(__name__)

app.layout = html.Div(style={'backgroundColor': '#0f172a', 'color': '#f1f5f9', 'padding': '20px', 'fontFamily': 'Inter'}, children=[
    html.H1("Monitoramento em Tempo Real - Lei de Newton", style={'textAlign': 'center', 'color': '#38bdf8'}),
    html.P("MNPEF - Aula 08: Investigando o Resfriamento", style={'textAlign': 'center', 'color': '#64748b'}),
    
    dcc.Graph(id='live-graph', animate=False),
    
    dcc.Interval(
        id='graph-update',
        interval=2000, # Atualiza o gráfico a cada 2 segundos
        n_intervals=0
    ),
    
    html.Div(style={'textAlign': 'center', 'marginTop': '20px'}, children=[
        html.A("📥 Baixar Planilha CSV", href=f"/{CSV_FILENAME}", target="_blank", 
               style={'backgroundColor': '#1e293b', 'color': '#f1f5f9', 'padding': '10px 20px', 'borderRadius': '8px', 'textDecoration': 'none', 'border': '1px solid #334155'})
    ])
])

@app.callback(Output('live-graph', 'figure'),
              [Input('graph-update', 'n_intervals')])
def update_graph_scatter(n):
    if not data_buffer:
        return go.Figure()

    df = pd.DataFrame(data_buffer)
    
    fig = go.Figure()
    fig.add_trace(go.Scatter(
        x=df['Tempo'],
        y=df['Temperatura'],
        mode='lines+markers',
        line=dict(color='#0ea5e9', width=3),
        marker=dict(size=6, color='#f97316'),
        name='Temperatura (°C)'
    ))

    fig.update_layout(
        title='Curva de Resfriamento de Newton',
        xaxis_title='Tempo (minutos)',
        yaxis_title='Temperatura (°C)',
        template='plotly_dark',
        paper_bgcolor='#0f172a',
        plot_bgcolor='#1e293b',
        hovermode='x unified',
        xaxis=dict(showgrid=True, gridcolor='#334155'),
        yaxis=dict(showgrid=True, gridcolor='#334155')
    )
    
    return fig

if __name__ == '__main__':
    print("Iniciando servidor de visualização...")
    print("Acesse http://127.0.0.1:8050 no seu navegador.")
    app.run_server(debug=False, port=8050)
