import pandas as pd
import numpy as np
import json
from pathlib import Path
from scipy.signal import savgol_filter

# --- CONFIGURAÇÕES DE CAMINHOS ---
BASE_DIR = Path(__file__).parent / "Gateados 2025"
PASTA_AMOSTRAS = BASE_DIR / "Amostra"
ARQUIVO_EXCEL = BASE_DIR / "BAGUETAS GATEADOS  densidade.xlsx"
OUTPUT_EXCEL = BASE_DIR / "test_sav_gol_DB_estimada.xlsx"

def extrair_dados_resistencia(caminho_arquivo):
    """Extrai a RP bruta e a RP filtrada via Savitzky-Golay."""
    try:
        with open(caminho_arquivo, 'r', encoding='utf-8') as f:
            dados = json.load(f)

        drill = np.array(dados['profile']['drill'])

        # 1. Média do sinal bruto (sem filtro)
        rp_bruta = np.mean(drill)

        # 2. Média do sinal filtrado (SG: janela 31, ordem 3)
        drill_filtrado = savgol_filter(drill, window_length=31, polyorder=3)
        rp_filtrada = np.mean(drill_filtrado)

        return rp_bruta, rp_filtrada
    except Exception:
        return None, None

# 1. Carregar e Limpar Dados de Laboratório
print("Lendo dados de laboratório...")
abas = pd.read_excel(ARQUIVO_EXCEL, sheet_name=None)
df_lab = pd.concat(abas.values(), ignore_index=True)

df_lab = df_lab.loc[:, ~df_lab.columns.str.contains('^Unnamed')]
df_lab['ME.Bas'] = pd.to_numeric(df_lab['ME.Bas'], errors='coerce')
df_lab['Registro'] = pd.to_numeric(df_lab['Registro'], errors='coerce')
df_lab = df_lab.dropna(subset=['ME.Bas', 'Registro'])

# 2. Processar arquivos .rgp
print("Processando arquivos .rgp (Bruto vs SG)...")
lista_bruta = []
lista_sg = []

for reg in df_lab['Registro']:
    nome_arq = f"Measurement{str(int(reg)).zfill(3)}.rgp"
    caminho = PASTA_AMOSTRAS / nome_arq

    if caminho.exists():
        bruta, sg = extrair_dados_resistencia(caminho)
        lista_bruta.append(bruta)
        lista_sg.append(sg)
    else:
        lista_bruta.append(None)
        lista_sg.append(None)

df_lab['RP_Bruta'] = lista_bruta
df_lab['RP_SG'] = lista_sg

# Remove amostras onde o arquivo .rgp não foi encontrado
df_final = df_lab.dropna(subset=['RP_Bruta', 'RP_SG']).copy()

# 3. MATEMÁTICA E COMPARAÇÃO
def calcular_estimativa(df, col_x, col_y):
    x = df[col_x].values
    y = df[col_y].values
    m, c = np.polyfit(x, y, 1)
    estimada = (m * x) + c
    erro = np.abs(y - estimada)
    return estimada, m, c, erro.mean()

# Processamento para o cenário BRUTO
estimada_bruta, m_b, c_b, erro_b = calcular_estimativa(df_final, 'RP_Bruta', 'ME.Bas')
df_final['DB_Est_Bruta'] = estimada_bruta
df_final['Erro_Bruto'] = np.abs(df_final['ME.Bas'] - estimada_bruta)

# Processamento para o cenário SAVITZKY-GOLAY
estimada_sg, m_s, c_s, erro_s = calcular_estimativa(df_final, 'RP_SG', 'ME.Bas')
df_final['DB_Est_SG'] = estimada_sg
df_final['Erro_SG'] = np.abs(df_final['ME.Bas'] - estimada_sg)

# 4. Salvar Resultados
df_final.to_excel(OUTPUT_EXCEL, index=False)

# --- RELATÓRIO FINAL ---
print("\n" + "="*40)
print("COMPARATIVO DE FILTRAGEM")
print("-"*40)
print(f"CENÁRIO SEM FILTRO (BRUTO):")
print(f"  Equação: DB = ({m_b:.6f} * RP) + ({c_b:.6f})")
print(f"  Erro Médio: {erro_b:.6f} g/cm³")
print("-"*40)
print(f"CENÁRIO COM SAVITZKY-GOLAY:")
print(f"  Equação: DB = ({m_s:.6f} * RP) + ({c_s:.6f})")
print(f"  Erro Médio: {erro_s:.6f} g/cm³")
print("-"*40)

melhoria = ((erro_b - erro_s) / erro_b) * 100
status = "MELHOROU" if melhoria > 0 else "PIOROU"
print(f"Resultado: O filtro SG {status} a precisão em {abs(melhoria):.2f}%")
print(f"Arquivo detalhado em: {OUTPUT_EXCEL}")
print("="*40)
