from django.shortcuts import render
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.views.generic.list import ListView
from django.views.generic.base import View
from django.views.generic.detail import DetailView
from .models import Estado, Cidade, TipoCliente, Cliente, Visita, Servico, Recibo, Funcionario
from .models import Agendamento
from django.urls import reverse_lazy
from django.contrib.auth.mixins import LoginRequiredMixin
from braces.views import GroupRequiredMixin
from django.shortcuts import get_object_or_404
from .utils import render_pdf 
from django.http import HttpResponse
from django.db.models import Q
from django.http import JsonResponse
from .models import Agendamento
from django.views.generic import TemplateView
from .models import Cliente, Visita, Servico, Recibo # Importe seus modelos
import json
from django.views.decorators.csrf import csrf_exempt # Para facilitar o teste inicial
import re
from django import forms
from django.utils import timezone
from django.db.models import Sum, Q # Adicione o Sum nos imports

#################### AJUSTE DATA PARA AGENDAMENTO ####################

class AgendamentoForm(forms.ModelForm):
    class Meta:
        model = Agendamento
        fields = ['titulo', 'descricao', 'data', 'hora', 'status']
        widgets = {
            'data': forms.DateInput(
                format='%Y-%m-%d',
                attrs={'type': 'date', 'class': 'form-control'}
            ),
            'hora': forms.TimeInput(
                format='%H:%M',
                attrs={'type': 'time', 'class': 'form-control'}
            ),
        }

    def __init__(self, *args, **kwargs):
        super(AgendamentoForm, self).__init__(*args, **kwargs)
        # Força o valor inicial da data para o formato ISO (AAAA-MM-DD)
        if self.instance and self.instance.data:
            self.fields['data'].initial = self.instance.data.strftime('%Y-%m-%d')
        if self.instance and self.instance.hora:
            self.fields['hora'].initial = self.instance.hora.strftime('%H:%M')


#################### CREATE ####################

class EstadoCreate(GroupRequiredMixin, LoginRequiredMixin, CreateView):
    login_url = reverse_lazy('login')
    group_required = u"Administrador"
    model = Estado
    fields = ['nome']
    template_name = 'cadastros/estado.html'
    success_urls = reverse_lazy('ListarEstado')  

class CidadeCreate(GroupRequiredMixin, LoginRequiredMixin, CreateView):
    login_url = reverse_lazy('login')
    group_required = u"Administrador"
    model = Cidade
    fields = ['nome', 'estado']
    template_name = 'cadastros/cidade.html'
    success_urls = reverse_lazy('ListarCidade')

class TipoClienteCreate(GroupRequiredMixin, LoginRequiredMixin, CreateView):
    login_url = reverse_lazy('login')
    group_required = u"Administrador"
    model = TipoCliente
    fields = ['tipo']
    template_name = 'cadastros/tipocliente.html'
    success_urls = reverse_lazy('ListarTipoCiente')

class ClienteCreate(LoginRequiredMixin, CreateView):
    login_url = reverse_lazy('login')
    model = Cliente
    fields = ['codigo', 'datacadastro', 'situacao', 'tipopessoa', 'tipocliente', 'nome', 'datanascimento', 'cnpj', 'cpf', 'rg', 'rgemissor', 'cep', 'bairro', 'cidade', 'estado', 'telefone01', 'telefone02', 'email', 'website', 'observacao']
    template_name = 'cadastros/cliente.html'
    success_urls = reverse_lazy('ListarCliente')    

class VisitaCreate(LoginRequiredMixin, CreateView):
    login_url = reverse_lazy('login')
    model = Visita
    fields = ['protocolo', 'datavisita', 'cliente', 'cnpj', 'cpf', 'telefone', 'email', 'historico', 'arquivo', 'usuario']
    template_name = 'cadastros/visita.html'
    success_urls = reverse_lazy('ListarVisita')  

    def form_valid(self, form):
        form.instance.usuario = self.request.user
        url = super().form_valid(form)
        return url

class ServicoCreate(LoginRequiredMixin, CreateView):
    login_url = reverse_lazy('login')
    model = Servico
    fields = ['protocolo','status', 'cliente', 'cnpj', 'cpf', 'telefone', 'email', 'dataentrada', 'datasaida', 'equipamento', 'estatus', 'problema', 'analise', 'metodo', 'procedimento', 'pecas', 'transporte', 'manufatura', 'desconto', 'total', 'observacao', 'responsavel']
    template_name = 'cadastros/servico.html'
    success_url = reverse_lazy('ListarServico')

    def form_valid(self, form):
        form.instance.usuario = self.request.user
        url = super().form_valid(form)
        return url
    

class ReciboCreate(LoginRequiredMixin, CreateView):
    login_url = reverse_lazy('login')
    model = Recibo
    fields = ['protocolo', 'dataservico', 'datarecebimento', 'cliente', 'cnpj', 'cpf', 'telefone', 'email', 'historico', 'responsavel', 'valorrecibo']
    template_name = 'cadastros/recibo.html'
    success_urls = reverse_lazy('ListarServico')   

    def form_valid(self, form):
        form.instance.usuario = self.request.user
        url = super().form_valid(form)
        return url
    

class FuncionarioCreate(LoginRequiredMixin, CreateView):
    login_url = reverse_lazy('login')
    model = Funcionario
    fields = ['codigo', 'datacadastro', 'situacao', 'nome', 'usuario', 'datanascimento', 'cpf', 'rg', 'rgemissor', 'cep', 'bairro', 'cidade', 'estado', 'telefone01', 'telefone02', 'email', 'observacao']
    template_name = 'cadastros/funcionario.html'
    success_url = reverse_lazy('ListarFuncionario')

class AgendamentoCreate(LoginRequiredMixin, CreateView):
    login_url = reverse_lazy('login')
    model = Agendamento
    form_class = AgendamentoForm # Usa o form com widgets de data
    template_name = 'cadastros/agendamento.html'
    success_url = reverse_lazy('ListarAgendamento')

    def form_valid(self, form):
        # Define o usuário logado automaticamente como dono do agendamento
        form.instance.usuario = self.request.user
        return super().form_valid(form)

#################### UPDATE ####################

class EstadoUpdate(GroupRequiredMixin, LoginRequiredMixin, UpdateView):
    login_url = reverse_lazy('login')
    group_required = u"Administrador"
    model = Estado
    fields = ['nome']
    template_name = 'editar/upestado.html'
    success_urls = reverse_lazy('ListarEstado') 

class CidadeUpdate(GroupRequiredMixin, LoginRequiredMixin, UpdateView):
    login_url = reverse_lazy('login')
    group_required = u"Administrador"
    model = Cidade
    fields = ['nome', 'estado']
    template_name = 'editar/upcidade.html'
    success_urls = reverse_lazy('ListarCidade')

class TipoClienteUpdate(GroupRequiredMixin, LoginRequiredMixin, UpdateView):
    login_url = reverse_lazy('login')
    group_required = u"Administrador"
    model = TipoCliente
    fields = ['tipo']
    template_name = 'editar/uptipocliente.html'
    success_urls = reverse_lazy('ListarTipoCliente')

class ClienteUpdate(LoginRequiredMixin, UpdateView):
    login_url = reverse_lazy('login')
    model = Cliente
    fields = ['codigo', 'datacadastro', 'situacao', 'tipopessoa', 'tipocliente', 'nome', 'datanascimento', 'cnpj', 'cpf', 'rg', 'rgemissor', 'cep', 'bairro', 'cidade', 'estado', 'telefone01', 'telefone02', 'email', 'website', 'observacao']
    template_name = 'editar/upcliente.html'
    success_urls = reverse_lazy('Listarliente')

class VisitaUpdate(LoginRequiredMixin, UpdateView):
    login_url = reverse_lazy('login')
    model = Visita
    fields = ['protocolo', 'datavisita', 'cliente', 'cnpj', 'cpf', 'telefone', 'email', 'historico', 'arquivo', 'responsavel']
    template_name = 'editar/upvisita.html'
    success_urls = reverse_lazy('ListarVisita')  

    def get_object(self,nqueryset=None):
        self.object = get_object_or_404(Visita, pk=self.kwargs['pk'], usuario=self.request.user)
        return self.object

class ServicoUpdate(LoginRequiredMixin, UpdateView):
    login_url = reverse_lazy('login')
    model = Servico
    fields = ['protocolo','status', 'cliente', 'cnpj', 'cpf', 'telefone', 'email', 'dataentrada', 'datasaida', 'equipamento', 'estatus', 'problema', 'analise', 'metodo', 'procedimento', 'pecas', 'transporte', 'manufatura', 'desconto', 'total', 'observacao', 'responsavel']
    template_name = 'editar/upservico.html'
    success_url = reverse_lazy('ListarServico')

    def get_object(self,nqueryset=None):
        self.object = get_object_or_404(Servico, pk=self.kwargs['pk'], usuario=self.request.user)
        return self.object

class ReciboUpdate(LoginRequiredMixin, UpdateView):
    login_url = reverse_lazy('login')
    model = Recibo
    fields = ['protocolo', 'dataservico', 'datarecebimento', 'cliente', 'cnpj', 'cpf', 'telefone', 'email', 'historico', 'responsavel', 'valorrecibo']
    template_name = 'editar/uprecibo.html'
    success_urls = reverse_lazy('ListarRecibo')   

class FuncionarioUpdate(LoginRequiredMixin, UpdateView):
    login_url = reverse_lazy('login')
    model = Funcionario
    fields = ['codigo', 'datacadastro', 'situacao', 'nome', 'usuario', 'datanascimento',  'cpf', 'rg', 'rgemissor', 'cep', 'bairro', 'cidade', 'estado', 'telefone01', 'telefone02', 'email', 'observacao']
    template_name = 'editar/upfuncionario.html'
    success_urls = reverse_lazy('ListarFuncionario')

class AgendamentoUpdate(LoginRequiredMixin, UpdateView):
    login_url = reverse_lazy('login')
    model = Agendamento
    form_class = AgendamentoForm # Usa o form com widgets de data
    template_name = 'editar/upagendamento.html'
    success_url = reverse_lazy('ListarAgendamento')

    def get_object(self, queryset=None):
        # Busca o agendamento pelo ID (pk) e garante que pertence ao usuário logado
        self.object = get_object_or_404(
            Agendamento, 
            pk=self.kwargs['pk'], 
            usuario=self.request.user
        )
        return self.object

#################### DELETE ####################

class EstadoDelete(GroupRequiredMixin, LoginRequiredMixin, DeleteView):
    login_url = reverse_lazy('login')
    group_required = u"Administrador"
    model = Estado
    template_name = 'excluir/delestado.html'
    success_url = reverse_lazy('ListarEstado')

class CidadeDelete(GroupRequiredMixin, LoginRequiredMixin, DeleteView):
    login_url = reverse_lazy('login')
    group_required = u"Administrador"
    model = Cidade
    template_name = 'excluir/delcidade.html'
    success_urls = reverse_lazy('ListarCidade')

class TipoClienteDelete(GroupRequiredMixin, LoginRequiredMixin, DeleteView):
    login_url = reverse_lazy('login')
    group_required = u"Administrador"
    model = TipoCliente
    template_name = 'excluir/deltipocliente.html'
    success_urls = reverse_lazy('ListarTipoCliente')

class ClienteDelete(LoginRequiredMixin, DeleteView):
    login_url = reverse_lazy('login')
    model = Cliente
    template_name = 'excluir/delcliente.html'
    success_urls = reverse_lazy('ListarCliente')

class VisitaDelete(LoginRequiredMixin, DeleteView):
    login_url = reverse_lazy('login')
    model = Visita
    template_name = 'excluir/delvisita.html'
    success_urls = reverse_lazy('ListarVisita')

    def get_object(self,nqueryset=None):
        self.object = get_object_or_404(Visita, pk=self.kwargs['pk'], usuario=self.request.user)
        return self.object

class ServicoDelete(LoginRequiredMixin, DeleteView):
    login_url = reverse_lazy('login')
    model = Servico
    template_name = 'excluir/delservico.html'
    success_urls = reverse_lazy('ListarServico')

    def get_object(self,nqueryset=None):
        self.object = get_object_or_404(Servico, pk=self.kwargs['pk'], usuario=self.request.user)
        return self.object
    
class ReciboDelete(LoginRequiredMixin, DeleteView):
    login_url = reverse_lazy('login')
    model = Recibo
    template_name = 'excluir/delrecibo.html'
    success_urls = reverse_lazy('ListarVisita')

    def get_object(self,nqueryset=None):
        self.object = get_object_or_404(Recibo, pk=self.kwargs['pk'], usuario=self.request.user)
        return self.object

class FuncionarioDelete(LoginRequiredMixin, DeleteView):
    login_url = reverse_lazy('login')
    model = Funcionario
    template_name = 'excluir/delfuncionario.html'
    success_urls = reverse_lazy('ListarFuncionario')

#################### LISTA ####################

class EstadoList(LoginRequiredMixin, ListView):
    login_url = reverse_lazy('login')
    model = Estado
    template_name = 'listas/listestado.html'
    context_object_name = 'estados'

class CidadeList(LoginRequiredMixin, ListView):
    login_url = reverse_lazy('login')
    model = Cidade
    template_name = 'listas/listcidade.html'
    context_object_name = 'cidades'

class TipoClienteList(LoginRequiredMixin, ListView):
    login_url = reverse_lazy('login')
    model = TipoCliente
    template_name = 'listas/listtipocliente.html'

class ClienteList(LoginRequiredMixin, ListView):
    login_url = reverse_lazy('login')
    model = Cliente
    template_name = 'listas/listcliente.html'
    paginate_by = 10

    def get_queryset(self):
        queryset = super().get_queryset()

        busca = self.request.GET.get('busca')

        if busca:           
            queryset = queryset.filter(Q(cpf__icontains=busca) | Q(cnpj__icontains=busca) | Q(nome__icontains=busca))

        queryset = queryset.order_by('nome')

        return queryset

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['busca'] = self.request.GET.get('busca', '')
        return context
   
     
    
class VisitaList(LoginRequiredMixin, ListView):
    login_url = reverse_lazy('login')
    model = Visita
    template_name = 'listas/listvisita.html'
    paginate_by = 10
    
    def get_queryset(self):
        queryset = super().get_queryset()

        busca = self.request.GET.get('busca')

        if busca:           
            queryset = queryset.filter(Q(cliente__icontains=busca) | Q(cpf__icontains=busca) | Q(cnpj__icontains=busca))

        queryset = queryset.order_by('-datavisita')

        return queryset

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['busca'] = self.request.GET.get('busca', '')
        return context
    

   
class ServicoList(LoginRequiredMixin, ListView):
    login_url = reverse_lazy('login')
    model = Servico
    template_name = 'listas/listservico.html'
    paginate_by = 10

    def get_queryset(self):
        queryset = super().get_queryset()

        busca = self.request.GET.get('busca')

        if busca:           
            queryset = queryset.filter(Q(cliente__icontains=busca) | Q(cpf__icontains=busca) | Q(cnpj__icontains=busca))

        queryset = queryset.order_by('-dataentrada')

        return queryset

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['busca'] = self.request.GET.get('busca', '')
        return context


class ReciboList(LoginRequiredMixin, ListView):
    login_url = reverse_lazy('login')
    model = Recibo
    template_name = 'listas/listrecibo.html'
    paginate_by = 10
    
    def get_queryset(self):
        queryset = super().get_queryset()

        busca = self.request.GET.get('busca')

        if busca:           
            queryset = queryset.filter(Q(cliente__icontains=busca) | Q(cpf__icontains=busca) | Q(cnpj__icontains=busca))

        queryset = queryset.order_by('-dataservico')

        return queryset

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['busca'] = self.request.GET.get('busca', '')
        return context


class FuncionarioList(LoginRequiredMixin, ListView):
    login_url = reverse_lazy('login')
    model = Funcionario
    template_name = 'listas/listfuncionario.html'
    paginate_by = 10

    def get_queryset(self):
        queryset = super().get_queryset()

        busca = self.request.GET.get('busca')

        if busca:           
            queryset = queryset.filter(Q(cpf__icontains=busca) | Q(nome__icontains=busca))

        queryset = queryset.order_by('nome')

        return queryset

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['busca'] = self.request.GET.get('busca', '')
        return context

class AgendamentoList(LoginRequiredMixin, ListView):
    login_url = reverse_lazy('login')
    model = Agendamento
    template_name = 'listas/listagendamento.html'
    paginate_by = 10

    def get_queryset(self):
        # Filtramos pelo usuário logado E ordenamos
        # '-data' e '-hora' fazem a ordenação decrescente (mais recentes primeiro)
        return Agendamento.objects.filter(usuario=self.request.user).order_by('-data', '-hora')


#################### RELATORIOS ####################

class ClienteGeral(LoginRequiredMixin, ListView):
    login_url = reverse_lazy('login')
    model = Cliente
    template_name = 'relatorios/geralcliente.html'
    paginate_by = 10
    context_object_name = 'clientes'

    def get_queryset(self):
        queryset = super().get_queryset()

        busca = self.request.GET.get('busca')

        if busca:           
            queryset = queryset.filter(Q(cpf__icontains=busca) | Q(cnpj__icontains=busca) | Q(nome__icontains=busca))

        queryset = queryset.order_by('nome')

        return queryset

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['busca'] = self.request.GET.get('busca', '')
        return context


class VisitaGeral(LoginRequiredMixin, ListView):
    login_url = reverse_lazy('login')
    model = Visita
    template_name = 'relatorios/geralvisita.html'
    paginate_by = 10
    context_object_name = 'visitas'

    def get_queryset(self):
        self.object_list = Visita.objects.filter(usuario=self.request.user)
        return self.object_list

    def get_queryset(self):
        queryset = super().get_queryset()

        busca = self.request.GET.get('busca')

        if busca:           
            queryset = queryset.filter(Q(cliente__icontains=busca) | Q(cpf__icontains=busca) | Q(cnpj__icontains=busca))

        queryset = queryset.order_by('-datavisita')

        return queryset

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['busca'] = self.request.GET.get('busca', '')
        return context
    

class ServicoGeral(LoginRequiredMixin, ListView):
    login_url = reverse_lazy('login')
    model = Servico
    template_name = 'relatorios/geralservico.html'
    paginate_by = 10
    context_object_name = 'servicos'

    def get_queryset(self):
        self.object_list = Servico.objects.filter(usuario=self.request.user)
        return self.object_list

    def get_queryset(self):
        queryset = super().get_queryset()

        busca = self.request.GET.get('busca')

        if busca:           
            queryset = queryset.filter(Q(cliente__icontains=busca) | Q(cpf__icontains=busca) | Q(cnpj__icontains=busca))

        queryset = queryset.order_by('-dataentrada')

        return queryset

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['busca'] = self.request.GET.get('busca', '')
        return context
    

class ReciboGeral(LoginRequiredMixin, ListView):
    login_url = reverse_lazy('login')
    model = Recibo
    template_name = 'relatorios/geralrecibo.html'
    paginate_by = 10
    context_object_name = 'recibos'

    def get_queryset(self):
        self.object_list = Recibo.objects.filter(usuario=self.request.user)
        return self.object_list

    def get_queryset(self):
        queryset = super().get_queryset()

        busca = self.request.GET.get('busca')

        if busca:           
            queryset = queryset.filter(Q(cliente__icontains=busca) | Q(cpf__icontains=busca) | Q(cnpj__icontains=busca))

        queryset = queryset.order_by('-dataservico')

        return queryset

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['busca'] = self.request.GET.get('busca', '')
        return context

class FuncionarioGeral(LoginRequiredMixin, ListView):
    login_url = reverse_lazy('login')
    model = Funcionario
    template_name = 'relatorios/geralfuncionario.html'
    paginate_by = 10
    context_object_name = 'funcionarios'

    def get_queryset(self):
        queryset = super().get_queryset()

        busca = self.request.GET.get('busca')

        if busca:           
            queryset = queryset.filter(Q(cpf__icontains=busca) | Q(nome__icontains=busca))

        queryset = queryset.order_by('nome')

        return queryset

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['busca'] = self.request.GET.get('busca', '')
        return context
    
    
#################### PDFS ####################

class EstadoListPdf(View):
    def get(self, request, *args, **kwargs):
       estados = Estado.objects.all()
       dados = { 'estados': estados}
       pdf = render_pdf('pdfs/listpdfestado.html', dados)
       return HttpResponse(pdf, content_type='application/pdf')
    

class CidadeListPdf(View):
    def get(self, request, *args, **kwargs):
       cidades = Cidade.objects.all()
       dados = {'cidades': cidades}
       pdf = render_pdf('pdfs/listpdfcidade.html', dados)
       return HttpResponse(pdf, content_type='application/pdf')


class ClienteListPdf(LoginRequiredMixin, View):
    def get(self, request, *args, **kwargs):
        busca = request.GET.get('busca')
        acao = request.GET.get('acao', 'visualizar')
        
        # 1. Busca todos os registros
        clientes = Cliente.objects.all()

        # 2. Aplica o filtro se o usuário digitou algo na busca
        if busca:
            clientes = clientes.filter(
                Q(nome__icontains=busca) | 
                Q(cnpj__icontains=busca) | 
                Q(cpf__icontains=busca)
            )

        # 3. Ordenação alfabética
        clientes = clientes.order_by('nome')

        # 4. O dicionário que enviamos para o HTML
        # AQUI ESTÁ O SEGREDO: Vamos usar a chave 'itens'
        dados = {
            'itens': clientes,
            'total': clientes.count(),
        }

        pdf = render_pdf('pdfs/listpdfcliente.html', dados)
        response = HttpResponse(pdf, content_type='application/pdf')
        
        dispo = 'attachment' if acao == 'baixar' else 'inline'
        response['Content-Disposition'] = f'{dispo}; filename="relatorio_clientes.pdf"'
        
        return response


class VisitaListPdf(LoginRequiredMixin, View):
    def get(self, request, *args, **kwargs):
        busca = request.GET.get('busca')
        # Capturamos se o usuário quer baixar ou apenas ver
        acao = request.GET.get('acao', 'visualizar') 
        
        visitas = Visita.objects.all()

        if busca:
            visitas = visitas.filter(
                Q(cliente__icontains=busca) | 
                Q(cpf__icontains=busca) | 
                Q(cnpj__icontains=busca) |
                Q(protocolo__icontains=busca)
            )

        visitas = visitas.order_by('-datavisita', '-id')

        dados = {
            'visitas': visitas,
            'total_geral': visitas.count(),
            'data_emissao': timezone.now(),
        }

        pdf = render_pdf('pdfs/listpdfvisita.html', dados)
        response = HttpResponse(pdf, content_type='application/pdf')
        
        data_atual = timezone.now().strftime('%d-%m-%Y')
        nome_arquivo = f"Relatorio_Visitas_{data_atual}.pdf"

        # Lógica de decisão:
        if acao == 'baixar':
            disposition = 'attachment'
        else:
            disposition = 'inline' # Abre no navegador

        response['Content-Disposition'] = f'{disposition}; filename="{nome_arquivo}"'
        
        return response

class ServicoListPdf(LoginRequiredMixin, View):
    def get(self, request, *args, **kwargs):
        busca = request.GET.get('busca')
        acao = request.GET.get('acao', 'visualizar')
        
        # Usamos 'dataentrada' que é o campo real do seu modelo
        servicos = Servico.objects.all()

        if busca:
            servicos = servicos.filter(
                Q(protocolo__icontains=busca) | 
                Q(cliente__nome__icontains=busca) | # Se o cliente for ForeignKey
                Q(equipamento__icontains=busca) |
                Q(responsavel__icontains=busca)
            )

        # Ordenamos pelo campo correto: 'dataentrada'
        servicos = servicos.order_by('-dataentrada', '-id')

        dados = {
            'itens': servicos,
            'total': servicos.count(),
            'data_emissao': timezone.now(),
        }

        pdf = render_pdf('pdfs/listpdfservico.html', dados)
        response = HttpResponse(pdf, content_type='application/pdf')
        
        dispo = 'attachment' if acao == 'baixar' else 'inline'
        response['Content-Disposition'] = f'{dispo}; filename="servicos.pdf"'
        
        return response
    
class ReciboListPdf(LoginRequiredMixin, View):
    def get(self, request, *args, **kwargs):
        busca = request.GET.get('busca')
        acao = request.GET.get('acao', 'visualizar')
        
        recibos = Recibo.objects.all()

        if busca:
            recibos = recibos.filter(
                Q(protocolo__icontains=busca) | 
                Q(cliente__icontains=busca) |
                Q(historico__icontains=busca)
            )

        recibos = recibos.order_by('-id')

        # CORREÇÃO: Usando 'valorrecibo' conforme a lista de campos do erro
        total_financeiro = recibos.aggregate(Sum('valorrecibo'))['valorrecibo__sum'] or 0

        dados = {
            'itens': recibos,
            'total_count': recibos.count(),
            'total_financeiro': total_financeiro,
            'data_emissao_doc': timezone.now(),
        }

        pdf = render_pdf('pdfs/listpdfrecibo.html', dados)
        response = HttpResponse(pdf, content_type='application/pdf')
        
        dispo = 'attachment' if acao == 'baixar' else 'inline'
        response['Content-Disposition'] = f'{dispo}; filename="relatorio_recibos.pdf"'
        
        return response

class FuncionarioListPdf(LoginRequiredMixin, View):
    def get(self, request, *args, **kwargs):
        busca = request.GET.get('busca')
        acao = request.GET.get('acao', 'visualizar')
        
        # 1. Busca todos os registros
        funcionario = Funcionario.objects.all()

        # 2. Aplica o filtro se o usuário digitou algo na busca
        if busca:
            funcionario = funcionario.filter(
                Q(nome__icontains=busca) | 
                Q(cpf__icontains=busca)
            )

        # 3. Ordenação alfabética
        funcionarios = funcionarios.order_by('nome')

        # 4. O dicionário que enviamos para o HTML
        # AQUI ESTÁ O SEGREDO: Vamos usar a chave 'itens'
        dados = {
            'itens': funcionarios,
            'total': funcionarios.count(),
        }

        pdf = render_pdf('pdfs/listpdfcliente.html', dados)
        response = HttpResponse(pdf, content_type='application/pdf')
        
        dispo = 'attachment' if acao == 'baixar' else 'inline'
        response['Content-Disposition'] = f'{dispo}; filename="relatorio_clientes.pdf"'
        
        return response

#################### DETAILS ####################

class EstadoDetail(GroupRequiredMixin, LoginRequiredMixin, DetailView):
    login_url = reverse_lazy('login')
    group_required = u"Administrador"
    model = Estado
    template_name = 'visualizar/visualestado.html'
    success_url = reverse_lazy('VisualisarEstado')


class CidadeDetail(GroupRequiredMixin, LoginRequiredMixin, DetailView):
    login_url = reverse_lazy('login')
    group_required = u"Administrador"
    model = Cidade
    template_name = 'visualizar/visualcidade.html'
    success_url = reverse_lazy('VisualisarCidade')


class ClienteDetail(GroupRequiredMixin, LoginRequiredMixin, DetailView):
    login_url = reverse_lazy('login')
    group_required = u"Administrador"
    model = Cliente
    template_name = 'visualizar/visualcliente.html'
    success_url = reverse_lazy('VisualisarCliente')


class VisitaDetail(GroupRequiredMixin, LoginRequiredMixin, DetailView):
    login_url = reverse_lazy('login')
    group_required = u"Administrador"
    model = Visita
    template_name = 'visualizar/visualvisita.html'
    success_url = reverse_lazy('VisualisarVisita')


class ServicoDetail(GroupRequiredMixin, LoginRequiredMixin, DetailView):
    login_url = reverse_lazy('login')
    group_required = u"Administrador"
    model = Servico
    template_name = 'visualizar/visualservico.html'
    success_url = reverse_lazy('VisualisarServico')

class ReciboDetail(GroupRequiredMixin, LoginRequiredMixin, DetailView):
    login_url = reverse_lazy('login')
    group_required = u"Administrador"
    model = Recibo
    template_name = 'visualizar/visualrecibo.html'
    success_url = reverse_lazy('VisualisarRecibo')

class FuncionarioDetail(GroupRequiredMixin, LoginRequiredMixin, DetailView):
    login_url = reverse_lazy('login')
    group_required = u"Administrador"
    model = Funcionario
    template_name = 'visualizar/visualfuncionario.html'
    success_url = reverse_lazy('VisualisarFuncionario')

class AgendamentoDetail(GroupRequiredMixin, LoginRequiredMixin, DetailView):
    login_url = reverse_lazy('login')
    group_required = u"Administrador"
    model = Agendamento
    template_name = 'visualizar/visualagendamento.html'
    success_url = reverse_lazy('VisualisarAgendamento')

#################### DETAILPDFS ####################

class EstadoDetailPdf(View):
    def get(self, request, *args, **kwargs):
       pk = kwargs.get('pk')
       estados = get_object_or_404(Estado, pk=pk)
       dados = {'estados': estados}
       pdf = render_pdf('pdfs/detailpdfestado.html', dados)
       return HttpResponse(pdf, content_type='application/pdf')


class CidadeDetailPdf(View):
    def get(self, request, *args, **kwargs):
       pk = kwargs.get('pk')
       cidades = get_object_or_404(Cidade, pk=pk)
       dados = {'cidades': cidades}
       pdf = render_pdf('pdfs/detailpdfcidade.html', dados)
       return HttpResponse(pdf, content_type='application/pdf')
    

class ClienteDetailPdf(LoginRequiredMixin, View):
    def get(self, request, *args, **kwargs):
        cliente = get_object_or_404(Cliente, pk=self.kwargs['pk'])
        params = {
            'clientes': cliente, # Note que seu HTML usa 'visitas' no plural
        }
        pdf = render_pdf('pdfs/detailpdfcliente.html', params)
        
        response = HttpResponse(pdf, content_type='application/pdf')
        # Isso faz o navegador sugerir um nome de arquivo ao salvar
        filename = f"clientecodigo{cliente.pk}.pdf"
        response['Content-Disposition'] = f'attachment; filename="{filename}"'
        return response
    

class VisitaDetailPdf(LoginRequiredMixin, View):
    def get(self, request, *args, **kwargs):
        visita = get_object_or_404(Visita, pk=self.kwargs['pk'])
        params = {
            'visitas': visita, # Note que seu HTML usa 'visitas' no plural
        }
        pdf = render_pdf('pdfs/detailpdfvisita.html', params)
        
        response = HttpResponse(pdf, content_type='application/pdf')
        # Isso faz o navegador sugerir um nome de arquivo ao salvar
        filename = f"visita{visita.protocolo}.pdf"
        response['Content-Disposition'] = f'attachment; filename="{filename}"'
        return response


class ServicoDetailPdf(LoginRequiredMixin, View):
    def get(self, request, *args, **kwargs):
        servico = get_object_or_404(Servico, pk=self.kwargs['pk'])
        params = {
            'servicos': servico, # Note que seu HTML usa 'visitas' no plural
        }
        pdf = render_pdf('pdfs/detailpdfservico.html', params)
        
        response = HttpResponse(pdf, content_type='application/pdf')
        # Isso faz o navegador sugerir um nome de arquivo ao salvar
        filename = f"servico{servico.protocolo}.pdf"
        response['Content-Disposition'] = f'attachment; filename="{filename}"'
        return response

class ServicoClienteDetailPdf(LoginRequiredMixin, View):
    def get(self, request, *args, **kwargs):
        servico = get_object_or_404(Servico, pk=self.kwargs['pk'])
        params = {
            'servicos': servico, # Note que seu HTML usa 'visitas' no plural
        }
        pdf = render_pdf('pdfs/detailpdfservicocliente.html', params)
        
        response = HttpResponse(pdf, content_type='application/pdf')
        # Isso faz o navegador sugerir um nome de arquivo ao salvar
        filename = f"servico{servico.protocolo}.pdf"
        response['Content-Disposition'] = f'attachment; filename="{filename}"'
        return response

class ReciboDetailPdf(LoginRequiredMixin, View):
    def get(self, request, *args, **kwargs):
        recibo = get_object_or_404(Recibo, pk=self.kwargs['pk'])
        params = {
            'recibos': recibo, # Note que seu HTML usa 'visitas' no plural
        }
        pdf = render_pdf('pdfs/detailpdfrecibo.html', params)
        
        response = HttpResponse(pdf, content_type='application/pdf')
        # Isso faz o navegador sugerir um nome de arquivo ao salvar
        filename = f"recibo{recibo.protocolo}.pdf"
        response['Content-Disposition'] = f'attachment; filename="{filename}"'
        return response

class FuncionarioDetailPdf(LoginRequiredMixin, View):
    def get(self, request, *args, **kwargs):
        funcionario = get_object_or_404(Funcionario, pk=self.kwargs['pk'])
        params = {
            'funcionario': funcionario, # Note que seu HTML usa 'visitas' no plural
        }
        pdf = render_pdf('pdfs/detailpdffuncionario.html', params)
        
        response = HttpResponse(pdf, content_type='application/pdf')
        # Isso faz o navegador sugerir um nome de arquivo ao salvar
        filename = f"funcionariocodigo{funcionario.pk}.pdf"
        response['Content-Disposition'] = f'attachment; filename="{filename}"'
        return response

#################### DETAILIMPORTS ####################


class ClienteImports(View):
    def get(self, request, *args, **kwargs):
       pk = kwargs.get('pk')
       clientes = get_object_or_404(Cliente, pk=pk)
       dados = {'clientes': clientes}
       pdf = render_pdf('cadastros/visita.html', dados)
       return HttpResponse(pdf, content_type='application/pdf')
    
    
#################### AGENDAMENTO ####################

def salvar_agendamento(request):
    if request.method == 'POST':
        try:
            data_recebida = json.loads(request.body)
            
            # Criando o registro no banco
            novo_agendamento = Agendamento.objects.create(
                usuario=request.user,
                titulo=data_recebida['titulo'],
                data=data_recebida['data'], # O JS deve enviar em formato YYYY-MM-DD
                hora=data_recebida['hora']
            )
            
            return JsonResponse({
                'status': 'sucesso', 
                'id': novo_agendamento.id,
                'mensagem': 'Agendado com sucesso!'
            })
        except Exception as e:
            return JsonResponse({'status': 'erro', 'message': str(e)}, status=400)
            
    return JsonResponse({'status': 'erro', 'message': 'Método não permitido'}, status=405)

#################### RETORNO DADOS PARA RECIBOS ####################

def busca_dados_cliente_ajax(request):
    cliente_id = request.GET.get('id')
    try:
        cliente = Cliente.objects.get(pk=cliente_id)
        data = {
            'cnpj': cliente.cnpj,
            'cpf': cliente.cpf,
            'telefone01': cliente.telefone01, 
            'email': cliente.email,
        }
        return JsonResponse(data)
    except Cliente.DoesNotExist:
        return JsonResponse({'erro': 'Cliente não encontrado'}, status=404)
    

def busca_servico_ajax(request):
    protocolo = request.GET.get('protocolo')
    try:
        # Busca o serviço pelo protocolo e traz os dados do cliente relacionado
        servico = Servico.objects.get(protocolo=protocolo)
        data = {
            'protocolo': servico.protocolo,
            'dataentrada': servico.dataentrada,
            'datasaida': servico.datasaida,
            'cliente': servico.cliente.nome,
            'cnpj': servico.cnpj,
            'cpf': servico.cpf,
            'telefone': servico.telefone,
            'email': servico.email,
            'historico': servico.problema, # Ou servico.procedimento, dependendo do que deseja no recibo
            'valorrecibo': str(servico.total), # Converte Decimal para string para o JSON
            'responsavel': servico.responsavel,
        }
        return JsonResponse(data)
    except Servico.DoesNotExist:
        return JsonResponse({'erro': 'Protocolo não encontrado'}, status=404)
    
#################### RETORNO DADOS PARA VISITAS ####################

def busca_cliente_autocomplete(request):
    termo = request.GET.get('q', '') # O Select2 envia o que foi digitado no parâmetro 'q'
    clientes = Cliente.objects.filter(nome__icontains=termo)[:10] # Limita a 10 resultados
    
    results = []
    for cliente in clientes:
        results.append({
            'id': cliente.id,
            'text': cliente.nome, # O que aparece na lista
            'cnpj': cliente.cnpj,
            'cpf': cliente.cpf,
            'telefone': cliente.telefone01,
            'email': cliente.email
        })
    
    return JsonResponse({'results': results})  

#################### DASHBOARD ####################

class IndexView(LoginRequiredMixin, TemplateView):
    template_name = 'paginas/index.html' # ou o nome do seu arquivo

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # Enviando as contagens reais para o template
        context['qtd_clientes'] = Cliente.objects.count()
        context['qtd_visitas'] = Visita.objects.count()
        context['qtd_servicos'] = Servico.objects.count()
        context['qtd_recibos'] = Recibo.objects.count()
        return context
   