# gerar relatorio doc dos calculos
import os
from datetime import datetime
from django.conf import settings
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.db import connection
from django.http import HttpResponse, HttpResponseForbidden
from django.shortcuts import render, get_object_or_404
from docx import Document
from docx.shared import Inches, Pt
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.table import WD_ROW_HEIGHT_RULE
from docx.enum.section import WD_SECTION
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np
from ctermica.models import Ambiente
from paredes.models import Parede
from portas.models import Porta
from projeto.models import Projeto
from telhados.models import Telhado
from termicos.models import DadosTermicos
from vidros.models import Vidro
from .cargasparedes import calcular_carga_termica_parede, calcular_carga_insolacao_parede, carregar_temperaturas_projeto2
from .cargasvidros import calcular_cargas_vidros
from .cargasportas import calcular_carga_insolacao_porta, calcular_carga_termica_porta, calcular_cargas_portas
from .cargastelhados import calcular_cargas_telhados, calcular_carga_insolacao_telhado, calcular_carga_termica_telhado
from .cargastermicos import (
    calcular_cargas_termicas_ambiente,
    calcular_calor_sensivel_ar_exterior,
    calcular_calor_latente_ar_exterior,
    calcular_vazao_ar_infiltracao, calcular_vazao_ar_renovacao, calcular_vazao_total_ar_exterior,
    calcular_densidade_ar
)

ORIENTACOES = ['norte', 'sul', 'leste', 'oeste']
HORARIOS = ["06:00", "07:00", "08:00", "09:00", "10:00", "11:00", "12:00", 
            "13:00", "14:00", "15:00", "16:00", "17:00", "18:00"]


from docx.shared import Pt, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH

def inserir_marca_dagua(doc):
    """
    Insere uma marca d'água de texto em todas as páginas do documento de forma mais visível e inclinada.
    """
    watermark_text = "VERSÃO DE TESTE – NÃO USAR COMERCIALMENTE"

    for section in doc.sections:
        # Cabeçalho - Marca d’água na parte superior da página
        header = section.header
        paragraph_header = header.paragraphs[0] if header.paragraphs else header.add_paragraph()
        run_header = paragraph_header.add_run(watermark_text)
        run_header.font.size = Pt(24)  # Fonte maior para melhor visibilidade
        run_header.font.color.rgb = RGBColor(150, 150, 150)  # Cinza mais escuro para ficar mais visível
        paragraph_header.alignment = WD_ALIGN_PARAGRAPH.CENTER  # Centraliza horizontalmente
        
        # Adiciona uma linha extra para maior espaçamento e efeito de marca d’água diagonal
        paragraph_header.add_run("\n\n" + watermark_text)

        # Rodapé - Reforça a marca d’água na parte inferior da página
        footer = section.footer
        paragraph_footer = footer.paragraphs[0] if footer.paragraphs else footer.add_paragraph()
        run_footer = paragraph_footer.add_run(watermark_text)
        run_footer.font.size = Pt(24)
        run_footer.font.color.rgb = RGBColor(150, 150, 150)
        paragraph_footer.alignment = WD_ALIGN_PARAGRAPH.CENTER

        # Repetição extra para garantir que fique visível mesmo em diferentes tamanhos de papel
        paragraph_footer.add_run("\n\n" + watermark_text)


def create_load_graphs(horarios, carga_termica_total_ambiente, output_dir):
    """
    Cria gráficos de carga térmica em W e TR.
    """
    # Converte para TR
    carga_tr = [w/3517 for w in carga_termica_total_ambiente]
    
    # Configurações de estilo comum
    plt.style.use('default')
    
    # Gráfico em W
    plt.figure(figsize=(12, 6))
    plt.plot(horarios, carga_termica_total_ambiente, 'b-o', linewidth=2)
    plt.title('Variação da Carga Térmica Total (W)', pad=20)
    plt.xlabel('Horário')
    plt.ylabel('Carga Térmica (W)')
    plt.grid(True)
    plt.xticks(rotation=45)
    
    # Adiciona valores nos pontos
    for i, v in enumerate(carga_termica_total_ambiente):
        plt.text(i, float(v), f'{float(v):.0f}W', ha='center', va='bottom')
    
    max_index_w = np.argmax(carga_termica_total_ambiente)
    max_value_w = carga_termica_total_ambiente[max_index_w]
    max_hour_w = horarios[max_index_w]
    
    # Adiciona o texto descritivo
    plt.figtext(0.5, 0.01,
                f"O gráfico demonstra a variação da carga térmica ao longo do dia, com o valor máximo de {max_value_w:.2f} W atingido às {max_hour_w}.",
                ha='center', fontsize=12, wrap=True)
    
    plt.tight_layout(rect=[0, 0.03, 1, 1])  # Ajusta o espaço para o texto
    graph_w_path = os.path.join(output_dir, 'graph_w.png')
    plt.savefig(graph_w_path, dpi=300, bbox_inches='tight')
    plt.close()
    
    # Gráfico em TR
    plt.figure(figsize=(12, 6))
    plt.plot(horarios, carga_tr, 'r-o', linewidth=2)
    plt.title('Variação da Carga Térmica Total (TR)', pad=20)
    plt.xlabel('Horário')
    plt.ylabel('Carga Térmica (TR)')
    plt.grid(True)
    plt.xticks(rotation=45)
    
    # Adiciona valores nos pontos
    for i, v in enumerate(carga_tr):
        plt.text(i, v, f'{v:.2f}TR', ha='center', va='bottom')
    
    max_index_tr = np.argmax(carga_tr)
    max_value_tr = carga_tr[max_index_tr]
    max_hour_tr = horarios[max_index_tr]
    
    # Adiciona o texto descritivo
    plt.figtext(0.5, 0.01,
                f"O gráfico demonstra a variação da carga térmica ao longo do dia, com o valor máximo de {max_value_tr:.2f} TR atingido às {max_hour_tr}.",
                ha='center', fontsize=12, wrap=True)
    
    plt.tight_layout(rect=[0, 0.03, 1, 1])  # Ajusta o espaço para o texto
    graph_tr_path = os.path.join(output_dir, 'graph_tr.png')
    plt.savefig(graph_tr_path, dpi=300, bbox_inches='tight')
    plt.close()
    
    return graph_w_path, graph_tr_path

def format_table(table):
    """
    Formata uma tabela do Word.
    """
    # Define larguras preferidas das células
    for row in table.rows:
        # Primeira coluna mais larga para acomodar os títulos
        row.cells[0].width = Inches(2.5)
        # Outras colunas com largura uniforme
        for cell in row.cells[1:]:
            cell.width = Inches(1.0)
    
    # Aplica estilo às células
    for row in table.rows:
        for cell in row.cells:
            # Remove quebra automática de texto
            paragraph = cell.paragraphs[0]
            paragraph_format = paragraph.paragraph_format
            paragraph_format.space_before = Pt(2)
            paragraph_format.space_after = Pt(2)
            # Centraliza o conteúdo
            paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
            # Define fonte e tamanho
            for run in paragraph.runs:
                run.font.size = Pt(7)
                run.font.name = 'Arial'

    # Estilo especial para cabeçalho
    for cell in table.rows[0].cells:
        for paragraph in cell.paragraphs:
            for run in paragraph.runs:
                run.font.bold = True
                run.font.size = Pt(7)
    
    # Ajusta altura mínima das linhas
    for row in table.rows:
        row.height = Inches(0.3)
        row.height_rule = WD_ROW_HEIGHT_RULE.AT_LEAST

def add_table_rows(table, data, header=False):
    """
    Adiciona linhas a uma tabela com base nos dados fornecidos.
    """
    for row_data in data:
        row_cells = table.add_row().cells
        row_cells[0].text = row_data[0]
        for i, value in enumerate(row_data[1]):
            if isinstance(value, (float, np.float64)):
                row_cells[i+1].text = f'{value:.2f} W'
            else:
                row_cells[i+1].text = str(value)

def ensure_array(value, length):
    """
    Garante que um valor seja um array de determinado comprimento.
    """
    if isinstance(value, (float, np.float64)):
        return [float(value)] * length
    elif isinstance(value, np.ndarray):
        return value.tolist()
    return value

@login_required
def gerar_relatorio_completo(request, projeto_id, ambiente_id):
    try:
        # Verifica autenticação e tenant
        if not request.user.is_authenticated or not request.user.tenant:
            return HttpResponseForbidden("Usuário não autenticado ou sem tenant")

        connection.set_schema(request.user.tenant.schema_name)
        
        projeto = get_object_or_404(Projeto, id=projeto_id)
        ambiente = get_object_or_404(Ambiente, id=ambiente_id, projeto=projeto)
        termicos = get_object_or_404(DadosTermicos, ambiente=ambiente)
        paredes = Parede.objects.filter(ambiente=ambiente)
        vidros = Vidro.objects.filter(ambiente=ambiente)
        portas = Porta.objects.filter(ambiente=ambiente)
        telhados = Telhado.objects.filter(ambiente=ambiente)

        try:
            temperaturas_externas, umidade_absoluta_externa, calor_latente_agua = carregar_temperaturas_projeto2(projeto_id)
        except FileNotFoundError as e:
            messages.error(request, str(e))
            return render(request, 'calculotermica/resultados_cargatermica.html', {
                'projeto': projeto,
                'ambiente': ambiente,
                'erro': True
            })

        temperatura_interna = termicos.temperatura_interna
        altitude = projeto.altitude if projeto.altitude is not None else 0
        densidade_ar = calcular_densidade_ar(altitude)

        # Cálculo das vazões de ar exterior
        vazao_infiltracao = calcular_vazao_ar_infiltracao(termicos.area_piso, termicos.pe_direito)
        vazao_renovacao = calcular_vazao_ar_renovacao(termicos.numero_pessoas, termicos.taxa_renovacao)
        vazao_total_ar_exterior = calcular_vazao_total_ar_exterior(
            termicos.area_piso, termicos.pe_direito, termicos.numero_pessoas, termicos.taxa_renovacao
        )

        calor_sensivel_ar_exterior = calcular_calor_sensivel_ar_exterior(
            termicos, temperaturas_externas, temperatura_interna, vazao_total_ar_exterior
        )

        calor_latente_ar_exterior = calcular_calor_latente_ar_exterior(
            densidade_ar,
            vazao_total_ar_exterior,
            umidade_absoluta_externa,
            termicos.umidade_absoluta_interna,
            hlv=calor_latente_agua
        )

        # Inicializar dicionários e definir orientações e horários
        cargas_termo = {}
        cargas_insolacao = {}

        # Cálculos para paredes
        total_carga_termica_paredes = np.zeros(len(HORARIOS))
        total_carga_insolacao_paredes = np.zeros(len(HORARIOS))

        for parede in paredes:
            for orientacao in ORIENTACOES:
                carga_termica = calcular_carga_termica_parede(projeto_id, parede, termicos, orientacao)
                carga_insolacao = calcular_carga_insolacao_parede(parede, orientacao)
                
                total_carga_termica_paredes += np.array(carga_termica)
                total_carga_insolacao_paredes += np.array(carga_insolacao)
                
                cargas_termo[f'{orientacao}'] = carga_termica
                cargas_insolacao[f'{orientacao}'] = carga_insolacao

        total_parede_calculo = total_carga_termica_paredes + total_carga_insolacao_paredes
        cargas_totais_paredes = {
            'total_carga_termica': total_carga_termica_paredes,
            'total_carga_insolacao': total_carga_insolacao_paredes,
            'total_parede_calculo': total_parede_calculo
        }

        # Cálculos para vidros
        cargas_termo_vidros, cargas_insolacao_vidros = calcular_cargas_vidros(projeto_id, vidros, termicos)
        total_carga_termica_vidros = np.zeros(len(HORARIOS))
        total_carga_insolacao_vidros = np.zeros(len(HORARIOS))

        for orientacao, carga_termica in cargas_termo_vidros.items():
            total_carga_termica_vidros += np.array(carga_termica)
        for orientacao, carga_insolacao in cargas_insolacao_vidros.items():
            total_carga_insolacao_vidros += np.array(carga_insolacao)

        total_vidro_calculo = total_carga_termica_vidros + total_carga_insolacao_vidros
        cargas_totais_vidros = {
            'total_carga_termica': total_carga_termica_vidros,
            'total_carga_insolacao': total_carga_insolacao_vidros,
            'total_vidro_calculo': total_vidro_calculo
        }

        # Cálculos para todas as portas (unificadas)
        cargas_termo_portas = {}
        cargas_insolacao_portas = {}
        total_carga_termica_portas = np.zeros(len(HORARIOS))
        total_carga_insolacao_portas = np.zeros(len(HORARIOS))

        for porta in portas:
            for orientacao in ORIENTACOES:
                carga_termica = calcular_carga_termica_porta(projeto_id, porta, termicos, orientacao)
                carga_insolacao = calcular_carga_insolacao_porta(porta, orientacao)
                
                cargas_termo_portas[orientacao] = cargas_termo_portas.get(orientacao, np.zeros(len(HORARIOS))) + np.array(carga_termica)
                cargas_insolacao_portas[orientacao] = cargas_insolacao_portas.get(orientacao, np.zeros(len(HORARIOS))) + np.array(carga_insolacao)
                
                total_carga_termica_portas += np.array(carga_termica)
                total_carga_insolacao_portas += np.array(carga_insolacao)

        total_porta_calculo = total_carga_termica_portas + total_carga_insolacao_portas

        cargas_totais_portas = {
            'total_carga_termica': total_carga_termica_portas,
            'total_carga_insolacao': total_carga_insolacao_portas,
            'total_porta_calculo': total_porta_calculo
        }



    # Cálculos para telhados
        cargas_termo_telhados = {}
        cargas_insolacao_telhados = {}
        total_carga_termica_telhados = np.zeros(len(HORARIOS))
        total_carga_insolacao_telhados = np.zeros(len(HORARIOS))

        for telhado in telhados:
            carga_termica = calcular_carga_termica_telhado(projeto_id, telhado, termicos)
            carga_insolacao = calcular_carga_insolacao_telhado(projeto_id, telhado, termicos)

            cargas_termo_telhados[f'telhado_{telhado.id}'] = carga_termica
            cargas_insolacao_telhados[f'telhado_{telhado.id}'] = carga_insolacao

            total_carga_termica_telhados += np.array(carga_termica)
            total_carga_insolacao_telhados += np.array(carga_insolacao)

        total_telhado_calculo = total_carga_termica_telhados + total_carga_insolacao_telhados
        cargas_totais_telhados = {
            'total_carga_termica': total_carga_termica_telhados,
            'total_carga_insolacao': total_carga_insolacao_telhados,
            'total_telhado_calculo': total_telhado_calculo
        }

        # Cálculos do ambiente
        cargas_ambiente = calcular_cargas_termicas_ambiente(termicos)
        cargas_totais_ambiente = {
            'carga_sensivel_pessoas': np.zeros(len(HORARIOS)) if 'carga_sensivel_pessoas' not in cargas_ambiente else cargas_ambiente['carga_sensivel_pessoas'],
            'carga_latente_pessoas': np.zeros(len(HORARIOS)) if 'carga_latente_pessoas' not in cargas_ambiente else cargas_ambiente['carga_latente_pessoas'],
            'carga_iluminacao': np.zeros(len(HORARIOS)) if 'carga_iluminacao' not in cargas_ambiente else cargas_ambiente['carga_iluminacao'],
            'carga_equipamentos': np.zeros(len(HORARIOS)) if 'carga_equipamentos' not in cargas_ambiente else cargas_ambiente['carga_equipamentos'],
        }

        # Somatórios finais
        somatorio_carga_sensivel_total = (
            total_parede_calculo + 
            total_vidro_calculo + 
            total_porta_calculo + 
            total_telhado_calculo + 
            np.array(cargas_totais_ambiente['carga_sensivel_pessoas']) + 
            calor_sensivel_ar_exterior +
            np.array(cargas_totais_ambiente['carga_iluminacao']) +
            np.array(cargas_totais_ambiente['carga_equipamentos'])
        )

        somatorio_carga_latente_total = (
            np.array(cargas_totais_ambiente['carga_latente_pessoas']) + 
            calor_latente_ar_exterior
        )

        carga_termica_total_ambiente = somatorio_carga_latente_total + somatorio_carga_sensivel_total
        carga_termica_total_ambiente_max = max(carga_termica_total_ambiente)

        # Criar o contexto com todos os dados calculados
        contexto = {
            'projeto': projeto,
            'ambiente': ambiente,
            'cargas_totais_paredes': cargas_totais_paredes,
            'cargas_totais_vidros': cargas_totais_vidros,
            'total_porta_calculo': total_porta_calculo,
            'cargas_totais_telhados': cargas_totais_telhados,
            'cargas_totais_ambiente': cargas_totais_ambiente,
            'cargas_termo': cargas_termo,
            'cargas_insolacao': cargas_insolacao,
            'cargas_termo_vidros': cargas_termo_vidros,
            'cargas_insolacao_vidros': cargas_insolacao_vidros,
            'total_carga_termica': total_carga_termica_portas,
            'total_carga_insolacao': total_carga_insolacao_portas,
            'cargas_termo_telhados': cargas_termo_telhados,
            'cargas_insolacao_telhados': cargas_insolacao_telhados,
            'cargas_ambiente': cargas_ambiente,
            'vazao_infiltracao': vazao_infiltracao,
            'vazao_renovacao': vazao_renovacao,
            'vazao_total_ar_exterior': vazao_total_ar_exterior,
            'calor_sensivel_ar_exterior': calor_sensivel_ar_exterior,
            'calor_latente_ar_exterior': calor_latente_ar_exterior,
            'horarios': HORARIOS,
            'altitude': altitude,
            'densidade_ar': densidade_ar,
            'somatorio_carga_sensivel_total': somatorio_carga_sensivel_total,
            'somatorio_carga_latente_total': somatorio_carga_latente_total,
            'carga_termica_total_ambiente': carga_termica_total_ambiente,
            'carga_termica_total_ambiente_max': carga_termica_total_ambiente_max,
        }

        # Cria o documento Word
        doc = Document()
            # ---------------------
        # INSERE MARCA D'ÁGUA SE FOR TESTE
        # ---------------------
        if request.user.tenant.schema_name == "teste":
            inserir_marca_dagua(doc)

        # Configuração da página para margem menor
        section = doc.sections[0]
        section.left_margin = Inches(0.7)
        section.right_margin = Inches(0.7)
        section.page_width = Inches(11.69)  # A4 altura = 297mm
        section.page_height = Inches(8.27)  # A4 largura = 210mm

        # Adiciona o logo
        logo_path = '/var/www/html/cag/static/relatorio/grf_graph_logo.png'
        
        if os.path.exists(logo_path):
            doc.add_picture(logo_path, width=Inches(3))  # 200px ≈ 2 inches
            last_paragraph = doc.paragraphs[-1]
            last_paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
        
                # Adiciona o logo em todas as páginas
        section = doc.sections[0]
        footer = section.footer
        footer_para = footer.paragraphs[0]
        footer_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
        run = footer_para.add_run()
        run.add_picture(logo_path, width=Inches(1.5))  # Ajuste o tamanho conforme necessário
        
        # Adiciona título
        title = doc.add_heading('Relatório de Cálculo de Carga Térmica')
        title.alignment = WD_ALIGN_PARAGRAPH.CENTER
        
        # Informações básicas
        doc.add_paragraph(f'Projeto: {projeto.nome_projeto}')
        doc.add_paragraph(f'Ambiente: {ambiente.nome_ambiente}')
        doc.add_paragraph(f'Data: {datetime.now().strftime("%d/%m/%Y")}')
        
        # Altitude e densidade do ar
        doc.add_heading('Informações Básicas', level=1)
        p = doc.add_paragraph()
        p.add_run('Altitude: ').bold = True
        p.add_run(f'{altitude} m')
        p = doc.add_paragraph()
        p.add_run('Densidade do Ar: ').bold = True
        p.add_run(f'{densidade_ar:.4f} kg/m³')

        # Vazões de ar
        doc.add_heading('Vazões de Ar', level=1)
        table = doc.add_table(rows=1, cols=len(HORARIOS) + 1)
        table.style = 'Table Grid'
        
        header_cells = table.rows[0].cells
        header_cells[0].text = 'Tipo de Vazão'
        for i, hora in enumerate(HORARIOS):
            header_cells[i+1].text = hora

        # Adiciona cada tipo de vazão
        vazao_infiltracao = ensure_array(vazao_infiltracao, len(HORARIOS))
        vazao_renovacao = ensure_array(vazao_renovacao, len(HORARIOS))
        vazao_total_ar_exterior = ensure_array(vazao_total_ar_exterior, len(HORARIOS))

        vazoes = [
            ('Vazão de Infiltração', vazao_infiltracao),
            ('Vazão de Renovação', vazao_renovacao),
            ('Vazão Total de Ar Exterior', vazao_total_ar_exterior)
        ]
        
        add_table_rows(table, vazoes)
        format_table(table)

        # Cargas térmicas das paredes
        doc.add_heading('Cargas Térmicas das Paredes por Orientação', level=1)
        
        # Tabela de cargas térmicas
        table = doc.add_table(rows=1, cols=len(HORARIOS) + 1)
        table.style = 'Table Grid'
        
        header_cells = table.rows[0].cells
        header_cells[0].text = 'Orientação'
        for i, hora in enumerate(HORARIOS):
            header_cells[i+1].text = hora

        add_table_rows(table, cargas_termo.items())
        format_table(table)
                
        # Tabela de cargas de insolação
        doc.add_heading('Cargas de Insolação das Paredes por Orientação', level=1)
        table = doc.add_table(rows=1, cols=len(HORARIOS) + 1)
        table.style = 'Table Grid'
        
        header_cells = table.rows[0].cells
        header_cells[0].text = 'Orientação'
        for i, hora in enumerate(HORARIOS):
            header_cells[i+1].text = hora

        add_table_rows(table, cargas_insolacao.items())
        format_table(table)

        # Totais das paredes
        doc.add_heading('Totais das Cargas das Paredes', level=2)
        table = doc.add_table(rows=1, cols=len(HORARIOS) + 1)
        table.style = 'Table Grid'
        
        header_cells = table.rows[0].cells
        header_cells[0].text = 'Tipo'
        for i, hora in enumerate(HORARIOS):
            header_cells[i+1].text = hora

        totais_parede = [
            ('Total Carga Térmica', cargas_totais_paredes['total_carga_termica']),
            ('Total Carga Insolação', cargas_totais_paredes['total_carga_insolacao']),
            ('Total Geral', cargas_totais_paredes['total_parede_calculo'])
        ]

        add_table_rows(table, totais_parede)
        format_table(table)

        # Cargas térmicas dos vidros
        doc.add_heading('Cargas Térmicas dos Vidros por Orientação', level=1)
        table = doc.add_table(rows=1, cols=len(HORARIOS) + 1)
        table.style = 'Table Grid'
        
        header_cells = table.rows[0].cells
        header_cells[0].text = 'Orientação'
        for i, hora in enumerate(HORARIOS):
            header_cells[i+1].text = hora

        add_table_rows(table, cargas_termo_vidros.items())
        format_table(table)

        # Cargas de insolação dos vidros
        doc.add_heading('Cargas de Insolação dos Vidros por Orientação', level=1)
        table = doc.add_table(rows=1, cols=len(HORARIOS) + 1)
        table.style = 'Table Grid'

        header_cells = table.rows[0].cells
        header_cells[0].text = 'Orientação'
        for i, hora in enumerate(HORARIOS):
            header_cells[i+1].text = hora

        add_table_rows(table, cargas_insolacao_vidros.items())
        format_table(table)

        # Totais dos vidros
        doc.add_heading('Totais das Cargas dos Vidros', level=2)
        table = doc.add_table(rows=1, cols=len(HORARIOS) + 1)
        table.style = 'Table Grid'

        header_cells = table.rows[0].cells
        header_cells[0].text = 'Orientação'
        for i, hora in enumerate(HORARIOS):
            header_cells[i+1].text = hora

        totais_vidro = [
            ('Total Carga Térmica', cargas_totais_vidros['total_carga_termica']),
            ('Total Carga Insolação', cargas_totais_vidros['total_carga_insolacao']),
            ('Total Geral', cargas_totais_vidros['total_vidro_calculo'])
        ]

        add_table_rows(table, totais_vidro)
        format_table(table)

        # Cargas térmicas das portas por orientação
        doc.add_heading('Cargas Térmicas das Portas por Orientação', level=1)
        table = doc.add_table(rows=1, cols=len(HORARIOS) + 1)
        table.style = 'Table Grid'

        header_cells = table.rows[0].cells
        header_cells[0].text = 'Orientação'
        for i, hora in enumerate(HORARIOS):
            header_cells[i+1].text = hora

        add_table_rows(table, cargas_termo_portas.items())
        format_table(table)

        # Cargas de insolação das portas por orientação
        doc.add_heading('Cargas de Insolação das Portas por Orientação', level=1)
        table = doc.add_table(rows=1, cols=len(HORARIOS) + 1)
        table.style = 'Table Grid'

        header_cells = table.rows[0].cells
        header_cells[0].text = 'Orientação'
        for i, hora in enumerate(HORARIOS):
            header_cells[i+1].text = hora

        add_table_rows(table, cargas_insolacao_portas.items())
        format_table(table)

        # Totais das cargas das portas
        doc.add_heading('Totais das Cargas das Portas', level=2)
        table = doc.add_table(rows=1, cols=len(HORARIOS) + 1)
        table.style = 'Table Grid'

        header_cells = table.rows[0].cells
        header_cells[0].text = 'Tipo'
        for i, hora in enumerate(HORARIOS):
            header_cells[i+1].text = hora

        totais_portas = [
            ('Total Carga Térmica', cargas_totais_portas['total_carga_termica']),
            ('Total Carga Insolação', cargas_totais_portas['total_carga_insolacao']),
            ('Total Geral', cargas_totais_portas['total_porta_calculo']),
        ]

        add_table_rows(table, totais_portas)
        format_table(table)


        # Telhados
        doc.add_heading('Cargas Térmicas dos Telhados', level=1)
        table = doc.add_table(rows=1, cols=len(HORARIOS) + 1)
        table.style = 'Table Grid'

        header_cells = table.rows[0].cells
        header_cells[0].text = 'Orientação'
        for i, hora in enumerate(HORARIOS):
            header_cells[i+1].text = hora

        add_table_rows(table, cargas_termo_telhados.items())
        format_table(table)

        # Insolação telhados
        doc.add_heading('Cargas de Insolação dos Telhados', level=1)
        table = doc.add_table(rows=1, cols=len(HORARIOS) + 1)
        table.style = 'Table Grid'

        header_cells = table.rows[0].cells
        header_cells[0].text = 'Orientação'
        for i, hora in enumerate(HORARIOS):
            header_cells[i+1].text = hora

        add_table_rows(table, cargas_insolacao_telhados.items())
        format_table(table)

        # Totais dos telhados
        doc.add_heading('Totais das Cargas dos Telhados', level=2)
        table = doc.add_table(rows=1, cols=len(HORARIOS) + 1)
        table.style = 'Table Grid'

        header_cells = table.rows[0].cells
        header_cells[0].text = 'Orientação'
        for i, hora in enumerate(HORARIOS):
            header_cells[i+1].text = hora

        totais_telhado = [
            ('Total Carga Térmica', cargas_totais_telhados['total_carga_termica']),
            ('Total Carga Insolação', cargas_totais_telhados['total_carga_insolacao']),
            ('Total Geral', cargas_totais_telhados['total_telhado_calculo'])
        ]

        add_table_rows(table, totais_telhado)
        format_table(table)

        # Cargas do ambiente
        doc.add_heading('Cargas do Ambiente', level=1)
        table = doc.add_table(rows=1, cols=len(HORARIOS) + 1)
        table.style = 'Table Grid'

        header_cells = table.rows[0].cells
        header_cells[0].text = 'Tipo de Carga'
        for i, hora in enumerate(HORARIOS):
            header_cells[i+1].text = hora

        # Prepara os dados das cargas do ambiente
        carga_sensivel = ensure_array(cargas_totais_ambiente['carga_sensivel_pessoas'], len(HORARIOS))
        carga_latente = ensure_array(cargas_totais_ambiente['carga_latente_pessoas'], len(HORARIOS))
        carga_iluminacao = ensure_array(cargas_totais_ambiente['carga_iluminacao'], len(HORARIOS))
        carga_equipamentos = ensure_array(cargas_totais_ambiente['carga_equipamentos'], len(HORARIOS))

        cargas_amb = [
            ('Carga Sensível Pessoas', carga_sensivel),
            ('Carga Latente Pessoas', carga_latente),
            ('Carga Iluminação', carga_iluminacao),
            ('Carga Equipamentos', carga_equipamentos)
        ]

        add_table_rows(table, cargas_amb)
        format_table(table)

        # Calor do ar exterior
        doc.add_heading('Calor do Ar Exterior', level=1)
        table = doc.add_table(rows=1, cols=len(HORARIOS) + 1)
        table.style = 'Table Grid'

        header_cells = table.rows[0].cells
        header_cells[0].text = 'Tipo de Calor'
        for i, hora in enumerate(HORARIOS):
            header_cells[i+1].text = hora

        # Verifica se os valores são escalares ou arrays e ajusta conforme necessário
        calor_sensivel_valores = ensure_array(calor_sensivel_ar_exterior, len(HORARIOS))
        calor_latente_valores = ensure_array(calor_latente_ar_exterior, len(HORARIOS))

        calores_ar = [
            ('Calor Sensível', calor_sensivel_valores),
            ('Calor Latente', calor_latente_valores)
        ]

        add_table_rows(table, calores_ar)
        format_table(table)

        # Resultados finais - Somatórios
        doc.add_heading('Somatório das Cargas Térmicas', level=1)
        table = doc.add_table(rows=1, cols=len(HORARIOS) + 1)
        table.style = 'Table Grid'

        header_cells = table.rows[0].cells
        header_cells[0].text = 'Tipo de Carga'
        for i, hora in enumerate(HORARIOS):
            header_cells[i+1].text = hora

        # Adiciona os somatórios finais
        somatorios = [
            ('Somatório Carga Sensível', somatorio_carga_sensivel_total),
            ('Somatório Carga Latente', somatorio_carga_latente_total),
            ('Carga Térmica Total', carga_termica_total_ambiente)
        ]

        add_table_rows(table, somatorios)
        format_table(table)

        # Carga Térmica Total Máxima
        doc.add_heading('Carga Térmica Total Máxima', level=1)
        p = doc.add_paragraph()
        p.add_run('Valor Máximo: ').bold = True
        p.add_run(f'{carga_termica_total_ambiente_max:.2f} W')
        
        # Conversão para TR (Tonelada de Refrigeração)
        tr_max = carga_termica_total_ambiente_max / 3517
        p = doc.add_paragraph()
        p.add_run('Valor Máximo em TR: ').bold = True
        p.add_run(f'{tr_max:.2f} TR')

        # Adiciona os gráficos
        doc.add_heading('Gráficos de Variação da Carga Térmica', level=1)

        # Cria diretório temporário para os gráficos
        temp_dir = os.path.join(settings.MEDIA_ROOT, 'temp_graphs')
        os.makedirs(temp_dir, exist_ok=True)

        # Gera os gráficos
        graph_w_path, graph_tr_path = create_load_graphs(
            HORARIOS, 
            carga_termica_total_ambiente,
            temp_dir
        )

        # Adiciona descrição dos gráficos
        doc.add_paragraph('Os gráficos abaixo mostram a variação da carga térmica total ao longo do dia. ' + 
                        'O primeiro gráfico apresenta os valores em Watts (W) e o segundo em Toneladas de ' +
                        'Refrigeração (TR). Observe os picos de carga e a variação ao longo das horas do dia.')

        # Adiciona os gráficos ao documento
        doc.add_picture(graph_w_path, width=Inches(10))
        last_paragraph = doc.paragraphs[-1]
        last_paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER

        doc.add_picture(graph_tr_path, width=Inches(10))
        last_paragraph = doc.paragraphs[-1]
        last_paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER

        # Salva o documento
        output_path = os.path.join(settings.MEDIA_ROOT, 'relatorios', 
                                f'relatorio_calculo_{projeto.nome_projeto}_{ambiente.nome_ambiente}.docx')
        os.makedirs(os.path.dirname(output_path), exist_ok=True)
        doc.save(output_path)
        
        # Retorna o documento como resposta
        with open(output_path, 'rb') as doc_file:
            response = HttpResponse(doc_file.read(), 
                                content_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document')
            response['Content-Disposition'] = f'attachment; filename=relatorio_calculo_{projeto.nome_projeto}_{ambiente.nome_ambiente}.docx'
            return response

    except Exception as e:
        print(f"Erro detalhado: {str(e)}")
        return HttpResponse(f"Erro ao gerar relatório: {str(e)}", status=500)