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_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, ambiente_id):
    """
    Cria gráficos de carga térmica em W e TR para um ambiente específico,
    gerando nomes de arquivos únicos.
    """
    # Converte para TR
    carga_tr = [w / 3517 for w in carga_termica_total_ambiente]
    
    # Nomeia os arquivos com ID do ambiente para evitar sobrescrita
    graph_w_filename = f'graph_w_{ambiente_id}.png'
    graph_tr_filename = f'graph_tr_{ambiente_id}.png'
    
    # -- 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)

    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]
    plt.figtext(
        0.5, 0.01,
        f"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])
    
    graph_w_path = os.path.join(output_dir, graph_w_filename)
    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)

    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]
    plt.figtext(
        0.5, 0.01,
        f"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])
    
    graph_tr_path = os.path.join(output_dir, graph_tr_filename)
    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 (largura, fonte, centralização etc.).
    """
    for row in table.rows:
        # Primeira coluna mais larga
        row.cells[0].width = Inches(2.5)
        for cell in row.cells[1:]:
            cell.width = Inches(1.0)
    
    for row in table.rows:
        for cell in row.cells:
            paragraph = cell.paragraphs[0]
            paragraph_format = paragraph.paragraph_format
            paragraph_format.space_before = Pt(2)
            paragraph_format.space_after = Pt(2)
            paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
            for run in paragraph.runs:
                run.font.size = Pt(7)
                run.font.name = 'Arial'

    # Cabeçalho em negrito
    for run in table.rows[0].cells[0].paragraphs[0].runs:
        run.font.bold = True

    # 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):
    """
    Adiciona linhas a uma tabela, onde data é uma lista de tuplas: (rótulo, array_de_valores).
    """
    for row_data in data:
        row_cells = table.add_row().cells
        row_cells[0].text = str(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 tamanho 'length'.
    Caso seja escalar ou array parcial, transforma em list do tamanho adequado.
    """
    if isinstance(value, (float, int, np.float64)):
        return [float(value)] * length
    elif isinstance(value, np.ndarray):
        return value.tolist()
    elif isinstance(value, list) and len(value) == length:
        return value
    else:
        return [0.0]*length

def add_table_from_queryset(doc, title, queryset, fields, headers):
    """
    Cria uma tabela no documento Word para um queryset, exibindo
    apenas os campos especificados em 'fields' com rótulos 'headers'.
    """
    doc.add_heading(title, level=2)
    if not queryset.exists():
        doc.add_paragraph("Nenhum dado cadastrado.")
        return

    table = doc.add_table(rows=1, cols=len(fields))
    table.style = 'Table Grid'

    # Cabeçalho
    header_cells = table.rows[0].cells
    for i, header in enumerate(headers):
        header_cells[i].text = header

    # Linhas com dados
    for obj in queryset:
        row_cells = table.add_row().cells
        for i, field in enumerate(fields):
            valor = getattr(obj, field, "N/A")
            row_cells[i].text = str(valor)

    format_table(table)

@login_required
def gerar_relatorio_todos_ambientes(request, projeto_id):
    """
    Gera um único relatório Word contendo todos os ambientes do projeto,
    incluindo quebra de página para cada ambiente.
    """
    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)
        ambientes = Ambiente.objects.filter(projeto=projeto).order_by('id')

        if not ambientes.exists():
            messages.warning(request, "Este projeto não possui ambientes cadastrados.")
            return render(request, 'calculotermica/resultados_cargatermica.html', {
                'projeto': projeto,
                'ambientes': [],
                'erro': True
            })

        # Carrega as temperaturas externas e umidades (para todo o projeto)
        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,
                'ambientes': ambientes,
                'erro': True
            })
        
        # Cria um único documento para todo o projeto
        doc = Document()

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

        # Configurações de margem/tamanho
        section = doc.sections[0]
        section.left_margin = Inches(0.7)
        section.right_margin = Inches(0.7)
        section.page_width = Inches(11.69)  # A4 paisagem
        section.page_height = Inches(8.27)  # A4 paisagem

        # Adiciona um cabeçalho inicial para o relatório completo
        # (Opcional: Você pode personalizar essa "capa")
        doc.add_heading('Relatório de Cálculo de Carga Térmica', 0).alignment = WD_ALIGN_PARAGRAPH.CENTER
        doc.add_paragraph(f'Projeto: {projeto.nome_projeto}').alignment = WD_ALIGN_PARAGRAPH.CENTER
        doc.add_paragraph(f'Data: {datetime.now().strftime("%d/%m/%Y")}').alignment = WD_ALIGN_PARAGRAPH.CENTER
        
        # Caso queira inserir um logo no início
        logo_path = '/var/www/html/cagpublico/cag/static/relatorio/grf_graph_logo.png'
        if os.path.exists(logo_path):
            doc.add_picture(logo_path, width=Inches(3))
            doc.paragraphs[-1].alignment = WD_ALIGN_PARAGRAPH.CENTER

        # Configura o rodapé com o logo (opcional)
        footer = section.footer
        footer_para = footer.paragraphs[0]
        footer_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
        run_footer = footer_para.add_run()
        if os.path.exists(logo_path):
            run_footer.add_picture(logo_path, width=Inches(1.5))

        # Se quiser uma quebra de página após a capa
        doc.add_page_break()

        # Loop pelos ambientes
        for idx, ambiente in enumerate(ambientes):
            # --- Cálculos específicos de cada ambiente ---
            termicos = get_object_or_404(DadosTermicos, ambiente=ambiente)
            paredes = Parede.objects.filter(ambiente=ambiente)
            vidros = Vidro.objects.filter(ambiente=ambiente)
            porta = Porta.objects.filter(ambiente=ambiente)
            telhados = Telhado.objects.filter(ambiente=ambiente)

            # Parâmetros básicos
            temperatura_interna = termicos.temperatura_interna
            altitude = projeto.altitude if projeto.altitude is not None else 0
            densidade_ar = calcular_densidade_ar(altitude)

            # Vazões de ar
            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
            )

            # 1) Paredes
            cargas_termo = {}
            cargas_insolacao = {}
            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[orientacao] = carga_termica
                    cargas_insolacao[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
            }

            # 2) 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, val in cargas_termo_vidros.items():
                total_carga_termica_vidros += np.array(val)
            for orientacao, val in cargas_insolacao_vidros.items():
                total_carga_insolacao_vidros += np.array(val)

            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
            }

            # Portas (modelo unificado)
            cargas_termo_portas = {}
            cargas_insolacao_portas = {}
            total_carga_termica_portas = np.zeros(len(HORARIOS))
            total_carga_insolacao_portas = np.zeros(len(HORARIOS))

            porta = get_object_or_404(Porta, ambiente=ambiente)

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

            total_portas_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_portas_calculo': total_portas_calculo
            }


            # 5) 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_telh = calcular_carga_termica_telhado(
                    projeto_id, telhado, termicos
                )
                carga_insolacao_telh = calcular_carga_insolacao_telhado(
                    projeto_id, telhado, termicos
                )
                total_carga_termica_telhados += np.array(carga_termica_telh)
                total_carga_insolacao_telhados += np.array(carga_insolacao_telh)
                cargas_termo_telhados[f'Telhado {telhado.id}'] = carga_termica_telh
                cargas_insolacao_telhados[f'Telhado {telhado.id}'] = carga_insolacao_telh
            
            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
            }

            # 6) Cargas do Ambiente (pessoas, iluminação, etc.)
            cargas_ambiente = calcular_cargas_termicas_ambiente(termicos)
            c_sensivel_pessoas = ensure_array(cargas_ambiente.get('carga_sensivel_pessoas', 0.0), len(HORARIOS))
            c_latente_pessoas  = ensure_array(cargas_ambiente.get('carga_latente_pessoas', 0.0),  len(HORARIOS))
            c_iluminacao       = ensure_array(cargas_ambiente.get('carga_iluminacao', 0.0),        len(HORARIOS))
            c_equipamentos     = ensure_array(cargas_ambiente.get('carga_equipamentos', 0.0),      len(HORARIOS))
            
            cargas_totais_ambiente = {
                'carga_sensivel_pessoas': c_sensivel_pessoas,
                'carga_latente_pessoas': c_latente_pessoas,
                'carga_iluminacao': c_iluminacao,
                'carga_equipamentos': c_equipamentos,
            }

            # Somatório de cargas sensíveis
            somatorio_carga_sensivel_total = (
                total_parede_calculo +
                total_vidro_calculo +
                total_portas_calculo + 
                total_telhado_calculo +
                np.array(c_sensivel_pessoas) +
                np.array(calor_sensivel_ar_exterior) +
                np.array(c_iluminacao) +
                np.array(c_equipamentos)
            )


            # Somatório de cargas latentes
            somatorio_carga_latente_total = (
                np.array(c_latente_pessoas) +
                np.array(calor_latente_ar_exterior)
            )

            # Carga térmica total hora a hora
            carga_termica_total_ambiente = somatorio_carga_sensivel_total + somatorio_carga_latente_total
            carga_termica_total_ambiente_max = max(carga_termica_total_ambiente)
            tr_max = carga_termica_total_ambiente_max / 3517.0

            # --- Agora começa a escrita no relatório para ESTE ambiente ---

            # Título para o ambiente
            doc.add_heading(f'Ambiente: {ambiente.nome_ambiente}', level=1)
            
            # Informações básicas
            doc.add_paragraph(f'Altitude: {altitude} m')
            doc.add_paragraph(f'Densidade do Ar: {densidade_ar:.4f} kg/m³')

            # Vazões
            doc.add_heading('Vazões de Ar (m³/h)', 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 de Vazão'
            for i, hora in enumerate(HORARIOS):
                header_cells[i+1].text = hora
            
            v_infil = ensure_array(vazao_infiltracao, len(HORARIOS))
            v_renov = ensure_array(vazao_renovacao, len(HORARIOS))
            v_total = ensure_array(vazao_total_ar_exterior, len(HORARIOS))
            vazoes_data = [
                ('Vazão Infiltração', v_infil),
                ('Vazão Renovação', v_renov),
                ('Vazão Total Exterior', v_total),
            ]
            add_table_rows(table, vazoes_data)
            format_table(table)

            # Paredes: Carga térmica e insolação
            doc.add_heading('Cargas Térmicas das Paredes por Orientação (W)', 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
            add_table_rows(table, list(cargas_termo.items()))
            format_table(table)

            doc.add_heading('Cargas de Insolação das Paredes (W)', 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
            add_table_rows(table, list(cargas_insolacao.items()))
            format_table(table)

            doc.add_heading('Totais das Cargas das Paredes (W)', level=3)
            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

            parede_data = [
                ('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, parede_data)
            format_table(table)

            # Vidros
            doc.add_heading('Cargas Térmicas dos Vidros (W)', 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
            add_table_rows(table, list(cargas_termo_vidros.items()))
            format_table(table)

            doc.add_heading('Cargas de Insolação dos Vidros (W)', 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
            add_table_rows(table, list(cargas_insolacao_vidros.items()))
            format_table(table)

            doc.add_heading('Totais das Cargas dos Vidros (W)', level=3)
            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
            vidro_data = [
                ('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, vidro_data)
            format_table(table)

            # Portas (Modelo Unificado)
            doc.add_heading('Cargas Térmicas das Portas (W)', 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
            add_table_rows(table, list(cargas_termo_portas.items()))
            format_table(table)

            doc.add_heading('Cargas de Insolação das Portas (W)', 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
            add_table_rows(table, list(cargas_insolacao_portas.items()))
            format_table(table)

            doc.add_heading('Totais das Portas (W)', level=3)
            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

            portas_data = [
                ('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_portas_calculo']),
            ]
            add_table_rows(table, portas_data)
            format_table(table)


            # Telhados
            doc.add_heading('Cargas Térmicas dos Telhados (W)', 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 = 'Telhado'
            for i, hora in enumerate(HORARIOS):
                header_cells[i+1].text = hora
            add_table_rows(table, list(cargas_termo_telhados.items()))
            format_table(table)

            doc.add_heading('Cargas de Insolação dos Telhados (W)', 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 = 'Telhado'
            for i, hora in enumerate(HORARIOS):
                header_cells[i+1].text = hora
            add_table_rows(table, list(cargas_insolacao_telhados.items()))
            format_table(table)

            doc.add_heading('Totais dos Telhados (W)', level=3)
            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
            telhado_data = [
                ('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, telhado_data)
            format_table(table)

            # Cargas do ambiente
            doc.add_heading('Cargas Internas do Ambiente (W)', 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
            amb_data = [
                ('Carga Sensível Pessoas', c_sensivel_pessoas),
                ('Carga Latente Pessoas', c_latente_pessoas),
                ('Carga Iluminação', c_iluminacao),
                ('Carga Equipamentos', c_equipamentos),
            ]
            add_table_rows(table, amb_data)
            format_table(table)

            # Calor do ar exterior
            doc.add_heading('Calor do Ar Exterior (W)', 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
            ar_data = [
                ('Calor Sensível', ensure_array(calor_sensivel_ar_exterior, len(HORARIOS))),
                ('Calor Latente',  ensure_array(calor_latente_ar_exterior, len(HORARIOS))),
            ]
            add_table_rows(table, ar_data)
            format_table(table)

            # Resultados Finais
            doc.add_heading('Somatório das Cargas Térmicas (W)', 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
            soma_data = [
                ('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, soma_data)
            format_table(table)

            # Máximos
            doc.add_paragraph(
                f"Carga Térmica Máxima: {carga_termica_total_ambiente_max:.2f} W"
            )
            doc.add_paragraph(
                f"Em Toneladas de Refrigeração (TR): {tr_max:.2f} TR"
            )

            # Geração de gráficos (opcional) para cada ambiente
            doc.add_heading('Gráficos de Variação de Carga Térmica', level=2)
            temp_dir = os.path.join(settings.MEDIA_ROOT, 'temp_graphs')
            os.makedirs(temp_dir, exist_ok=True)
            graph_w_path, graph_tr_path = create_load_graphs(
                HORARIOS,
                carga_termica_total_ambiente,
                temp_dir,
                ambiente.id 
            )
            doc.add_picture(graph_w_path, width=Inches(9))
            doc.paragraphs[-1].alignment = WD_ALIGN_PARAGRAPH.CENTER
            doc.add_picture(graph_tr_path, width=Inches(9))
            doc.paragraphs[-1].alignment = WD_ALIGN_PARAGRAPH.CENTER

            # Se não for o último ambiente, insere quebra de página
            if idx < len(ambientes) - 1:
                doc.add_page_break()

        # Salva o documento final (com todos os ambientes)
        nome_arquivo = f'relatorio_calculo_{projeto.nome_projeto}.docx'
        output_path = os.path.join(settings.MEDIA_ROOT, 'relatorios', nome_arquivo)
        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={nome_arquivo}'
            return response

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