from django.shortcuts import render, get_object_or_404
from datetime import datetime, timedelta
from projeto.models import Projeto
from .models import CondicaoExt  # Importando o modelo correto
import math
import requests
import pandas as pd
import logging
from django.db import connection
from django.contrib.auth.decorators import login_required

from django.shortcuts import render, get_object_or_404
from datetime import datetime, timedelta
from projeto.models import Projeto
from .models import CondicaoExt
import math
import requests
import pandas as pd
import logging
from django.db import connection
from django.contrib.auth.decorators import login_required

# Função para calcular a umidade absoluta
def calcular_umidade_absoluta(temperatura, umidade_relativa):
    pressao_saturacao = 6.112 * math.exp((17.67 * temperatura) / (temperatura + 243.5))
    umidade_absoluta = (pressao_saturacao * umidade_relativa * 2.1674) / (temperatura + 273.15)
    return umidade_absoluta

# **Função para obter o período dos últimos 4 anos**
def obter_periodo_ultimos_4_anos():
    data_fim = datetime.now()
    data_inicio = data_fim - timedelta(days=1460)  # 4 anos atrás
    return data_inicio.strftime('%Y-%m-%d'), data_fim.strftime('%Y-%m-%d')

# **Função para obter temperaturas horárias - API HISTÓRICA**
def obter_temperaturas_periodo(projeto, data_inicio, data_fim):
    latitude = projeto.latitude
    longitude = projeto.longitude

    url = "https://archive-api.open-meteo.com/v1/archive"  # ✅ Usando API histórica
    params = {
        "latitude": latitude,
        "longitude": longitude,
        "start_date": data_inicio,
        "end_date": data_fim,
        "hourly": "temperature_2m",
        "timezone": "America/Sao_Paulo"
    }

    try:
        response = requests.get(url, params=params)
        response.raise_for_status()
        data = response.json()
        
        if "hourly" not in data:
            logging.error(f"Erro: Dados históricos não disponíveis para {latitude}, {longitude}.")
            return None

        df = pd.DataFrame({
            'time': data['hourly']['time'],
            'temperature_2m': data['hourly']['temperature_2m'],
        })
        df['time'] = pd.to_datetime(df['time'])
        return df
    except Exception as e:
        logging.error(f"Erro ao obter dados da API: {e}")
        return None

# **Função para identificar o dia mais quente**
def identificar_dia_mais_quente(df):
    df['date'] = df['time'].dt.date
    max_temps_por_dia = df.groupby('date')['temperature_2m'].max()
    dia_mais_quente = max_temps_por_dia.idxmax()
    temperatura_max = max_temps_por_dia.max()
    return dia_mais_quente, temperatura_max

# **Função para obter dados do dia mais quente - API HISTÓRICA**
def obter_dados_dia_mais_quente(projeto, dia_mais_quente):
    latitude = projeto.latitude
    longitude = projeto.longitude

    url = "https://archive-api.open-meteo.com/v1/archive"  # ✅ API correta
    params = {
        "latitude": latitude,
        "longitude": longitude,
        "start_date": dia_mais_quente.strftime('%Y-%m-%d'),
        "end_date": dia_mais_quente.strftime('%Y-%m-%d'),
        "hourly": "temperature_2m,relative_humidity_2m",
        "timezone": "America/Sao_Paulo"
    }

    try:
        response = requests.get(url, params=params)
        response.raise_for_status()
        data = response.json()

        if "hourly" not in data:
            logging.error(f"Erro: Dados históricos não disponíveis para {latitude}, {longitude}.")
            return None

        df = pd.DataFrame({
            'time': data['hourly']['time'],
            'temperature_2m': data['hourly']['temperature_2m'],
            'relative_humidity_2m': data['hourly']['relative_humidity_2m'],
        })
        df['time'] = pd.to_datetime(df['time'])
        df = df[(df['time'].dt.hour >= 6) & (df['time'].dt.hour <= 18)]  # Filtrar entre 06h e 18h
        return df
    except Exception as e:
        logging.error(f"Erro ao obter dados da API: {e}")
        return None

# **Função para buscar e salvar os dados no banco de dados**
@login_required
def obter_temperaturas_projeto(request, projeto_id):
    if request.user.is_authenticated and request.user.tenant:
        connection.set_schema(request.user.tenant.schema_name)

    projeto = get_object_or_404(Projeto, id=projeto_id)

    if not projeto.latitude or not projeto.longitude:
        return render(request, 'projeto/erro.html', {'erro': 'As coordenadas do projeto não estão disponíveis.'})

    # 🔹 Alterado para 4 anos
    data_inicio, data_fim = obter_periodo_ultimos_4_anos()
    df_temperaturas = obter_temperaturas_periodo(projeto, data_inicio, data_fim)

    if df_temperaturas is None or df_temperaturas.empty:
        return render(request, 'projeto/erro.html', {'erro': 'Não foi possível obter as temperaturas.'})

    dia_mais_quente, temperatura_max = identificar_dia_mais_quente(df_temperaturas)

    # Verificar se os dados já existem no banco
    dados_existentes = CondicaoExt.objects.filter(projeto=projeto, data=dia_mais_quente)
    if dados_existentes.exists():
        temperaturas_horarias = dados_existentes.values('hora', 'temperatura', 'umidade_relativa', 'umidade_absoluta')
    else:
        df_dia_mais_quente = obter_dados_dia_mais_quente(projeto, dia_mais_quente)

        if df_dia_mais_quente is None or df_dia_mais_quente.empty:
            return render(request, 'projeto/erro.html', {'erro': 'Não foi possível obter os dados do dia mais quente.'})

        df_dia_mais_quente['umidade_absoluta'] = df_dia_mais_quente.apply(
            lambda row: calcular_umidade_absoluta(row['temperature_2m'], row['relative_humidity_2m']), axis=1
        )

        # Salvar no banco de dados
        salvar_dados_climaticos(projeto, df_dia_mais_quente)

        temperaturas_horarias = df_dia_mais_quente.to_dict('records')

    return render(request, 'condicaoext/temperaturas.html', {
        'projeto': projeto,
        'dia_mais_quente': dia_mais_quente,
        'temperatura_max': temperatura_max,
        'temperaturas_horarias': temperaturas_horarias,
        'periodo_inicio': data_inicio,
        'periodo_fim': data_fim
    })




def registrar_temperaturas_dia_mais_quente(projeto_id):
    projeto = get_object_or_404(Projeto, id=projeto_id)

    # Obter o período dos últimos dois anos
    data_inicio, data_fim = obter_periodo_ultimos_4_anos()
    
    # Carregar as temperaturas para o período
    df_temperaturas = obter_temperaturas_periodo(projeto, data_inicio, data_fim)

    if df_temperaturas is None or df_temperaturas.empty:
        print("Erro: Não foi possível obter as temperaturas.")
        return

    # Identificar o dia mais quente
    dia_mais_quente, temperatura_max = identificar_dia_mais_quente(df_temperaturas)

    # Verificar se as temperaturas do dia mais quente já foram registradas
    dados_existentes = CondicaoExt.objects.filter(projeto=projeto, data=dia_mais_quente)
    if dados_existentes.exists():
        print("As temperaturas para o dia mais quente já estão registradas no banco de dados.")
        return

    # Obter dados detalhados para o dia mais quente
    df_dia_mais_quente = obter_dados_dia_mais_quente(projeto, dia_mais_quente)

    if df_dia_mais_quente is None or df_dia_mais_quente.empty:
        print("Erro: Não foi possível obter os dados do dia mais quente.")
        return

    # Calcular a umidade absoluta com base na temperatura e umidade relativa
    df_dia_mais_quente['umidade_absoluta'] = df_dia_mais_quente.apply(
        lambda row: calcular_umidade_absoluta(row['temperature_2m'], row['relative_humidity_2m']), axis=1
    )

    # Salvar os dados climáticos no banco de dados
    salvar_dados_climaticos(projeto, df_dia_mais_quente)
    print(f"Temperaturas do dia mais quente ({dia_mais_quente}) registradas com sucesso.")



import os
from django.conf import settings

# Função para salvar os dados climáticos associando diretamente ao projeto e salvar em CSV
# Função para salvar os dados climáticos associando diretamente ao projeto e salvar em CSV

def salvar_dados_climaticos(projeto, df_dia_mais_quente):
    # Adicionando o cálculo do calor latente de vaporização para cada temperatura
    df_dia_mais_quente['calor_latente'] = df_dia_mais_quente['temperature_2m'].apply(calcular_calor_latente)

    # Salvar os dados no banco de dados
    for _, row in df_dia_mais_quente.iterrows():
        CondicaoExt.objects.create(
            projeto=projeto,  # Associação direta ao projeto
            data=row['time'].date(),
            hora=row['time'].time(),
            temperatura=row['temperature_2m'],
            umidade_relativa=row['relative_humidity_2m'],
            umidade_absoluta=row['umidade_absoluta'],
            calor_latente=row['calor_latente']  # Adicionando o calor latente ao modelo
        )

    # Definir o caminho para salvar o CSV dentro da pasta do projeto
    caminho_pasta_projeto = os.path.join(settings.MEDIA_ROOT, f'/var/www/html/cagpublico/cag/arquivos_climaticos/{projeto.nome_projeto}')
    
    # Cria a pasta do projeto, caso não exista
    os.makedirs(caminho_pasta_projeto, exist_ok=True)

    # Caminho completo para o arquivo CSV
    caminho_csv = os.path.join(caminho_pasta_projeto, f'dados_climaticos_{projeto.nome_projeto}.csv')

    # Salvando o DataFrame em CSV
    df_dia_mais_quente.to_csv(caminho_csv, index=False, sep=';', encoding='utf-8')



import os
import pandas as pd
from django.conf import settings
from django.shortcuts import render, get_object_or_404
from projeto.models import Projeto
import plotly.graph_objs as go
import plotly.io as pio
from django.utils.dateformat import DateFormat

# Função para gerar gráficos interativos com Plotly

def gerar_grafico_plotly(x, y, titulo, xlabel, ylabel):
    # Criar o gráfico
    fig = go.Figure()
    fig.add_trace(go.Scatter(x=x, y=y, mode='lines+markers'))

    # Configurações do layout
    fig.update_layout(
        title=titulo,
        xaxis_title=xlabel, 
        yaxis_title=ylabel,
        template='plotly_white',
    )

    # Retornar o gráfico como JSON para ser renderizado no template
    return pio.to_html(fig, full_html=False)

from django.shortcuts import render

def exibir_erro(request):
    return render(request, 'condicaoext/erro.html', {'mensagem': 'Página não encontrada ou outro erro ocorreu.'})


import os
import pandas as pd
from django.conf import settings
from django.shortcuts import render, get_object_or_404
import plotly.graph_objects as go
from projeto.models import Projeto

# Função para calcular o calor latente de vaporização com base na temperatura (real)

def calcular_calor_latente(temp):
    # Fórmula para o calor latente de vaporização (em kJ/kg) como função da temperatura (em °C)
    L = 2500.8 - 2.36 * temp + 0.0016 * temp**2 - 0.00006 * temp**3
    return L


import os
import pandas as pd
import plotly.graph_objects as go
from django.shortcuts import render, get_object_or_404
from .models import Projeto
from ctermica.models import Ambiente
from termicos.models import DadosTermicos
from django.conf import settings

from django.contrib.auth.decorators import login_required
from django.shortcuts import render, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.db import connection

import os
import pandas as pd
from django.conf import settings
import plotly.graph_objects as go

from django.contrib.auth.decorators import login_required
from django.shortcuts import render, get_object_or_404
from django.db import connection
from django.conf import settings
import os
import pandas as pd
import plotly.graph_objects as go

from projeto.models import Projeto
from ctermica.models import Ambiente
from termicos.models import DadosTermicos
from .models import CondicaoExt  # se precisar
from .views import calcular_calor_latente  # Ajuste o import conforme a localização real da função

@login_required
def exibir_graficos_csv(request, projeto_id):
    # Define o schema do tenant, caso o usuário tenha
    if request.user.is_authenticated and request.user.tenant:
        connection.set_schema(request.user.tenant.schema_name)
    
    # Obtém o projeto
    projeto = get_object_or_404(Projeto, id=projeto_id)

    # Obtém os ambientes relacionados ao projeto
    ambientes = Ambiente.objects.filter(projeto=projeto)
    if not ambientes.exists():
        return render(request, 'condicaoext/erro.html', {'mensagem': 'Nenhum ambiente encontrado para este projeto.'})

    # Selecione o primeiro ambiente (ou modifique conforme sua lógica)
    ambiente = ambientes.first()

    # Obtém os dados térmicos do ambiente
    dados_termicos = DadosTermicos.objects.filter(ambiente=ambiente).first()
    if not dados_termicos:
        return render(request, 'condicaoext/erro.html', {'mensagem': 'Nenhum dado térmico encontrado para o ambiente.'})

    # Caminho do arquivo CSV
    caminho_csv = os.path.join(
        settings.MEDIA_ROOT,
        f'arquivos_climaticos/{projeto.nome_projeto}/dados_climaticos_{projeto.nome_projeto}.csv'
    )
    if not os.path.exists(caminho_csv):
        return render(request, 'condicaoext/erro.html', {'mensagem': 'Nenhum dado climático encontrado.'})

    # Carregar os dados do CSV
    df = pd.read_csv(caminho_csv, sep=';', encoding='utf-8')

    # Converte a coluna 'time' para pandas.Timestamp (se não estiver ainda)
    # (Caso a coluna já esteja em Timestamp, você pode pular esta linha)
    df['time'] = pd.to_datetime(df['time'])

    # Usar a temperatura interna definida em DadosTermicos
    temperatura_interna = dados_termicos.temperatura_interna

    # Calcular o calor latente para a temperatura interna
    calor_latente_interna = calcular_calor_latente(temperatura_interna)

    # Criar um DataFrame com o valor constante ao longo do dia
    df_calor_latente_interna = pd.DataFrame({
        'time': df['time'],
        'calor_latente_interna': [calor_latente_interna] * len(df['time'])
    })

    # Gráfico de calor latente para a temperatura interna
    fig_calor_latente_interna = go.Figure()
    fig_calor_latente_interna.add_trace(go.Scatter(
        x=df_calor_latente_interna['time'],
        y=df_calor_latente_interna['calor_latente_interna'],
        mode='lines',
        name=f'Calor Latente Interno ({temperatura_interna}°C)'
    ))
    fig_calor_latente_interna.update_layout(
        title=f"Calor Latente para Temperatura Interna de {temperatura_interna}°C",
        xaxis_title="Horário",
        yaxis_title="Calor Latente (kJ/kg)",
        xaxis=dict(dtick=3600000),
        width=1000,
        height=600
    )
    plot_calor_latente_interna = fig_calor_latente_interna.to_html(full_html=False)

    # Gráfico de calor latente externo (baseado em temperaturas externas)
    df['calor_latente_dia'] = df['temperature_2m'].apply(calcular_calor_latente)
    fig_calor_latente_dia = go.Figure()
    fig_calor_latente_dia.add_trace(go.Scatter(
        x=df['time'],
        y=df['calor_latente_dia'],
        mode='lines',
        name='Calor Latente Externo (kJ/kg)'
    ))
    fig_calor_latente_dia.update_layout(
        title="Calor Latente Externo ao Longo do Dia (kJ/kg)",
        xaxis_title="Horário",
        yaxis_title="Calor Latente (kJ/kg)",
        xaxis=dict(dtick=3600000),
        width=1000,
        height=600
    )
    plot_calor_latente_dia = fig_calor_latente_dia.to_html(full_html=False)

    # Gráfico de temperatura horária
    fig_temp = go.Figure()
    fig_temp.add_trace(go.Scatter(
        x=df['time'],
        y=df['temperature_2m'],
        mode='lines',
        name='Temperatura (°C)'
    ))
    fig_temp.update_layout(
        title="Temperatura Externa Horária (°C)",
        xaxis_title="Horário",
        yaxis_title="Temperatura (°C)",
        xaxis=dict(dtick=3600000),
        width=1000,
        height=600
    )
    plot_temp = fig_temp.to_html(full_html=False)

    # Gráfico de umidade relativa externa horária
    fig_umidade_rel = go.Figure()
    fig_umidade_rel.add_trace(go.Scatter(
        x=df['time'],
        y=df['relative_humidity_2m'],
        mode='lines',
        name='Umidade Relativa (%)'
    ))
    fig_umidade_rel.update_layout(
        title="Umidade Relativa Horária (%)",
        xaxis_title="Horário",
        yaxis_title="Umidade Relativa (%)",
        xaxis=dict(dtick=3600000),
        width=1000,
        height=600
    )
    plot_umidade_rel = fig_umidade_rel.to_html(full_html=False)

    # Gráfico de umidade absoluta externa horária
    fig_umidade_abs = go.Figure()
    fig_umidade_abs.add_trace(go.Scatter(
        x=df['time'],
        y=df['umidade_absoluta'],
        mode='lines',
        name='Umidade Absoluta (g/kg)'
    ))
    fig_umidade_abs.update_layout(
        title="Umidade Absoluta Horária (g/kg)",
        xaxis_title="Horário",
        yaxis_title="Umidade Absoluta (g/kg)",
        xaxis=dict(dtick=3600000),
        width=1000,
        height=600
    )
    plot_umidade_abs = fig_umidade_abs.to_html(full_html=False)

    # ✅ Corrigir dia_mais_quente: converter para datetime em Python
    dia_mais_quente_pandas = df['time'].iloc[0]
    if isinstance(dia_mais_quente_pandas, pd.Timestamp):
        dia_mais_quente = dia_mais_quente_pandas.to_pydatetime()
    else:
        dia_mais_quente = dia_mais_quente_pandas  # caso seja datetime ou string

    # Determinar temperatura máxima
    temperatura_max = df['temperature_2m'].max()

    # Retorna para o template, onde podemos usar o filtro |date:"d/m/Y"
    return render(request, 'condicaoext/registrocsv.html', {
        'projeto': projeto,
        'dia_mais_quente': dia_mais_quente,
        'temperatura_max': temperatura_max,
        'plot_temp': plot_temp,
        'plot_umidade_rel': plot_umidade_rel,
        'plot_umidade_abs': plot_umidade_abs,
        'plot_calor_latente_dia': plot_calor_latente_dia,
        'plot_calor_latente_interna': plot_calor_latente_interna,
        'temperatura_interna': temperatura_interna
    })





import os
import pandas as pd
from django.conf import settings

def gravar_csv_temperaturas(projeto, df_temperaturas):
    """
    Grava em CSV as colunas solicitadas: 'cidade', 'data', 'hora', 'temperatura'.
    Assim é possível avaliar se as informações retornadas pela API estão corretas.
    """
    # Garante que o campo 'time' seja datetime
    df_temperaturas['time'] = pd.to_datetime(df_temperaturas['time'])

    # Monta o DataFrame de exportação
    df_export = pd.DataFrame()
    df_export['cidade'] = [projeto.nome_projeto] * len(df_temperaturas)
    df_export['data'] = df_temperaturas['time'].dt.date
    df_export['hora'] = df_temperaturas['time'].dt.strftime('%H:%M')
    df_export['temperatura'] = df_temperaturas['temperature_2m']

    # Define o caminho e o nome do arquivo CSV
    # Por exemplo, dentro de "arquivos_climaticos/<nome do projeto>"
    pasta_saida = os.path.join(
        settings.MEDIA_ROOT, 
        f'arquivos_climaticos/{projeto.nome_projeto}'
    )
    os.makedirs(pasta_saida, exist_ok=True)  # Cria a pasta, se não existir

    caminho_csv = os.path.join(
        pasta_saida,
        f"historico_api_{projeto.nome_projeto}.csv"
    )

    # Salva o CSV
    df_export.to_csv(
        caminho_csv,
        index=False,
        sep=';',
        encoding='utf-8'
    )
    print(f"Arquivo CSV gerado em: {caminho_csv}")

from django.shortcuts import render, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.db import connection
from django.conf import settings
import os
import pandas as pd


@login_required
def salvar_temperaturas_csv(request, projeto_id):
    # Se você estiver usando multi-tenancy e quiser isolar a base do tenant logado
    if request.user.is_authenticated and request.user.tenant:
        connection.set_schema(request.user.tenant.schema_name)

    # Busca o projeto
    projeto = get_object_or_404(Projeto, id=projeto_id)

    # Calcula período (2 ou 4 anos, conforme sua função)
    data_inicio, data_fim = obter_periodo_ultimos_4_anos()  

    # Obtém DataFrame com temperaturas
    df_temperaturas = obter_temperaturas_periodo(projeto, data_inicio, data_fim)

    # Verifica se não veio vazio
    if df_temperaturas is None or df_temperaturas.empty:
        return render(
            request, 
            'condicaoext/erro.html',
            {'mensagem': 'Não foi possível obter as temperaturas ou nenhuma temperatura disponível.'}
        )

    # Grava o CSV
    gravar_csv_temperaturas(projeto, df_temperaturas)

    # Você pode retornar um HTML que diga que deu certo,
    # ou redirecionar para outra página.
    return render(
        request, 
        'condicaoext/sucesso.html',
        {'mensagem': 'CSV gerado com sucesso e salvo no servidor!'}
    )
