import os, pandas as pd, numpy as np, matplotlib.pyplot as plt
from matplotlib import use
from docx import Document
from docx.shared import Inches
from django.shortcuts import render, get_object_or_404, redirect
from django.http import HttpResponse, Http404
from django.conf import settings
from django.db import connection
from django.urls import reverse
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from itertools import combinations_with_replacement
from datetime import datetime

# Models Import
from projeto.models import Projeto
from ctermica.models import Ambiente
from paredes.models import Parede
from vidros.models import Vidro
from portas.models import Porta
from telhados.models import Telhado
from termicos.models import DadosTermicos

# Import dos modelos de aparelhos
from .renovador import RENOVADOR_MODELOS
from .hiwall import HIWALL_MODELOS
from .tipoduto import TIPODUTO_MODELOS
from .cassete4vias import CASSETE_4VIAS_MODELOS

# Funções de cálculo
from calculotermica.cargastermicos import calcular_vazao_total_ar_exterior

# Define o backend do Matplotlib para evitar uso de GUI
use('Agg')


########################################
# SELEÇÃO DE APARELHOS DE RENOVAÇÃO
########################################
def escolher_aparelho_renovacao(area_piso, pe_direito, numero_pessoas, taxa_renovacao, horas_dia=13):
    """
    Seleciona a combinação ideal de renovadores para atender à vazão necessária.
    Busca primeiro um único aparelho que atenda, depois a melhor combinação possível.
    """
    # Calcula a vazão total de ar exterior
    vazao_total_ar_exterior = calcular_vazao_total_ar_exterior(area_piso, pe_direito, numero_pessoas, taxa_renovacao, horas_dia)

    # Garante que seja escalar
    if isinstance(vazao_total_ar_exterior, (np.ndarray, list)):
        vazao_total_ar_exterior = float(np.sum(vazao_total_ar_exterior))
    else:
        vazao_total_ar_exterior = float(vazao_total_ar_exterior)

    # Vazão necessária por hora
    vazao_hora = vazao_total_ar_exterior / 13

    # Lista de vazões disponíveis (sempre usando a velocidade Alta)
    aparelho_disponivel = RENOVADOR_MODELOS[0]  # Considerando que só temos um modelo
    vazoes_disponiveis = [
        velocidade["vazao_maxima_m3h"]
        for velocidade in aparelho_disponivel["velocidades"]
    ]
    vazoes_disponiveis.sort()  # Exemplo: [1190, 1530, 2050]

    # Primeiro tenta encontrar um único aparelho que atenda
    for vazao in vazoes_disponiveis:
        if vazao >= vazao_hora:
            # Encontramos um único aparelho que atende
            velocidade_escolhida = next(
                v for v in aparelho_disponivel["velocidades"]
                if v["vazao_maxima_m3h"] == vazao
            )
            aparelho = aparelho_disponivel.copy()
            aparelho["velocidades"] = [velocidade_escolhida]
            return {
                "melhor_comb": [aparelho],
                "vazao_total_ar_exterior": vazao_hora
            }

    # Se precisar de mais de um aparelho, vamos buscar a melhor combinação
    melhor_comb = None
    menor_excesso = float('inf')
    menor_quantidade = float('inf')

    # Tenta todas as combinações possíveis de 2 a 10 aparelhos
    for n_aparelhos in range(2, 10):
        for comb in combinations_with_replacement(vazoes_disponiveis, n_aparelhos):
            soma_vazao = sum(comb)
            if soma_vazao >= vazao_hora:
                excesso = soma_vazao - vazao_hora
                if (len(comb) < menor_quantidade or
                    (len(comb) == menor_quantidade and excesso < menor_excesso)):
                    melhor_comb = comb
                    menor_excesso = excesso
                    menor_quantidade = len(comb)

    # Se encontrou uma combinação, monta o resultado
    if melhor_comb:
        resultado = []
        for vazao_necessaria in melhor_comb:
            velocidade_escolhida = next(
                v for v in aparelho_disponivel["velocidades"]
                if v["vazao_maxima_m3h"] == vazao_necessaria
            )
            aparelho = aparelho_disponivel.copy()
            aparelho["velocidades"] = [velocidade_escolhida]
            resultado.append(aparelho)

        return {
            "melhor_comb": resultado,
            "vazao_total_ar_exterior": vazao_hora
        }

    return {
        "melhor_comb": [],
        "vazao_total_ar_exterior": vazao_hora
    }


########################################
# SELEÇÃO DE APARELHOS DE AR CONDICIONADO
########################################
def determinar_aparelho(carga_maxima_watts, tipo_aparelho):
    """
    Determina a combinação de aparelhos (hiwall, tipoduto ou cassete4vias) para atender a 'carga_maxima_watts'.
    Retorna a melhor combinação possível (menor excesso e menor quantidade).
    """
    if tipo_aparelho == "hiwall":
        aparelhos = HIWALL_MODELOS
    elif tipo_aparelho == "tipoduto":
        aparelhos = TIPODUTO_MODELOS
    elif tipo_aparelho == "cassete4vias":
        aparelhos = CASSETE_4VIAS_MODELOS
    else:
        return "Tipo de aparelho não suportado"

    aparelhos = sorted(aparelhos, key=lambda x: x['capacidade_resfriamento_w'])

    melhor_comb = None
    menor_excesso = float('inf')
    menor_quantidade = float('inf')

    print(f"Carga máxima: {carga_maxima_watts} W, Tipo: {tipo_aparelho}")  # Debug
    for r in range(1, 20):
        for comb in combinations_with_replacement(aparelhos, r):
            capacidade_total = sum(a['capacidade_resfriamento_w'] for a in comb)
            excesso = capacidade_total - carga_maxima_watts

            if capacidade_total >= carga_maxima_watts:
                if len(comb) < menor_quantidade or (len(comb) == menor_quantidade and excesso < menor_excesso):
                    melhor_comb = comb
                    menor_excesso = excesso
                    menor_quantidade = len(comb)
                    print(f"Combinação encontrada: {len(comb)} aparelhos, Capacidade: {capacidade_total} W")  # Debug

    if melhor_comb:
        resultado = list(melhor_comb)
        print(f"Retornando {len(resultado)} aparelhos: {[ap['modelo'] for ap in resultado]}")  # Debug
        return resultado
    else:
        print("Nenhuma combinação adequada encontrada")  # Debug
        return "Não há combinação adequada de aparelhos."


########################################
# VIEW: LISTA PROJETOS/AMBIENTES
########################################
@login_required
def lista_projetos_ambientes(request, projeto_id, ambiente_nome=None):
    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)
    ambientes = Ambiente.objects.filter(projeto=projeto, nome_ambiente=ambiente_nome) if ambiente_nome else Ambiente.objects.filter(projeto=projeto)

    tipos_aparelhos = {}
    for amb in ambientes:
        tipo_aparelho = request.GET.get(f"tipo_aparelho_{amb.nome_ambiente}", None)
        tipos_aparelhos[amb.nome_ambiente] = tipo_aparelho

    lista_ambientes = []

    for ambiente in ambientes:
        tipo_aparelho_atual = tipos_aparelhos.get(ambiente.nome_ambiente) or ambiente.tipo_aparelho or "hiwall"

        if ambiente.tipo_aparelho != tipo_aparelho_atual and not ambiente.equipamento_existente:
            ambiente.tipo_aparelho = tipo_aparelho_atual
            ambiente.save()

        if ambiente.equipamento_existente:
            lista_ambientes.append({
                "nome": ambiente.nome_ambiente,
                "carga_termica_max": "N/A - Equipamento existente",
                "aparelho_detalhes": [{
                    "modelo": ambiente.modelo_aparelho or "Não especificado",
                    "capacidade_resfriamento_btu": "N/A",
                    "capacidade_aquecimento_btu": "N/A",
                    "capacidade_resfriamento_w": "N/A",
                    "capacidade_aquecimento_w": "N/A",
                    "fonte_alimentacao": "N/A",
                    "tubulacao_refrigerante_liquido_gas_mm": "N/A"
                }],
                "tipo_aparelho": ambiente.tipo_aparelho or "hiwall",
                "equipamento_existente": True
            })
            continue

        try:
            caminho_base = os.path.join(settings.BASE_DIR, f"arquivos_cargas_termicas/projeto_{projeto.nome_projeto}")
            caminho_arquivo = os.path.join(caminho_base, f"{ambiente.nome_ambiente}_resultados_termicos.xlsx")

            if os.path.exists(caminho_arquivo):
                df = pd.read_excel(caminho_arquivo, engine="openpyxl")
                if "Carga Térmica Total Ambiente" in df.columns:
                    carga_termica_max = df["Carga Térmica Total Ambiente"].max()
                    aparelhos_recomendados = determinar_aparelho(carga_termica_max, tipo_aparelho_atual) or []
                else:
                    carga_termica_max = "Coluna não encontrada"
                    aparelhos_recomendados = []
            else:
                carga_termica_max = "Arquivo não encontrado"
                aparelhos_recomendados = []
        except Exception as e:
            carga_termica_max = f"Erro ao processar arquivo: {e}"
            aparelhos_recomendados = []

        lista_ambientes.append({
            "nome": ambiente.nome_ambiente,
            "carga_termica_max": carga_termica_max,
            "aparelho_detalhes": aparelhos_recomendados,
            "tipo_aparelho": tipo_aparelho_atual,
            "equipamento_existente": False
        })

    contexto = {
        "projeto": projeto,
        "lista_ambientes": lista_ambientes,
        "tipos_aparelhos": tipos_aparelhos,
    }
    return render(request, "centraltermica/lista_ambientes_carga_termica.html", contexto)




########################################
# FUNÇÕES AUXILIARES PARA GERAÇÃO DE GRÁFICO E SALVAR DADOS
########################################
def gerar_grafico_carga_termica(df, caminho_grafico):
    """
    Gera e salva o gráfico da carga térmica total (convertida em TR) ao longo do dia.
    """
    os.makedirs(os.path.dirname(caminho_grafico), exist_ok=True)
    carga_termica_tr = df['Carga Térmica Total Ambiente'] / 3517

    plt.figure(figsize=(10, 6))
    plt.plot(df['Horário'], carga_termica_tr, label="Carga Térmica Total (TR)", marker="o")

    for i, valor in enumerate(carga_termica_tr):
        plt.text(df['Horário'][i], valor, f"{valor:.2f} TR", ha="center", va="bottom", fontsize=8)

    plt.xlabel("Horário do Dia")
    plt.ylabel("Carga Térmica Total (TR)")
    plt.title("Carga Térmica Total do Ambiente ao Longo do Dia (em TR)")
    plt.legend()
    plt.grid()
    plt.savefig(caminho_grafico)
    plt.close()


def salvar_dados_em_csv(projeto, nome_ambiente, parede, vidro, porta, telhado, termico):
    """
    Salva as variáveis do ambiente em CSV e retorna o DataFrame.
    """
    caminho_base = os.path.join(settings.BASE_DIR, f"/var/www/html/cagpublico/cag/arquivos_climaticos/projeto_{projeto.nome_projeto}/")
    os.makedirs(caminho_base, exist_ok=True)

    dados = {
        'nome_ambiente': [nome_ambiente],

        # Paredes
        'area_parede_norte': [parede.area_parede_norte],
        'coeficiente_parede_norte': [parede.coeficiente_parede_norte],
        'tipo_parede_norte': [parede.tipo_parede_norte],
        'area_parede_sul': [parede.area_parede_sul],
        'coeficiente_parede_sul': [parede.coeficiente_parede_sul],
        'tipo_parede_sul': [parede.tipo_parede_sul],
        'area_parede_leste': [parede.area_parede_leste],
        'coeficiente_parede_leste': [parede.coeficiente_parede_leste],
        'tipo_parede_leste': [parede.tipo_parede_leste],
        'area_parede_oeste': [parede.area_parede_oeste],
        'coeficiente_parede_oeste': [parede.coeficiente_parede_oeste],
        'tipo_parede_oeste': [parede.tipo_parede_oeste],

        # Vidros
        'area_vidro_norte': [vidro.area_vidro_norte],
        'coeficiente_vidro_norte': [vidro.coeficiente_vidro_norte],
        'tipo_vidro_norte': [vidro.tipo_vidro_norte],
        'area_vidro_sul': [vidro.area_vidro_sul],
        'coeficiente_vidro_sul': [vidro.coeficiente_vidro_sul],
        'tipo_vidro_sul': [vidro.tipo_vidro_sul],
        'area_vidro_leste': [vidro.area_vidro_leste],
        'coeficiente_vidro_leste': [vidro.coeficiente_vidro_leste],
        'tipo_vidro_leste': [vidro.tipo_vidro_leste],
        'area_vidro_oeste': [vidro.area_vidro_oeste],
        'coeficiente_vidro_oeste': [vidro.coeficiente_vidro_oeste],
        'tipo_vidro_oeste': [vidro.tipo_vidro_oeste],

        # Portas (unificadas)
        'area_porta_norte': [porta.area_porta_norte],
        'coeficiente_porta_norte': [porta.coeficiente_porta_norte],
        'tipo_porta_norte': [porta.tipo_porta_norte],
        'diferencial_insolacao_porta_norte': [porta.diferencial_insolacao_norte],
        'area_porta_sul': [porta.area_porta_sul],
        'coeficiente_porta_sul': [porta.coeficiente_porta_sul],
        'tipo_porta_sul': [porta.tipo_porta_sul],
        'diferencial_insolacao_porta_sul': [porta.diferencial_insolacao_sul],
        'area_porta_leste': [porta.area_porta_leste],
        'coeficiente_porta_leste': [porta.coeficiente_porta_leste],
        'tipo_porta_leste': [porta.tipo_porta_leste],
        'diferencial_insolacao_porta_leste': [porta.diferencial_insolacao_leste],
        'area_porta_oeste': [porta.area_porta_oeste],
        'coeficiente_porta_oeste': [porta.coeficiente_porta_oeste],
        'tipo_porta_oeste': [porta.tipo_porta_oeste],
        'diferencial_insolacao_porta_oeste': [porta.diferencial_insolacao_oeste],

        # Telhado
        'tipo_telhado': [telhado.tipo_telhado],
        'coeficiente_transmissao_telhado': [telhado.coeficiente_telhado],
        'area_telhado': [telhado.area_telhado],
        'diferencial_insolacao_telhado': [telhado.diferencial_insolacao_telhado],

        # Dados Térmicos
        'calor_sensivel_pessoa': [termico.calor_sensivel_pessoa],
        'calor_latente_pessoa': [termico.calor_latente_pessoa],
        'numero_pessoas': [termico.numero_pessoas],
        'taxa_iluminacao': [termico.taxa_iluminacao],
        'dissipacao_equipamentos': [termico.dissipacao_equipamentos],
        'pe_direito': [termico.pe_direito],
        'area_piso': [termico.area_piso],
        'temperatura_interna': [termico.temperatura_interna],
        'umidade_relativa_interna': [termico.umidade_relativa_interna],
        'umidade_absoluta_interna': [termico.umidade_absoluta_interna],
        'taxa_renovacao': [termico.taxa_renovacao],
    }

    df = pd.DataFrame(dados)
    caminho_csv = os.path.join(caminho_base, f"{nome_ambiente}_dados.csv")
    df.to_csv(caminho_csv, index=False)
    return df



########################################
# FUNÇÃO PARA GERAÇÃO DE RELATÓRIO DOCX (POR AMBIENTE)
########################################
from docx.shared import Pt, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
from cag.middleware import get_current_request

def gerar_relatorio_docx(projeto, ambiente, dados_ambiente, caminho_grafico,
                         aparelhos_recomendados, df_dados_ambiente, tipo_aparelho="hiwall"):
    """
    Gera um arquivo DOCX contendo:
      - Informações do projeto
      - Dados do ambiente
      - Gráfico de carga térmica
      - Aparelhos recomendados
      - Sistema de renovação de ar (imagem + dados estáticos de exemplo)
    Retorna o caminho do arquivo .docx gerado.
    """

    # Cria o documento
    doc = Document()

    # ---------------------
    # INSERE MARCA D'ÁGUA SE FOR TESTE
    # ---------------------
    request = get_current_request()  # Obtém o request atual
    if request and request.user.tenant.schema_name == "teste":
        for section in doc.sections:
            header = section.header
            header_paragraph = header.paragraphs[0] if header.paragraphs else header.add_paragraph()
            header_paragraph.text = "VERSÃO DE TESTE – NÃO USAR COMERCIALMENTE"
            header_paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
            run = header_paragraph.runs[0]
            run.font.size = Pt(36)
            run.font.color.rgb = RGBColor(200, 200, 200)  # Cinza claro

    # Título
    doc.add_heading('Relatório de Carga Térmica e Equipamentos', level=1)
    doc.add_paragraph(f'Projeto: {projeto.nome_projeto}')
    doc.add_paragraph(f'Cidade: {projeto.cidade}')
    doc.add_paragraph(f'Coordenadas: ({projeto.latitude}, {projeto.longitude})')
    doc.add_paragraph(f'Data de Criação: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}')
    doc.add_paragraph('_' * 80)

    # Ambiente
    doc.add_heading('Dados do Ambiente', level=2)
    if df_dados_ambiente is not None and not df_dados_ambiente.empty:
        tabela = doc.add_table(rows=1, cols=2)
        tabela.style = 'Table Grid'
        hdr_cells = tabela.rows[0].cells
        hdr_cells[0].text = 'Parâmetro'
        hdr_cells[1].text = 'Valor'
        for col, val in df_dados_ambiente.iloc[0].items():
            row_cells = tabela.add_row().cells
            row_cells[0].text = str(col)
            row_cells[1].text = str(val)
    else:
        doc.add_paragraph("Dados do ambiente não encontrados.")

    # Gráfico de Carga Térmica
    doc.add_paragraph('\nGráfico de Carga Térmica:')
    if os.path.exists(caminho_grafico):
        doc.add_picture(caminho_grafico, width=Inches(5))
    else:
        doc.add_paragraph("(Gráfico não disponível)")

    # Aparelhos recomendados
    doc.add_heading('Aparelhos Recomendados', level=2)
    doc.add_paragraph(f"Tipo de Aparelho Selecionado: {tipo_aparelho.capitalize()}")

    # Imagem do aparelho
    imagens = {
        "hiwall": os.path.join(settings.BASE_DIR, "static", "imagens", "hi-wall-02.jpg"),
        "tipoduto": os.path.join(settings.BASE_DIR, "static", "imagens", "PDuto_Inverter.jpg"),
        "cassete4vias": os.path.join(settings.BASE_DIR, "static", "imagens", "PCassete_Inverter.jpg"),
    }
    caminho_imagem_aparelho = imagens.get(tipo_aparelho)
    if caminho_imagem_aparelho and os.path.exists(caminho_imagem_aparelho):
        doc.add_picture(caminho_imagem_aparelho, width=Inches(3))
    else:
        doc.add_paragraph("(Imagem do aparelho não disponível)")

    # Tabela de equipamentos
    if aparelhos_recomendados and isinstance(aparelhos_recomendados, list):
        tabela = doc.add_table(rows=1, cols=6)
        tabela.style = 'Table Grid'
        hdr_cells = tabela.rows[0].cells
        headers = ["Modelo", "Cap. Resf.", "Cap. Aque.", "Alimentação", "Tubulação", "Potência"]
        for i, header in enumerate(headers):
            hdr_cells[i].text = header

        for aparelho in aparelhos_recomendados:
            if isinstance(aparelho, dict):
                row_cells = tabela.add_row().cells
                row_cells[0].text = aparelho.get('modelo', 'N/A')
                row_cells[1].text = f"{aparelho.get('capacidade_resfriamento_btu', 'N/A')} BTU/h"
                row_cells[2].text = f"{aparelho.get('capacidade_aquecimento_btu', 'N/A')} BTU/h"
                row_cells[3].text = aparelho.get('fonte_alimentacao', 'N/A')
                row_cells[4].text = aparelho.get('tubulacao_refrigerante_liquido_gas_mm', 'N/A')
                row_cells[5].text = aparelho.get('potencia_motor_w', 'N/A')
    else:
        doc.add_paragraph("Nenhum aparelho recomendado foi encontrado.")

    # Sistema de Renovação de Ar
    doc.add_heading('Sistema de Renovação de Ar', level=2)
    doc.add_paragraph("Vazão Total Necessária (Exemplo): N/A m³/h")

    imagem_renovador = os.path.join(settings.BASE_DIR, "static", "imagens", "renovador.jpg")
    if os.path.exists(imagem_renovador):
        doc.add_picture(imagem_renovador, width=Inches(3))
    else:
        doc.add_paragraph("(Imagem do renovador não disponível)")

    # Salva o DOCX
    caminho_docx = os.path.join(settings.BASE_DIR, "arquivos_relatorios", f"{projeto.nome_projeto}_relatorio_{ambiente.nome_ambiente}.docx")
    os.makedirs(os.path.dirname(caminho_docx), exist_ok=True)
    doc.save(caminho_docx)

    return caminho_docx


########################################
# VIEW: SALVAR TIPO DE APARELHO
########################################
@login_required
def salvar_tipo_aparelho(request, projeto_id, ambiente_nome):
    if request.user.is_authenticated and request.user.tenant:
        connection.set_schema(request.user.tenant.schema_name)

    if request.method == "POST":
        tipo_aparelho = request.POST.get("tipo_aparelho")
        projeto = get_object_or_404(Projeto, id=projeto_id)
        ambiente = get_object_or_404(Ambiente, projeto=projeto, nome_ambiente=ambiente_nome)

        ambiente.tipo_aparelho = tipo_aparelho
        ambiente.save()

        messages.success(request, "Tipo de aparelho salvo com sucesso!!!")
        return redirect(reverse("lista_projetos_ambientes", kwargs={"projeto_id": projeto_id, "ambiente_nome": ambiente_nome}))


#
#
# marca d'agua

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)




########################################
# VIEW: GERAR RELATÓRIO DE AMBIENTE (DOCX)
########################################
@login_required
def gerar_relatorio_ambiente(request, projeto_id, ambiente_id):
    """
    Gera o relatório DOCX de um ambiente específico e devolve como download,
    incluindo dados do ambiente, gráfico, aparelhos de ar condicionado e
    sistema de renovação de ar.
    """
    # ---------------------
    # CONFIGURAÇÕES E DADOS INICIAIS
    # ---------------------
    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)
    ambiente = get_object_or_404(Ambiente, id=ambiente_id)

    # Carrega os objetos relacionados ao Ambiente
    parede = get_object_or_404(Parede, ambiente=ambiente)
    vidro = get_object_or_404(Vidro, ambiente=ambiente)
    porta = get_object_or_404(Porta, ambiente=ambiente)
    telhado = get_object_or_404(Telhado, ambiente=ambiente)
    termico = get_object_or_404(DadosTermicos, ambiente=ambiente)

    # ---------------------
    # CARREGA DADOS TÉRMICOS (XLSX)
    # ---------------------
    caminho_xlsx = os.path.join(
        settings.BASE_DIR,
        f"/var/www/html/cagpublico/cag/arquivos_cargas_termicas/projeto_{projeto.nome_projeto}",
        f"{ambiente.nome_ambiente}_resultados_termicos.xlsx"
    )
    if os.path.exists(caminho_xlsx):
        df = pd.read_excel(caminho_xlsx, engine="openpyxl")
        dados_ambiente = {
            'carga_termica_total_ambiente_max': df['Carga Térmica Total Ambiente'].max(),
            'somatorio_carga_sensivel_total': df['Somatório Carga Sensível Total'],
            'somatorio_carga_latente_total': df['Somatório Carga Latente Total']
        }
    else:
        dados_ambiente = {
            'carga_termica_total_ambiente_max': "N/A",
            'somatorio_carga_sensivel_total': "N/A",
            'somatorio_carga_latente_total': "N/A"
        }

    # ---------------------
    # SALVA DADOS EM CSV (caso necessário para histórico)
    # ---------------------
    df_dados_ambiente = salvar_dados_em_csv(
        projeto,
        ambiente.nome_ambiente,
        parede,
        vidro,
        porta,
        telhado,
        termico
    )

    # ---------------------
    # GERA GRÁFICO DE CARGA TÉRMICA (caso XLSX exista)
    # ---------------------
    caminho_grafico = os.path.join(
        settings.BASE_DIR,
        "media",
        f"grafico_carga_termica_{ambiente.nome_ambiente}.png"
    )
    if os.path.exists(caminho_xlsx):
        gerar_grafico_carga_termica(df, caminho_grafico)

    # ---------------------
    # OBTÉM APARELHOS RECOMENDADOS
    # ---------------------
    tipo_aparelho = ambiente.tipo_aparelho
    if dados_ambiente['carga_termica_total_ambiente_max'] != "N/A":
        aparelhos_recomendados = determinar_aparelho(
            dados_ambiente['carga_termica_total_ambiente_max'],
            tipo_aparelho
        )
    else:
        aparelhos_recomendados = []

    # ---------------------
    # CRIA O DOCUMENTO (DOCX)
    # ---------------------
    doc = Document()


    # ---------------------
    # INSERE MARCA D'ÁGUA SE FOR TESTE
    # ---------------------
    if request.user.tenant.schema_name == "teste":
        inserir_marca_dagua(doc)


    # ---------------------
    # CABEÇALHO / INFORMAÇÕES DO AMBIENTE
    # ---------------------
    header_section = doc.sections[0].header  # Obtém o cabeçalho da primeira seção
    header_paragraph = header_section.paragraphs[0] if header_section.paragraphs else header_section.add_paragraph()

    # Adiciona a logo ao cabeçalho
    logo_path = "/var/www/html/cagpublico/cag/static/relatorio/grf_graph_logo.png"
    if os.path.exists(logo_path):
        run = header_paragraph.add_run()
        run.add_picture(logo_path, width=Inches(2.5))  # Ajuste do tamanho da logo
        header_paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER  # Centraliza a logo

    # Adiciona as informações do ambiente abaixo da logo
    header_paragraph.add_run("\nRelatório do Ambiente\n").bold = True
    header_paragraph.add_run(f"Ambiente: {ambiente.nome_ambiente}\n")
    header_paragraph.add_run(f"Projeto: {projeto.nome_projeto}\n")
    header_paragraph.add_run(f"Cidade: {projeto.cidade}\n")
    header_paragraph.add_run(f"Data de geração: {datetime.now().strftime('%d/%m/%Y')}\n")

    # Linha separadora
    doc.add_paragraph("_" * 80)


    # ---------------------
    # DADOS DO AMBIENTE
    # ---------------------
    doc.add_heading("Dados do Ambiente", level=1)
    if df_dados_ambiente is not None and not df_dados_ambiente.empty:
        tabela = doc.add_table(rows=1, cols=2)
        tabela.style = 'Table Grid'
        hdr_cells = tabela.rows[0].cells
        hdr_cells[0].text = 'Parâmetro'
        hdr_cells[1].text = 'Valor'
        for col, val in df_dados_ambiente.iloc[0].items():
            row_cells = tabela.add_row().cells
            row_cells[0].text = str(col)
            row_cells[1].text = str(val)
    else:
        doc.add_paragraph("Dados do ambiente não encontrados.")

    # ---------------------
    # GRÁFICO DE CARGA TÉRMICA
    # ---------------------
    doc.add_heading("Gráfico de Carga Térmica (em TR)", level=1)
    if os.path.exists(caminho_grafico):
        doc.add_picture(caminho_grafico, width=Inches(5))
    else:
        doc.add_paragraph("(Gráfico não disponível)")

    # ---------------------
    # APARELHOS DE AR CONDICIONADO RECOMENDADOS
    # ---------------------
    doc.add_heading("Aparelhos de Ar Condicionado Recomendados", level=1)
    doc.add_paragraph(f"Tipo de Aparelho Selecionado: {tipo_aparelho.capitalize()}")

    # Exibe imagem do aparelho selecionado (se existir)
    imagens = {
        "hiwall": os.path.join(settings.BASE_DIR, "static", "imagens", "hi-wall-02.jpg"),
        "tipoduto": os.path.join(settings.BASE_DIR, "static", "imagens", "PDuto_Inverter.jpg"),
        "cassete4vias": os.path.join(settings.BASE_DIR, "static", "imagens", "PCassete_Inverter.jpg"),
    }
    caminho_imagem_aparelho = imagens.get(tipo_aparelho)
    if caminho_imagem_aparelho and os.path.exists(caminho_imagem_aparelho):
        doc.add_picture(caminho_imagem_aparelho, width=Inches(3))
    else:
        doc.add_paragraph("(Imagem do aparelho não disponível)")

    # Tabela dos aparelhos recomendados
    if aparelhos_recomendados and isinstance(aparelhos_recomendados, list):
        tabela_ar = doc.add_table(rows=1, cols=6)
        tabela_ar.style = 'Table Grid'
        hdr_cells = tabela_ar.rows[0].cells
        headers = [
            "Modelo",
            "Cap. Resf. (BTU/h)",
            "Cap. Aque. (BTU/h)",
            "Alimentação",
            "Tubulação (mm)",
            "Potência (W)"
        ]
        for i, header in enumerate(headers):
            hdr_cells[i].text = header

        for aparelho in aparelhos_recomendados:
            if isinstance(aparelho, dict):
                row_cells = tabela_ar.add_row().cells
                row_cells[0].text = aparelho.get('modelo', 'N/A')
                row_cells[1].text = f"{aparelho.get('capacidade_resfriamento_btu', 'N/A')}"
                row_cells[2].text = f"{aparelho.get('capacidade_aquecimento_btu', 'N/A')}"
                row_cells[3].text = aparelho.get('fonte_alimentacao', 'N/A')
                row_cells[4].text = aparelho.get('tubulacao_refrigerante_liquido_gas_mm', 'N/A')
                row_cells[5].text = str(aparelho.get('potencia_motor_w', 'N/A'))
    else:
        doc.add_paragraph("Nenhum aparelho recomendado foi encontrado.")

    # ---------------------
    # SISTEMA DE RENOVAÇÃO DE AR
    # ---------------------
    doc.add_heading("Sistema de Renovação de Ar", level=1)

    if df_dados_ambiente is not None and not df_dados_ambiente.empty:
        # Recupera dados necessários
        area_piso = df_dados_ambiente['area_piso'].iloc[0]
        pe_direito = df_dados_ambiente['pe_direito'].iloc[0]
        numero_pessoas = df_dados_ambiente['numero_pessoas'].iloc[0]
        taxa_renovacao = df_dados_ambiente['taxa_renovacao'].iloc[0]
    else:
        area_piso, pe_direito, numero_pessoas, taxa_renovacao = 0, 0, 0, 0

    # Seleciona aparelho(s) de renovação
    renovador_info = escolher_aparelho_renovacao(
        area_piso,
        pe_direito,
        numero_pessoas,
        taxa_renovacao
    )
    vazao_necessaria = renovador_info.get('vazao_total_ar_exterior', 0)

    doc.add_paragraph(f"Vazão Total Necessária para Renovação: {vazao_necessaria:.2f} m³/h")

    # Exibe imagem genérica do renovador (se existir)
    imagem_renovador = os.path.join(settings.BASE_DIR, "static", "imagens", "renovador.jpg")
    if os.path.exists(imagem_renovador):
        doc.add_picture(imagem_renovador, width=Inches(3))
    else:
        doc.add_paragraph("(Imagem do renovador não disponível)")

    # Tabela com a melhor combinação de renovadores, se houver
    combinacao_renovadores = renovador_info.get('melhor_comb', [])
    if combinacao_renovadores:
        doc.add_paragraph(f"Combinação de {len(combinacao_renovadores)} Renovador(es) Selecionada.")
        tabela_rn = doc.add_table(rows=1, cols=7)
        tabela_rn.style = 'Table Grid'
        hdr_cells = tabela_rn.rows[0].cells
        headers = ["Aparelho", "Modelo", "Velocidade", "Vazão", "Pressão", "Nível Sonoro", "Potência"]
        for i, header in enumerate(headers):
            hdr_cells[i].text = header

        vazao_total_combinada = 0
        for idx, renovador in enumerate(combinacao_renovadores, 1):
            row_cells = tabela_rn.add_row().cells
            modelo_ren = renovador.get('modelo', 'N/A')
            velocidade = renovador['velocidades'][-1]  # Utiliza a velocidade máxima
            vazao_total_combinada += velocidade['vazao_maxima_m3h']

            row_cells[0].text = str(idx)
            row_cells[1].text = modelo_ren
            row_cells[2].text = velocidade['nome']
            row_cells[3].text = f"{velocidade['vazao_maxima_m3h']} m³/h"
            row_cells[4].text = f"{velocidade['pressao_maxima_mmca']} mmCA"
            row_cells[5].text = f"{velocidade['nivel_pressao_sonora_dba']} dBA"
            row_cells[6].text = f"{velocidade['potencia_motor_w']} W"

        doc.add_paragraph(f"Vazão Total da Combinação: {vazao_total_combinada} m³/h")
        if vazao_total_combinada >= vazao_necessaria:
            doc.add_paragraph("✓ A combinação atende à necessidade de renovação de ar.")
        else:
            doc.add_paragraph("⚠ A combinação não atende completamente à necessidade de renovação de ar.")
    else:
        doc.add_paragraph("Nenhum renovador foi selecionado para este ambiente.")

    # ---------------------
    # FINALIZA E RETORNA O ARQUIVO DOCX
    # ---------------------
    nome_docx = f"{ambiente.nome_ambiente}_relatorio.docx"
    caminho_docx = os.path.join(settings.BASE_DIR, "arquivos_relatorios", nome_docx)
    os.makedirs(os.path.dirname(caminho_docx), exist_ok=True)
    doc.save(caminho_docx)

    # Retorna o arquivo DOCX como resposta
    with open(caminho_docx, "rb") as f:
        response = HttpResponse(
            f.read(),
            content_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document"
        )
        response["Content-Disposition"] = f'attachment; filename="{os.path.basename(caminho_docx)}"'
    return response



########################################
# VIEW: GERAR RELATÓRIO COMPLETO DO PROJETO (DOCX)
########################################
@login_required
def gerar_relatorio_projeto(request, projeto_id):
    """
    Gera um relatório DOCX para todos os ambientes do projeto, incluindo:
      - Capa
      - Índice (simplificado)
      - Seção de cada ambiente (dados, gráfico, aparelhos, renovador)
      - Resumo final de todos os aparelhos
    """
    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)
    ambientes = Ambiente.objects.filter(projeto=projeto)

    # Verifica se há ao menos um ambiente
    if not ambientes.exists():
        messages.error(request, "Não há ambientes cadastrados neste projeto.")
        return redirect('lista_projetos')

    ambiente_exemplo = ambientes.first()  # Usado apenas para o cabeçalho inicial

    # Cria o documento
    doc = Document()

    # ---------------------
    # INSERE MARCA D'ÁGUA SE FOR TESTE
    # ---------------------
    if request.user.tenant.schema_name == "teste":
        inserir_marca_dagua(doc)

    # ---------------------
    # CAPA
    # ---------------------
    doc.add_heading("Relatório do Projeto", level=0)
    doc.add_paragraph(f"Projeto: {projeto.nome_projeto}")
    doc.add_paragraph(f"Cidade: {projeto.cidade}")
    doc.add_paragraph(f"Coordenadas: ({projeto.latitude}, {projeto.longitude})")
    doc.add_paragraph(f"Data de geração: {datetime.now().strftime('%d/%m/%Y')}")
    doc.add_paragraph("_" * 80)

    # ---------------------
    # CABEÇALHO DO DOCUMENTO (com nome do 1º ambiente só para referência visual)
    # ---------------------
    header_section = doc.sections[0].header
    header_paragraph = header_section.paragraphs[0] if header_section.paragraphs else header_section.add_paragraph()

    # Logo
    logo_path = "/var/www/html/cagpublico/cag/static/relatorio/grf_graph_logo.png"
    if os.path.exists(logo_path):
        run = header_paragraph.add_run()
        run.add_picture(logo_path, width=Inches(2.5))
        header_paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER

    # Informações básicas
    header_paragraph.add_run("\nRelatório do Projeto\n").bold = True
    header_paragraph.add_run(f"Ambiente (exemplo): {ambiente_exemplo.nome_ambiente}\n")
    header_paragraph.add_run(f"Projeto: {projeto.nome_projeto}\n")
    header_paragraph.add_run(f"Cidade: {projeto.cidade}\n")
    header_paragraph.add_run(f"Data de geração: {datetime.now().strftime('%d/%m/%Y')}\n")

    doc.add_paragraph("_" * 80)

    # ---------------------
    # ÍNDICE (simplificado)
    # ---------------------
    doc.add_heading("Índice", level=1)
    for i, ambiente in enumerate(ambientes, start=1):
        doc.add_paragraph(f"{i}. Ambiente: {ambiente.nome_ambiente}", style='List Number')

    doc.add_page_break()

    # Armazenam dados para resumo final
    aparelhos_selecionados = []
    renovadores_selecionados = []

    # ---------------------
    # LOOP DE AMBIENTES
    # ---------------------
    for ambiente in ambientes:
        doc.add_heading(f"Ambiente: {ambiente.nome_ambiente}", level=1)

        # Carrega os objetos relacionados
        parede = get_object_or_404(Parede, ambiente=ambiente)
        vidro = get_object_or_404(Vidro, ambiente=ambiente)
        porta = get_object_or_404(Porta, ambiente=ambiente)
        telhado = get_object_or_404(Telhado, ambiente=ambiente)
        termico = get_object_or_404(DadosTermicos, ambiente=ambiente)

        # Carrega dados térmicos
        caminho_xlsx = os.path.join(
            settings.BASE_DIR,
            f"/var/www/html/cagpublico/cag/arquivos_cargas_termicas/projeto_{projeto.nome_projeto}",
            f"{ambiente.nome_ambiente}_resultados_termicos.xlsx"
        )
        if os.path.exists(caminho_xlsx):
            df = pd.read_excel(caminho_xlsx, engine="openpyxl")
            dados_ambiente = {
                'carga_termica_total_ambiente_max': df['Carga Térmica Total Ambiente'].max(),
                'somatorio_carga_sensivel_total': df['Somatório Carga Sensível Total'],
                'somatorio_carga_latente_total': df['Somatório Carga Latente Total']
            }
        else:
            dados_ambiente = {
                'carga_termica_total_ambiente_max': "N/A",
                'somatorio_carga_sensivel_total': "N/A",
                'somatorio_carga_latente_total': "N/A"
            }

        # Salva dados ambiente (CSV)
        df_dados_ambiente = salvar_dados_em_csv(
            projeto,
            ambiente.nome_ambiente,
            parede,
            vidro,
            porta,
            telhado,
            termico
        )

        # Gera gráfico
        caminho_grafico = os.path.join(
            settings.BASE_DIR,
            "media",
            f"grafico_carga_termica_{ambiente.nome_ambiente}.png"
        )
        if os.path.exists(caminho_xlsx):
            gerar_grafico_carga_termica(df, caminho_grafico)

        # ---------------------
        # DADOS DO AMBIENTE
        # ---------------------
        doc.add_heading("Dados do Ambiente", level=2)
        if df_dados_ambiente is not None and not df_dados_ambiente.empty:
            tabela_dados = doc.add_table(rows=1, cols=2)
            tabela_dados.style = 'Table Grid'
            hdr_cells = tabela_dados.rows[0].cells
            hdr_cells[0].text = 'Parâmetro'
            hdr_cells[1].text = 'Valor'
            for col, val in df_dados_ambiente.iloc[0].items():
                row_cells = tabela_dados.add_row().cells
                row_cells[0].text = str(col)
                row_cells[1].text = str(val)
        else:
            doc.add_paragraph("Dados do ambiente não encontrados.")

        # ---------------------
        # GRÁFICO DE CARGA TÉRMICA
        # ---------------------
        doc.add_heading("Gráfico de Carga Térmica Total do Ambiente (em TR)", level=2)
        if os.path.exists(caminho_grafico):
            doc.add_picture(caminho_grafico, width=Inches(5))
        else:
            doc.add_paragraph("(Gráfico não disponível)")

        # ---------------------
        # APARELHOS DE AR CONDICIONADO RECOMENDADOS
        # ---------------------
        doc.add_heading("Aparelhos de Ar Condicionado Recomendados", level=2)
        tipo_aparelho = ambiente.tipo_aparelho
        doc.add_paragraph(f"Tipo de Aparelho Selecionado: {tipo_aparelho.capitalize()}")

        # Imagem do aparelho
        imagens = {
            "hiwall": os.path.join(settings.BASE_DIR, "static", "imagens", "hi-wall-02.jpg"),
            "tipoduto": os.path.join(settings.BASE_DIR, "static", "imagens", "PDuto_Inverter.jpg"),
            "cassete4vias": os.path.join(settings.BASE_DIR, "static", "imagens", "PCassete_Inverter.jpg"),
        }
        caminho_imagem_aparelho = imagens.get(tipo_aparelho)
        if caminho_imagem_aparelho and os.path.exists(caminho_imagem_aparelho):
            doc.add_picture(caminho_imagem_aparelho, width=Inches(3))
        else:
            doc.add_paragraph("(Imagem do aparelho não disponível)")

        # Tabela de aparelhos
        if dados_ambiente['carga_termica_total_ambiente_max'] != "N/A":
            recomendados = determinar_aparelho(
                dados_ambiente['carga_termica_total_ambiente_max'],
                tipo_aparelho
            )
        else:
            recomendados = []

        if recomendados and isinstance(recomendados, list):
            tabela_ar = doc.add_table(rows=1, cols=6)
            tabela_ar.style = 'Table Grid'
            hdr_cells = tabela_ar.rows[0].cells
            headers = [
                "Modelo",
                "Cap. Resf. (BTU/h)",
                "Cap. Aque. (BTU/h)",
                "Alimentação",
                "Tubulação (mm)",
                "Potência (W)"
            ]
            for i, header in enumerate(headers):
                hdr_cells[i].text = header

            for aparelho in recomendados:
                if isinstance(aparelho, dict):
                    row_cells = tabela_ar.add_row().cells
                    row_cells[0].text = aparelho.get('modelo', 'N/A')
                    row_cells[1].text = str(aparelho.get('capacidade_resfriamento_btu', 'N/A'))
                    row_cells[2].text = str(aparelho.get('capacidade_aquecimento_btu', 'N/A'))
                    row_cells[3].text = aparelho.get('fonte_alimentacao', 'N/A')
                    row_cells[4].text = aparelho.get('tubulacao_refrigerante_liquido_gas_mm', 'N/A')
                    row_cells[5].text = str(aparelho.get('potencia_motor_w', 'N/A'))

                    # Guarda para o resumo final
                    aparelhos_selecionados.append(aparelho)
        else:
            doc.add_paragraph("Nenhum aparelho recomendado foi encontrado.")

        # ---------------------
        # SISTEMA DE RENOVAÇÃO DE AR
        # ---------------------
        doc.add_heading("Sistema de Renovação de Ar", level=2)

        # Cálculo do renovador
        if df_dados_ambiente is not None and not df_dados_ambiente.empty:
            area_piso = df_dados_ambiente['area_piso'].iloc[0]
            pe_direito = df_dados_ambiente['pe_direito'].iloc[0]
            numero_pessoas = df_dados_ambiente['numero_pessoas'].iloc[0]
            taxa_renovacao = df_dados_ambiente['taxa_renovacao'].iloc[0]
        else:
            area_piso, pe_direito, numero_pessoas, taxa_renovacao = 0, 0, 0, 0

        renovador_info = escolher_aparelho_renovacao(area_piso, pe_direito, numero_pessoas, taxa_renovacao)
        vazao_necessaria = renovador_info.get('vazao_total_ar_exterior', 0)

        doc.add_paragraph(f"Vazão Total Necessária: {vazao_necessaria:.2f} m³/h")

        # Imagem do renovador
        imagem_renovador = os.path.join(settings.BASE_DIR, "static", "imagens", "renovador.jpg")
        if os.path.exists(imagem_renovador):
            doc.add_picture(imagem_renovador, width=Inches(3))
        else:
            doc.add_paragraph("(Imagem do renovador não disponível)")

        combinacao_renovadores = renovador_info.get('melhor_comb', [])
        if combinacao_renovadores:
            doc.add_paragraph(f"Combinação de {len(combinacao_renovadores)} Renovador(es) Selecionada.")
            tabela_rn = doc.add_table(rows=1, cols=7)
            tabela_rn.style = 'Table Grid'
            hdr_cells = tabela_rn.rows[0].cells
            headers = ["Aparelho", "Modelo", "Velocidade", "Vazão", "Pressão", "Nível Sonoro", "Potência"]
            for i, header in enumerate(headers):
                hdr_cells[i].text = header

            vazao_total_combinada = 0
            for idx, renovador in enumerate(combinacao_renovadores, 1):
                row_cells = tabela_rn.add_row().cells
                modelo_ren = renovador.get('modelo', 'N/A')
                velocidade = renovador['velocidades'][-1]  # usando a velocidade máxima
                vazao_total_combinada += velocidade['vazao_maxima_m3h']
                row_cells[0].text = str(idx)
                row_cells[1].text = modelo_ren
                row_cells[2].text = velocidade['nome']
                row_cells[3].text = f"{velocidade['vazao_maxima_m3h']} m³/h"
                row_cells[4].text = f"{velocidade['pressao_maxima_mmca']} mmCA"
                row_cells[5].text = f"{velocidade['nivel_pressao_sonora_dba']} dBA"
                row_cells[6].text = f"{velocidade['potencia_motor_w']} W"

                # Guarda para resumo final
                renovadores_selecionados.append(renovador)

            doc.add_paragraph(f"Vazão Total da Combinação: {vazao_total_combinada} m³/h")
            if vazao_total_combinada >= vazao_necessaria:
                doc.add_paragraph("✓ A combinação atende à necessidade de renovação de ar.")
            else:
                doc.add_paragraph("⚠ A combinação não atende completamente à necessidade de renovação de ar.")
        else:
            doc.add_paragraph("Nenhum renovador foi selecionado para este ambiente.")



    # ---------------------
    # RESUMO FINAL
    # ---------------------
    doc.add_heading("Resumo Final dos Equipamentos", level=1)

    # 1. Resumo de Aparelhos de Ar Condicionado
    doc.add_heading("Aparelhos de Ar Condicionado", level=2)
    # Agrupa por modelo
    aparelhos_por_modelo = {}
    for aparelho in aparelhos_selecionados:
        modelo = aparelho.get('modelo', 'N/A')
        aparelhos_por_modelo[modelo] = aparelhos_por_modelo.get(modelo, 0) + 1

    if aparelhos_por_modelo:
        tabela_ar = doc.add_table(rows=1, cols=2)
        tabela_ar.style = 'Table Grid'
        hdr_cells = tabela_ar.rows[0].cells
        hdr_cells[0].text = "Modelo"
        hdr_cells[1].text = "Quantidade"
        for modelo, qtd in aparelhos_por_modelo.items():
            row_cells = tabela_ar.add_row().cells
            row_cells[0].text = modelo
            row_cells[1].text = str(qtd)
    else:
        doc.add_paragraph("Nenhum aparelho de ar condicionado selecionado.")

    doc.add_paragraph("")

    # 2. Resumo de Renovadores
    doc.add_heading("Renovadores de Ar", level=2)
    renovadores_agrupados = {}
    for renovador in renovadores_selecionados:
        modelo = renovador.get('modelo', 'N/A')
        velocidade = renovador['velocidades'][-1]['nome']
        chave = f"{modelo} - {velocidade}"
        renovadores_agrupados[chave] = renovadores_agrupados.get(chave, 0) + 1

    if renovadores_agrupados:
        tabela_rn = doc.add_table(rows=1, cols=2)
        tabela_rn.style = 'Table Grid'
        hdr_cells = tabela_rn.rows[0].cells
        hdr_cells[0].text = "Modelo / Velocidade"
        hdr_cells[1].text = "Quantidade"

        for mv, qtd in renovadores_agrupados.items():
            row_cells = tabela_rn.add_row().cells
            row_cells[0].text = mv
            row_cells[1].text = str(qtd)
    else:
        doc.add_paragraph("Nenhum renovador selecionado.")

    # ---------------------
    # SALVA O DOCX FINAL
    # ---------------------
    caminho_docx_projeto = os.path.join(
        settings.BASE_DIR,
        "arquivos_relatorios",
        f"{projeto.nome_projeto}_relatorio_projeto.docx"
    )
    os.makedirs(os.path.dirname(caminho_docx_projeto), exist_ok=True)
    doc.save(caminho_docx_projeto)

    # Retorna como download
    with open(caminho_docx_projeto, "rb") as f:
        response = HttpResponse(
            f.read(),
            content_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document"
        )
        response["Content-Disposition"] = f'attachment; filename="{os.path.basename(caminho_docx_projeto)}"'
    return response





from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.db import connection
from django.core.exceptions import PermissionDenied
from calculotermica.relatorio_completo_projeto import gerar_relatorio_todos_ambientes


@login_required
def gerar_relatorio_completo(request, projeto_id):
    """
    View para gerar o relatório completo do projeto com todos os ambientes.
    """
    try:
        if not request.user.tenant:
            raise PermissionDenied("Usuário sem tenant associado.")

        # Define o esquema correto para o tenant do usuário
        connection.set_schema(request.user.tenant.schema_name)

        # Obtém o projeto
        projeto = get_object_or_404(Projeto, id=projeto_id)

        # Chama a função que gera o relatório
        response = gerar_relatorio_todos_ambientes(request, projeto_id)

        # Se a função retorna um HttpResponse, passamos direto para o navegador
        if isinstance(response, HttpResponse):
            return response

        messages.error(request, "Erro ao gerar o relatório.")
        return render(request, 'centraltermica/erro_relatorio.html', {'projeto': projeto})

    except Exception as e:
        messages.error(request, f"Erro ao gerar o relatório: {str(e)}")
        return render(request, 'centraltermica/erro_relatorio.html', {'erro': str(e)})
