import os
import json
from datetime import date, datetime
from decimal import Decimal, InvalidOperation

from django.shortcuts import render, redirect, get_object_or_404
from django.http import JsonResponse
from django.urls import reverse
from django.contrib.auth.decorators import login_required
from django.contrib.auth import logout
from django.contrib import messages
from django.views.decorators.http import require_POST
from django.db import connection
from django.db.models import Sum

from .forms import ObraForm
from .models import Obra, FotoObra, Pagamento, EtapaObra, GrupoAtividade, Foto
from .materiais import materiais
from .etapas import ETAPAS_PADRAO
from .uploads import user_file_path, salvar_arquivo_com_limite, atingiu_limite_hd, uso_hd_formatado
from .relatorio import gerar_relatorio_pdf_api

from .models import DocumentoEtapa
from django.core.files.storage import default_storage
from .uploads import comprimir_imagem

from .decorators import nao_equipe_required

########################################################

@login_required
def logout_view(request):
    logout(request)
    storage = messages.get_messages(request)
    list(storage)  # limpa mensagens anteriores
    messages.info(request, "Você saiu com sucesso.")
    return redirect('login')


########################################################
@nao_equipe_required
@login_required
def minhas_obras(request):
    if request.user.is_authenticated and request.user.tenant:
        connection.set_schema(request.user.tenant.schema_name)

    obras = Obra.objects.filter(usuario=request.user)
    uso_hd = uso_hd_formatado(request.user)  # ✅ pega uso de espaço

    return render(request, 'obras/minhas_obras.html', {
        'obras': obras,
        'uso_hd': uso_hd,
    })

########################################################
@nao_equipe_required
@login_required
def deletar_obra(request, obra_id):
    if request.user.is_authenticated and request.user.tenant:
        connection.set_schema(request.user.tenant.schema_name)

    obra = get_object_or_404(Obra, id=obra_id, usuario=request.user)
    if request.method == 'POST':
        obra.delete()
    return redirect('minhas_obras')


########################################################
@nao_equipe_required
@login_required
def cadastrar_obra(request):
    if request.user.is_authenticated and request.user.tenant:
        connection.set_schema(request.user.tenant.schema_name)

    if request.method == 'POST':
        form = ObraForm(request.POST)
        if form.is_valid():
            nova_obra = form.save(commit=False)
            nova_obra.usuario = request.user  # ✅ associar ao usuário logado
            nova_obra.save()
            return redirect('minhas_obras')
    else:
        form = ObraForm()
    return render(request, 'obras/cadastrar_obra.html', {'form': form})


########################################################

@nao_equipe_required
@login_required
def painel_obra(request, obra_id):
    if request.user.is_authenticated and request.user.tenant:
        connection.set_schema(request.user.tenant.schema_name)

    # Garante que a obra pertence ao usuário logado
    obra = get_object_or_404(Obra, id=obra_id, usuario=request.user)

    # Tempo decorrido
    tempo_decorrido = (
        f"{(date.today() - obra.data_inicio).days} dias" if obra.data_inicio else "—"
    )

    # Pagamentos confirmados e agendados
    pagamentos_feitos = Pagamento.objects.filter(obra=obra, pago=True)
    pagamentos_agendados = Pagamento.objects.filter(obra=obra, pago=False)

    def agrupar_por_data(queryset):
        dados = {}
        for p in queryset:
            data = p.data.strftime('%Y-%m-%d')
            dados[data] = dados.get(data, 0) + float(p.valor)
        return dados

    feitos_por_data = agrupar_por_data(pagamentos_feitos)
    agendados_por_data = agrupar_por_data(pagamentos_agendados)

    total_gasto = sum(feitos_por_data.values())
    total_agendado = sum(agendados_por_data.values())
    orcamento_total = float(obra.orcamento_total or 0)
    saldo = orcamento_total - total_gasto
    percentual = int((total_gasto / orcamento_total) * 100) if orcamento_total else 0

    return render(request, 'obras/painel_obra.html', {
        'obra': obra,
        'orcamento_total': orcamento_total,
        'total_gasto': total_gasto,
        'saldo': saldo,
        'percentual': percentual,
        'tempo_decorrido': tempo_decorrido,
        'feitos_por_data': json.dumps(feitos_por_data),
        'agendados_por_data': json.dumps(agendados_por_data),
        'agendados_total': total_agendado,
    })


########################################################

@nao_equipe_required
@login_required
def pagamentos_obra(request, obra_id):
    if request.user.is_authenticated and request.user.tenant:
        connection.set_schema(request.user.tenant.schema_name)

    obra = get_object_or_404(Obra, id=obra_id, usuario=request.user)
    etapas = EtapaObra.objects.filter(obra=obra).order_by('ordem')
    grupos = list(materiais.keys())

    materiais_lista = [
        {"subgrupo": subgrupo, "nome": item['nome'], "unidade": item['unidade']}
        for subgrupo, itens in materiais.items()
        for item in itens
    ]

    pagamentos_by_etapa = {}
    pagamentos_confirmados = Pagamento.objects.filter(obra=obra, pago=True).order_by("data")
    for p in pagamentos_confirmados:
        if p.etapa:
            eid = str(p.etapa.id)
            pagamentos_by_etapa.setdefault(eid, []).append({
                "tipo": p.tipo,
                "valor": float(p.valor),
                "data": p.data.strftime("%d/%m/%Y"),
                "descricao": p.descricao or "",
                "comprovante_url": p.comprovante.url if p.comprovante else ""
            })

    pagamentos_futuros = Pagamento.objects.filter(obra=obra, pago=False).order_by("data")
    comprovantes = Pagamento.objects.filter(obra=obra, comprovante__isnull=False)

    if request.method == "POST":
        if atingiu_limite_hd(request.user):
            return render(request, 'obras/pagamentos.html', {
                "obra": obra,
                "etapas": etapas,
                "grupos": grupos,
                "materiais_json": json.dumps(materiais_lista),
                "pagamentos_by_etapa_json": json.dumps(pagamentos_by_etapa),
                "pagamentos_futuros": pagamentos_futuros,
                "comprovantes": comprovantes,
                "today": date.today(),
                "erro_hd": "Você atingiu o limite de 800MB. Exclua arquivos ou adquira mais espaço."
            })

        tipo = request.POST.get("tipo")
        etapa = get_object_or_404(EtapaObra, id=request.POST.get("etapa_id"), obra=obra)
        valor_str = request.POST.get("valor", "").replace(".", "").replace(",", ".")
        try:
            valor = Decimal(valor_str)
        except InvalidOperation:
            valor = Decimal("0.00")

        data_pagamento = request.POST.get("data")
        comprovante = request.FILES.get("comprovante")

        grupo_nome = request.POST.get("grupo")
        grupo_obj = None
        if grupo_nome:
            grupo_obj, _ = GrupoAtividade.objects.get_or_create(nome=grupo_nome, tipo='material')

        material_selecionado = request.POST.get("material")
        item_nome = request.POST.get("material_outro") if material_selecionado == "Outro (digitar manualmente)" else material_selecionado

        profissional = request.POST.get("profissional") if tipo == "Profissional" else None
        descricao = profissional if tipo == "Profissional" else item_nome

        quantidade_str = request.POST.get("quantidade")
        quantidade = Decimal(quantidade_str.replace(",", ".")) if quantidade_str else None
        unidade = request.POST.get("unidade") or None
        pago = data_pagamento == str(date.today())

        Pagamento.objects.create(
            obra=obra,
            etapa=etapa,
            grupo=grupo_obj,
            tipo=tipo,
            descricao=descricao,
            material_outro=item_nome if material_selecionado == "Outro (digitar manualmente)" else None,
            valor=valor,
            data=data_pagamento,
            comprovante=comprovante,
            quantidade=quantidade,
            unidade=unidade,
            pago=pago
        )

        return redirect('pagamentos_obra', obra_id=obra.id)

    return render(request, 'obras/pagamentos.html', {
        "obra": obra,
        "etapas": etapas,
        "grupos": grupos,
        "materiais_json": json.dumps(materiais_lista),
        "pagamentos_by_etapa_json": json.dumps(pagamentos_by_etapa),
        "pagamentos_futuros": pagamentos_futuros,
        "comprovantes": comprovantes,
        "today": date.today(),
    })




########################################################

@nao_equipe_required
@login_required
@require_POST
def confirmar_pagamento(request, pagamento_id):
    if request.user.is_authenticated and request.user.tenant:
        connection.set_schema(request.user.tenant.schema_name)

    pagamento = get_object_or_404(Pagamento, id=pagamento_id)

    # Confirma que a obra vinculada ao pagamento pertence ao usuário logado
    if pagamento.obra.usuario != request.user:
        return redirect('pagamentos_obra', obra_id=pagamento.obra.id)  # ou retornar erro 403

    pagamento.pago = True
    pagamento.save()

    return redirect('pagamentos_obra', obra_id=pagamento.obra.id)


########################################################

@nao_equipe_required
@login_required
def etapa_info(request, etapa_id):
    if request.user.is_authenticated and request.user.tenant:
        connection.set_schema(request.user.tenant.schema_name)

    try:
        etapa = EtapaObra.objects.select_related('obra').get(id=etapa_id)
    except EtapaObra.DoesNotExist:
        return JsonResponse({'error': 'Etapa não encontrada'}, status=404)

    # Garante que a etapa pertence ao usuário logado
    if etapa.obra.usuario != request.user:
        return JsonResponse({'error': 'Acesso não autorizado'}, status=403)

    total_pago = (
        etapa.pagamento_set.filter(pago=True)
        .aggregate(total=Sum('valor'))['total'] or 0
    )

    return JsonResponse({
        'profissional': etapa.profissional or '',
        'valor_orcado': float(etapa.valor_orcado or 0),
        'valor_pago': float(total_pago),
    })


########################################################

from django.http import HttpResponseForbidden

@login_required
def fotos_obra(request, obra_id):
    if request.user.is_authenticated and request.user.tenant:
        connection.set_schema(request.user.tenant.schema_name)

    obra = get_object_or_404(Obra, id=obra_id)

    # Verifica se o usuário é o cliente (dono da obra) OU está na equipe da obra
    is_cliente = obra.usuario == request.user
    is_equipe = EquipeObra.objects.filter(obra=obra, usuario=request.user).exists()

    if not (is_cliente or is_equipe):
        return HttpResponseForbidden("Você não tem permissão para acessar esta obra.")

    etapas = EtapaObra.objects.filter(obra=obra)

    if is_cliente:
        voltar_url = reverse('painel_obra', args=[obra.id])
    else:
        voltar_url = reverse('obras_equipe')

    if request.method == 'POST':
        if atingiu_limite_hd(request.user):
            return JsonResponse({
                'success': False,
                'error': 'Você atingiu o limite de 800MB. Exclua arquivos ou adquira mais espaço.'
            }, status=403)

        etapa_id = request.POST.get('etapa_id')
        descricao = request.POST.get('descricao')
        imagem = request.FILES.get('imagem')
        if imagem:
            imagem = comprimir_imagem(imagem)

        etapa = None
        if etapa_id:
            etapa = EtapaObra.objects.filter(id=etapa_id, obra=obra).first()

        if imagem and etapa:
            Foto.objects.create(
                obra=obra,
                etapa=etapa,
                imagem=imagem,
                descricao=descricao or ""
            )
        return redirect('fotos_obra', obra_id=obra.id)

    fotos = Foto.objects.filter(obra=obra).order_by('-data_envio')
    fotos_by_etapa = {}
    for foto in fotos:
        eid = str(foto.etapa.id) if foto.etapa else "sem_etapa"
        if eid not in fotos_by_etapa:
            fotos_by_etapa[eid] = []
        fotos_by_etapa[eid].append({
            'url': foto.imagem.url,
            'descricao': foto.descricao,
            'data_envio': foto.data_envio.strftime('%d/%m/%Y %H:%M'),
        })

    context = {
        'obra': obra,
        'etapas': etapas,
        'fotos_by_etapa_json': json.dumps(fotos_by_etapa),
        'voltar_url': voltar_url,
    }
    return render(request, 'obras/fotos.html', context)


########################################################

@nao_equipe_required
@login_required
def resumo_obra(request, obra_id):
    if request.user.is_authenticated and request.user.tenant:
        connection.set_schema(request.user.tenant.schema_name)

    # 🔐 Garante que o usuário tem acesso à obra
    obra = get_object_or_404(Obra, id=obra_id, usuario=request.user)

    # 1) Etapas da obra
    etapas = EtapaObra.objects.filter(obra=obra).order_by('ordem')

    # 2) Pagamentos da obra
    pagamentos = Pagamento.objects.filter(obra=obra).order_by('data')

    # 3) Totais
    orcamento_total = float(obra.orcamento_total or 0)
    total_gasto = float(
        pagamentos.filter(pago=True).aggregate(total=Sum('valor'))['total'] or 0
    )
    total_agendado = float(
        pagamentos.filter(pago=False).aggregate(total=Sum('valor'))['total'] or 0
    )
    saldo = orcamento_total - total_gasto
    percentual = int((total_gasto / orcamento_total * 100) if orcamento_total else 0)

    # 4) Dados de etapas
    etapas_data = []
    for etapa in etapas:
        valor_orcado_f = float(etapa.valor_orcado or 0)
        pagos_etapa = float(
            Pagamento.objects.filter(etapa=etapa, pago=True).aggregate(total=Sum('valor'))['total'] or 0
        )
        saldo_etapa = valor_orcado_f - pagos_etapa
        etapas_data.append({
            'nome': etapa.nome,
            'status': etapa.status,
            'data_inicio': etapa.data_inicio.strftime('%d/%m/%Y') if etapa.data_inicio else '',
            'data_prevista_fim': etapa.data_prevista_fim.strftime('%d/%m/%Y') if etapa.data_prevista_fim else '',
            'data_fim': etapa.data_fim.strftime('%d/%m/%Y') if etapa.data_fim else '',
            'valor_orcado': valor_orcado_f,
            'valor_pago': pagos_etapa,
            'saldo_etapa': saldo_etapa,
        })

    # 5) Dados de pagamentos
    pagamentos_data = []
    feitos_por_data = {}
    agendados_por_data = {}

    for p in pagamentos:
        nome_etapa = p.etapa.nome if p.etapa else ''
        desc = p.material_outro if p.material_outro else p.descricao
        pagamentos_data.append({
            'data': p.data.strftime('%d/%m/%Y'),
            'tipo': p.tipo,
            'etapa': nome_etapa,
            'descricao': desc,
            'quantidade': float(p.quantidade) if p.quantidade else None,
            'unidade': p.unidade or None,
            'valor': float(p.valor),
            'pago': p.pago,
        })

        key = p.data.strftime('%Y-%m-%d')
        if p.pago:
            feitos_por_data[key] = feitos_por_data.get(key, 0) + float(p.valor)
        else:
            agendados_por_data[key] = agendados_por_data.get(key, 0) + float(p.valor)

    # 6) Contexto para template
    context = {
        'obra': obra,
        'orcamento_total': orcamento_total,
        'total_gasto': total_gasto,
        'total_agendado': total_agendado,
        'saldo': saldo,
        'percentual': percentual,
        'tempo_decorrido': f"{(date.today() - obra.data_inicio).days} dias" if obra.data_inicio else "—",
        'etapas_data_json': json.dumps(etapas_data),
        'pagamentos_data_json': json.dumps(pagamentos_data),
        'feitos_por_data_json': json.dumps(feitos_por_data),
        'agendados_por_data_json': json.dumps(agendados_por_data),
    }
    return render(request, 'obras/resumo.html', context)


########################################################

@nao_equipe_required
@login_required
def etapas_obra(request, obra_id):
    if request.user.is_authenticated and request.user.tenant:
        connection.set_schema(request.user.tenant.schema_name)

    # 🔒 Garante que a obra pertence ao usuário logado
    obra = get_object_or_404(Obra, id=obra_id, usuario=request.user)

    grupo_escolhido = request.GET.get('grupo') or request.POST.get('grupo')
    subgrupo_escolhido = request.GET.get('subgrupo') or request.POST.get('subgrupo')

    # Etapas já cadastradas no banco
    etapas_existentes = EtapaObra.objects.filter(obra=obra).order_by('ordem')

    # Carrega etapas do dicionário
    etapas_grupo = ETAPAS_PADRAO.get(grupo_escolhido, {})
    etapas_do_subgrupo = etapas_grupo.get(subgrupo_escolhido, []) if grupo_escolhido and subgrupo_escolhido else []

    if request.method == 'POST':
        etapa_id = int(request.POST.get('etapa_padrao_id', 0))
        data_prevista = request.POST.get('data_prevista')

        if 0 <= etapa_id < len(etapas_do_subgrupo):
            etapa_info = etapas_do_subgrupo[etapa_id]

            # ⛏ Cria a etapa no banco com base no dicionário padrão
            EtapaObra.objects.create(
                obra=obra,
                nome=etapa_info["nome"],
                grupo=grupo_escolhido,
                subgrupo=subgrupo_escolhido,
                status='em_andamento',
                data_inicio=date.today(),
                data_prevista_fim=data_prevista,
                ordem=etapa_info["ordem"]
            )

        # Redireciona mantendo os filtros aplicados
        return redirect(f'/obras/{obra.id}/etapas/?grupo={grupo_escolhido}&subgrupo={subgrupo_escolhido}')

    return render(request, 'obras/etapas.html', {
        'obra': obra,
        'etapas_existentes': etapas_existentes,
        'etapas_padrao': etapas_grupo,
        'etapas_do_subgrupo': list(enumerate(etapas_do_subgrupo)),
        'grupo_escolhido': grupo_escolhido,
        'subgrupo_escolhido': subgrupo_escolhido,
    })


########################################################

@nao_equipe_required
@login_required
def salvar_detalhes_etapa(request, obra_id, etapa_id):
    if request.user.is_authenticated and request.user.tenant:
        connection.set_schema(request.user.tenant.schema_name)

    obra = get_object_or_404(Obra, id=obra_id)
    etapa = get_object_or_404(EtapaObra, id=etapa_id, obra=obra)

    if request.method == 'POST':
        # --- Campos básicos ---
        etapa.descricao = request.POST.get('descricao', '').strip()
        etapa.profissional = request.POST.get('profissional', '').strip()
        etapa.documento_profissional = request.POST.get('documento_profissional', '').strip()
        etapa.subgrupo = request.POST.get('subgrupo', etapa.subgrupo)


        # --- Valor orçado com conversão pt-BR para float ---
        valor_orcado_str = request.POST.get('valor_orcado', '').strip()
        if valor_orcado_str:
            valor_orcado_str = valor_orcado_str.replace('.', '').replace(',', '.')
            try:
                etapa.valor_orcado = Decimal(valor_orcado_str)
            except InvalidOperation:
                etapa.valor_orcado = None  # ou registre erro para exibição

        # --- Datas ---
        data_inicio_str = request.POST.get('data_inicio')
        data_fim_str = request.POST.get('data_fim')
        if data_inicio_str:
            try:
                etapa.data_inicio = datetime.strptime(data_inicio_str, "%Y-%m-%d").date()
            except ValueError:
                etapa.data_inicio = None
        if data_fim_str:
            try:
                etapa.data_fim = datetime.strptime(data_fim_str, "%Y-%m-%d").date()
            except ValueError:
                etapa.data_fim = None

        # --- Arquivos: upload simples ---
        if request.FILES.get('documento_orcamento'):
            etapa.documento_orcamento = request.FILES['documento_orcamento']
        if request.FILES.get('contrato_servico'):
            etapa.contrato_servico = request.FILES['contrato_servico']

        etapa.save()

        # --- Redirecionamento com filtros mantidos ---
        grupo = request.POST.get('grupo', '')
        subgrupo = request.POST.get('subgrupo', '')
        redirect_url = reverse('etapas_obra', args=[obra.id])
        if grupo and subgrupo:
            redirect_url += f"?grupo={grupo}&subgrupo={subgrupo}"
        return redirect(redirect_url)

    return redirect('etapas_obra', obra_id=obra.id)




########################################################


@nao_equipe_required
@login_required
@require_POST
def concluir_etapa(request, obra_id, etapa_id):
    if request.user.is_authenticated and request.user.tenant:
        connection.set_schema(request.user.tenant.schema_name)

    # Garante que a obra pertence ao usuário autenticado
    obra = get_object_or_404(Obra, id=obra_id, usuario=request.user)

    # Garante que a etapa pertence àquela obra
    etapa = get_object_or_404(EtapaObra, id=etapa_id, obra=obra)

    if etapa.status in ['em_andamento', 'atrasada']:
        etapa.status = 'concluida'
        etapa.data_fim = date.today()
        etapa.save()

    grupo = request.POST.get('grupo', '')
    subgrupo = request.POST.get('subgrupo', '')
    return redirect(f'/obras/{obra_id}/etapas/?grupo={grupo}&subgrupo={subgrupo}')


########################################################

@nao_equipe_required
@login_required
@require_POST
def deletar_etapa(request, obra_id, etapa_id):
    if request.user.is_authenticated and request.user.tenant:
        connection.set_schema(request.user.tenant.schema_name)

    # Garante que a obra pertence ao usuário autenticado
    obra = get_object_or_404(Obra, id=obra_id, usuario=request.user)

    # Garante que a etapa pertence àquela obra
    etapa = get_object_or_404(EtapaObra, id=etapa_id, obra=obra)

    etapa.delete()

    grupo = request.POST.get('grupo', '')
    subgrupo = request.POST.get('subgrupo', '')
    redirect_url = reverse('etapas_obra', args=[obra.id])
    if grupo and subgrupo:
        redirect_url += f"?grupo={grupo}&subgrupo={subgrupo}"
    return redirect(redirect_url)


########################################################



ALLOWED_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.pdf']
MAX_FILE_SIZE_MB = 10

from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from django.core.files.storage import default_storage
from django.http import JsonResponse
import logging

logger = logging.getLogger(__name__)

@login_required
@require_POST
@csrf_exempt  # remova esta linha se estiver usando corretamente o token CSRF via cabeçalho
def upload_documento_etapa(request, obra_id, etapa_id):
    if request.user.is_authenticated and request.user.tenant:
        connection.set_schema(request.user.tenant.schema_name)

    etapa = get_object_or_404(EtapaObra, id=etapa_id, obra_id=obra_id)
    tipo = request.POST.get('tipo')
    arquivo = request.FILES.get('arquivo')

    logger.info(f"[Upload] Obra: {obra_id}, Etapa: {etapa_id}, Tipo: {tipo}, Arquivo: {arquivo}")

    # Validações iniciais
    if tipo not in ['orcamento', 'contrato']:
        logger.warning("[Upload] Tipo inválido recebido.")
        return JsonResponse({'error': 'Tipo inválido'}, status=400)

    if not arquivo:
        logger.warning("[Upload] Nenhum arquivo recebido.")
        return JsonResponse({'error': 'Arquivo não enviado'}, status=400)

    # Limite de espaço
    if atingiu_limite_hd(request.user):
        logger.warning("[Upload] Limite de espaço atingido.")
        return JsonResponse({'error': 'Limite de armazenamento atingido.'}, status=400)

    # Criação do documento
    try:
        doc = DocumentoEtapa.objects.create(
            etapa=etapa,
            tipo=tipo,
            arquivo=arquivo
        )

        is_pdf = doc.arquivo.name.lower().endswith('.pdf')
        logger.info(f"[Upload] Documento salvo com sucesso. URL: {doc.arquivo.url}")
        return JsonResponse({
            'url': doc.arquivo.url,
            'is_pdf': is_pdf,
            'tipo': doc.tipo
        })

    except Exception as e:
        logger.error(f"[Upload] Erro ao salvar documento: {str(e)}")
        return JsonResponse({'error': f'Erro ao salvar documento: {str(e)}'}, status=500)





########################################################


@nao_equipe_required
@login_required
@require_POST
def delete_documento_etapa(request, obra_id, etapa_id):
    if request.user.is_authenticated and request.user.tenant:
        connection.set_schema(request.user.tenant.schema_name)

    data = json.loads(request.body)
    url = data.get("url")
    etapa = get_object_or_404(EtapaObra, id=etapa_id, obra_id=obra_id)

    documento = DocumentoEtapa.objects.filter(etapa=etapa, arquivo__icontains=url).first()
    if documento:
        caminho = documento.arquivo.path
        documento.delete()
        if default_storage.exists(caminho):
            default_storage.delete(caminho)
        return JsonResponse({'ok': True})
    return JsonResponse({'error': 'Documento não encontrado'}, status=404)



########################################################
@nao_equipe_required
@login_required
def gerar_painel_relatorio(request, obra_id):
    if request.user.is_authenticated and request.user.tenant:
        connection.set_schema(request.user.tenant.schema_name)
    obra = get_object_or_404(Obra, id=obra_id)
    return render(request, 'obras/painel_relatorio.html', {'obra': obra})


########################################################

@nao_equipe_required
@login_required
def gerar_relatorio_api(request, obra_id):
    if request.user.is_authenticated and request.user.tenant:
        connection.set_schema(request.user.tenant.schema_name)
    return gerar_relatorio_pdf_api(request, obra_id)  # CHAMADA ENXUTA


########################################################

import unicodedata
import re
from django.utils.crypto import get_random_string
from django.core.mail import send_mail
from django.contrib.auth.models import Group
from django.contrib.auth import get_user_model
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.db import connection
from django.contrib.auth.decorators import login_required
from .models import Obra, EquipeObra
from .decorators import nao_equipe_required


def limpar_nome_para_username(nome):
    # Remove acentos e espaços
    nome = unicodedata.normalize('NFKD', nome).encode('ASCII', 'ignore').decode('utf-8')
    nome = re.sub(r'\W+', '', nome).lower()
    return nome[:6]  # máximo 6 letras


@nao_equipe_required
@login_required
def cadastrar_equipe(request, obra_id):
    connection.set_schema(request.user.tenant.schema_name)
    obra = get_object_or_404(Obra, id=obra_id)

    if request.method == 'POST':
        nome = request.POST.get('nome')
        email = request.POST.get('email')

        if not nome or not email:
            messages.error(request, 'Preencha todos os campos obrigatórios.')
            return redirect(request.path)

        if EquipeObra.objects.filter(obra=obra, email=email).exists():
            messages.error(request, 'Este e-mail já foi usado para esta obra.')
            return redirect(request.path)

        # Login: nome simplificado + número
        base_username = limpar_nome_para_username(nome)
        username = f"{base_username}{get_random_string(length=2, allowed_chars='123456789')}"
        senha = get_random_string(length=5, allowed_chars='abcdefghjkmnpqrstuvwxyz23456789')

        User = get_user_model()
        user = User.objects.create_user(
            username=username,
            email=email,
            password=senha,
            first_name=nome
        )
        user.tenant = request.user.tenant
        user.is_staff = False
        user.save()

        grupo, _ = Group.objects.get_or_create(name='Equipe')
        user.groups.add(grupo)

        EquipeObra.objects.create(
            obra=obra,
            usuario=user,
            nome=nome,
            email=email
        )

        send_mail(
            subject='Acesso ao sistema Minha Obra',
            message=f"""
Olá {nome},

Você foi cadastrado como membro da equipe da obra: {obra.nome}

Acesse: https://obras.grfgraph.com.br/login/
Usuário: {username}
Senha: {senha}

Troque sua senha após o primeiro acesso.

Atenciosamente,
Equipe GRFGraph
""",
            from_email='nao-responda@grfgraph.com.br',
            recipient_list=[email],
            fail_silently=True
        )

        messages.success(request, f'Membro cadastrado e convite enviado para {email}.')
        return redirect('ver_equipe', obra_id=obra.id)

    return render(request, 'obras/cadastrar_equipe.html', {'obra': obra})



########################################################
@nao_equipe_required
@login_required
def deletar_membro_equipe(request, obra_id, membro_id):
    connection.set_schema(request.user.tenant.schema_name)
    membro = get_object_or_404(EquipeObra, id=membro_id, obra_id=obra_id)

    usuario = membro.usuario
    membro.delete()
    usuario.delete()  # Remove o usuário e seu e-mail

    messages.success(request, f'Membro da equipe "{membro.nome}" removido com sucesso.')
    return redirect('ver_equipe', obra_id=obra_id)

########################################################


from .models import EquipeObra, Obra

@nao_equipe_required
@login_required
def ver_equipe(request, obra_id):
    connection.set_schema(request.user.tenant.schema_name)
    obra = get_object_or_404(Obra, id=obra_id)
    equipe = EquipeObra.objects.filter(obra=obra).order_by('-data_convite')
    return render(request, 'obras/ver_equipe.html', {'obra': obra, 'equipe': equipe})


########################################################

@login_required
def obras_equipe(request):
    if request.user.is_authenticated and request.user.tenant:
        connection.set_schema(request.user.tenant.schema_name)

    obras = EquipeObra.objects.filter(usuario=request.user).select_related('obra')
    return render(request, 'obras/obras_equipe.html', {'obras': obras})

########################################################

@login_required
def upload_foto_obra(request, obra_id):
    if request.user.is_authenticated and request.user.tenant:
        connection.set_schema(request.user.tenant.schema_name)

    obra = get_object_or_404(Obra, id=obra_id, usuario=request.user)

    # 🚫 Checar limite de armazenamento
    if atingiu_limite_hd(request.user):
        return JsonResponse({'success': False, 'error': 'Espaço esgotado. Limite de 800MB atingido.'})

    foto = request.FILES.get('foto')
    if foto:
        foto = comprimir_imagem(foto)
    if not foto:
        return JsonResponse({'success': False, 'error': 'Nenhuma foto enviada.'})

    FotoObra.objects.create(obra=obra, imagem=foto)
    return JsonResponse({'success': True})



########################################################

from django.shortcuts import render, get_object_or_404
from django.db.models import Sum
from django.utils.timezone import now
from .models import Obra, EtapaObra, Pagamento, Foto

from django.contrib.auth.decorators import login_required
from django.shortcuts import render, get_object_or_404
from django.db import connection
from django.db.models import Sum
from django.utils.timezone import now
from django.utils.safestring import mark_safe
from datetime import date
from collections import defaultdict
import json

from obras.models import Obra, EtapaObra, Pagamento, Foto
@nao_equipe_required
@login_required
def relatorio_preview(request, obra_id):
    if request.user.is_authenticated and request.user.tenant:
        connection.set_schema(request.user.tenant.schema_name)

    obra = get_object_or_404(Obra, id=obra_id, usuario=request.user)

    # Dados principais
    etapas = EtapaObra.objects.filter(obra=obra).order_by('ordem')
    pagamentos = Pagamento.objects.filter(obra=obra).order_by('data')
    fotos = Foto.objects.filter(obra=obra).order_by('data_envio')

    # Totais
    valor_orcado = float(obra.orcamento_total or 0)
    valor_pago = float(
        pagamentos.filter(pago=True).aggregate(total=Sum('valor'))['total'] or 0
    )
    saldo_obra = valor_orcado - valor_pago
    dias_decorr = (date.today() - obra.data_inicio).days if obra.data_inicio else 0

    # Separação dos pagamentos
    pagamentos_confirmados = pagamentos.filter(pago=True)
    pagamentos_agendados = pagamentos.filter(pago=False)
    pagamentos_agendados_valor = sum([float(p.valor) for p in pagamentos_agendados])

    # Etapas concluídas
    etapas_concluidas = etapas.filter(status='concluida').count()

    # Gráfico da curva S (imagem tradicional)
    grafico_curva_s = f"/media/relatorios/obra_{obra.id}_curva_s.png"

    # NOVO: dados acumulados para gráfico Chart.js
    feitos_por_data = defaultdict(float)
    agendados_por_data = defaultdict(float)

    for p in pagamentos:
        data_str = p.data.strftime("%Y-%m-%d")
        if p.pago:
            feitos_por_data[data_str] += float(p.valor)
        else:
            agendados_por_data[data_str] += float(p.valor)

    # Dados formatados para uso no template
    feitos_json = mark_safe(json.dumps(feitos_por_data))
    agendados_json = mark_safe(json.dumps(agendados_por_data))

    context = {
        'obra': obra,
        'etapas': etapas,
        'pagamentos': pagamentos,
        'fotos': fotos,
        'valor_orcado': valor_orcado,
        'valor_pago': valor_pago,
        'saldo_obra': saldo_obra,
        'dias_decorr': dias_decorr,
        'hoje': now(),
        'grafico_curva_s': grafico_curva_s,
        'pagamentos_confirmados': pagamentos_confirmados,
        'pagamentos_agendados': pagamentos_agendados,
        'pagamentos_agendados_valor': pagamentos_agendados_valor,
        'etapas_concluidas': etapas_concluidas,

        # Dados JSON para Chart.js
        'feitos_por_data_json': feitos_json,
        'agendados_por_data_json': agendados_json,
    }

    return render(request, 'obras/relatorios/relatorio_obra.html', context)

