import numpy as np
from .ctermicacalc import (
    obter_diferenciais_temperatura_insolacao_porta_madeira,
    obter_diferenciais_temperatura_insolacao_portas_vidros,
    obter_diferenciais_temperatura_porta_madeira,
    obter_diferenciais_temperatura_porta_vidro

)
from projeto.models import Projeto
from termicos.models import DadosTermicos
from django.shortcuts import get_object_or_404
from .cargasparedes import carregar_temperaturas_projeto

import numpy as np

# Função para calcular carga de insolação para portas de madeira
def calcular_carga_insolacao_porta_madeira(porta_madeira, orientacao):
    diferenciais_insolacao = obter_diferenciais_temperatura_insolacao_porta_madeira()
    key = getattr(porta_madeira, f'diferencial_insolacao_{orientacao}', None)
    diferencial_insolacao = diferenciais_insolacao.get(key, np.zeros(13))
    
    area_porta = getattr(porta_madeira, f'area_porta_{orientacao}', None)
    coeficiente_porta = getattr(porta_madeira, f'coeficiente_porta_{orientacao}', None)

    if area_porta is not None and coeficiente_porta is not None:
        carga_insolacao = coeficiente_porta * area_porta * diferencial_insolacao
    else:
        carga_insolacao = np.zeros(13)

    return carga_insolacao


# Função para calcular carga de insolação para portas de vidro
def calcular_carga_insolacao_porta_vidro(porta_vidro, orientacao):
    diferenciais_insolacao = obter_diferenciais_temperatura_insolacao_portas_vidros()
    key = getattr(porta_vidro, f'diferencial_insolacao_{orientacao}', None)
    diferencial_insolacao = diferenciais_insolacao.get(key, np.zeros(13))
    
    area_porta = getattr(porta_vidro, f'area_porta_{orientacao}', None)
    coeficiente_porta = getattr(porta_vidro, f'coeficiente_porta_{orientacao}', None)

    if area_porta is not None and coeficiente_porta is not None:
        carga_insolacao = coeficiente_porta * area_porta * diferencial_insolacao
    else:
        carga_insolacao = np.zeros(13)

    return carga_insolacao


# Função para calcular carga térmica de temperatura para portas de madeira
def calcular_carga_termica_porta_madeira(projeto_id, porta_madeira, termicos, orientacao):
    temperaturas_externas = carregar_temperaturas_projeto(projeto_id)
    temperatura_interna = termicos.temperatura_interna
    tipo_porta = getattr(porta_madeira, f'tipo_porta_{orientacao}', None)
    area_porta = getattr(porta_madeira, f'area_porta_{orientacao}', None)
    coeficiente_porta = getattr(porta_madeira, f'coeficiente_porta_{orientacao}', None)

    if tipo_porta == 'externa':
        diferencial = temperaturas_externas - temperatura_interna
    else:
        diferenciais_temperatura = obter_diferenciais_temperatura_porta_madeira()
        key = f"{tipo_porta}_{orientacao}"
        diferencial = diferenciais_temperatura.get(key, np.zeros(len(temperaturas_externas)))

    if diferencial is not None and area_porta is not None and coeficiente_porta is not None:
        carga_termica = coeficiente_porta * area_porta * diferencial
    else:
        carga_termica = np.zeros(len(temperaturas_externas))

    return carga_termica


# Função para calcular carga térmica de temperatura para portas de vidro
def calcular_carga_termica_porta_vidro(projeto_id, porta_vidro, termicos, orientacao):
    temperaturas_externas = carregar_temperaturas_projeto(projeto_id)
    temperatura_interna = termicos.temperatura_interna
    tipo_porta = getattr(porta_vidro, f'tipo_porta_{orientacao}', None)
    area_porta = getattr(porta_vidro, f'area_porta_{orientacao}', None)
    coeficiente_porta = getattr(porta_vidro, f'coeficiente_porta_{orientacao}', None)

    if tipo_porta == 'externa':
        diferencial = temperaturas_externas - temperatura_interna
    else:
        diferenciais_temperatura = obter_diferenciais_temperatura_porta_vidro()
        key = f"{tipo_porta}_{orientacao}"
        diferencial = diferenciais_temperatura.get(key, np.zeros(len(temperaturas_externas)))

    if diferencial is not None and area_porta is not None and coeficiente_porta is not None:
        carga_termica = coeficiente_porta * area_porta * diferencial
    else:
        carga_termica = np.zeros(len(temperaturas_externas))

    return carga_termica


# Função de agregação para calcular todas as cargas térmicas e de insolação para portas de madeira e vidro
def calcular_cargas_portas(projeto_id, portas_madeira, portas_vidro, termicos):
    cargas_termo_portas = {'madeira': {}, 'vidro': {}}
    cargas_insolacao_portas = {'madeira': {}, 'vidro': {}}

    for orientacao in ['norte', 'sul', 'leste', 'oeste']:
        # Inicializa com arrays de zeros para cada orientação
        cargas_termo_portas['madeira'][orientacao] = np.zeros(13)
        cargas_insolacao_portas['madeira'][orientacao] = np.zeros(13)
        cargas_termo_portas['vidro'][orientacao] = np.zeros(13)
        cargas_insolacao_portas['vidro'][orientacao] = np.zeros(13)

        for porta_madeira in portas_madeira:
            carga_termica_madeira = calcular_carga_termica_porta_madeira(projeto_id, porta_madeira, termicos, orientacao)
            carga_insolacao_madeira = calcular_carga_insolacao_porta_madeira(porta_madeira, orientacao)
            
            cargas_termo_portas['madeira'][orientacao] += carga_termica_madeira
            cargas_insolacao_portas['madeira'][orientacao] += carga_insolacao_madeira

        for porta_vidro in portas_vidro:
            carga_termica_vidro = calcular_carga_termica_porta_vidro(projeto_id, porta_vidro, termicos, orientacao)
            carga_insolacao_vidro = calcular_carga_insolacao_porta_vidro(porta_vidro, orientacao)
            
            cargas_termo_portas['vidro'][orientacao] += carga_termica_vidro
            cargas_insolacao_portas['vidro'][orientacao] += carga_insolacao_vidro

    return cargas_termo_portas, cargas_insolacao_portas

