# views.py
from django.views.generic import FormView, ListView, DetailView, CreateView, UpdateView
from django.views.generic.edit import FormView, BaseUpdateView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.decorators import permission_required
from django.contrib import messages
from django.shortcuts import render, redirect, get_object_or_404
from django.urls import reverse_lazy
from django.http import HttpResponse, HttpResponseRedirect
from django.views import View
from django.utils import timezone
from django.contrib.sites.shortcuts import get_current_site
from django.template.loader import render_to_string
from django.core.mail import send_mail
from django.conf import settings
from django.db import IntegrityError

from .models import Event, Prospect, EmailTracker, EmailCampaign, EventType
from .filters import ProspectFilter
from .forms import ProspectForm, CSVImportForm, BulkEmailForm, EventForm

from .mixins import CRMAccessMixin

import csv
from io import TextIOWrapper
from datetime import datetime

@permission_required('crm.view_crm', raise_exception=True)
def prospect_form(request, pk=None):
    # Get the prospect instance if pk is provided (edit mode)
    prospect = get_object_or_404(Prospect, pk=pk) if pk else None

    if request.method == 'POST':
        form = ProspectForm(request.POST, instance=prospect)
        if form.is_valid():
            prospect = form.save(commit=False)
            if not pk:  # New prospect
                prospect.created_by = request.user
            prospect.modified_by = request.user
            prospect.save()

            action = 'updated' if pk else 'added'
            messages.success(request,
                f'Prospect {prospect.entity_name} has been {action} successfully!')
            return redirect('crm:events')
    else:
        form = ProspectForm(instance=prospect)

    context = {
        'form': form,
        'is_edit': prospect is not None,
        'first_title': prospect.entity_name if prospect else 'Add Prospect',
        'second_title': prospect.full_name() if prospect else None
    }
    return render(request, 'crm/prospect_form.html', context)

# @permission_required('crm.view_crm', raise_exception=True)
# def add_prospect(request):
#     if request.method == 'POST':
#         entity_name = request.POST.get('entity_name')
#         first_name = request.POST.get('first_name')
#         last_name = request.POST.get('last_name')
#         email = request.POST.get('email')
#         phone = request.POST.get('phone')
#         address = request.POST.get('address')
#         zip_code = request.POST.get('zip_code')
#         city = request.POST.get('city')
#         # region = request.POST.get('region')

#         try:
#             prospect = Prospect.objects.create(
#                 entity_name=entity_name,
#                 first_name=first_name,
#                 last_name=last_name,
#                 email=email,
#                 phone=phone,
#                 address=address,
#                 zip_code=zip_code,
#                 city=city,
#                 # region=region,
#                 created_by=request.user,
#                 modified_by=request.user
#             )
#             messages.success(request, f'Prospect {name} has been added successfully!')
#             return redirect('crm:events')  # or wherever you want to redirect after success
#         except Exception as e:
#             messages.error(request, f'Error adding prospect: {str(e)}')

#     return render(request, 'crm/add_prospect.html')

class EventCreateView(CRMAccessMixin, CreateView):
    model = Event
    form_class = EventForm
    template_name = 'crm/event_form.html'
    success_url = reverse_lazy('crm:planned_events')

    def get_initial(self):
        initial = super().get_initial()
        prospect_id = self.kwargs.get('prospect_id')
        if prospect_id:
            initial['prospects'] = [prospect_id]
        return initial

    def form_valid(self, form):
        form.instance.created_by = self.request.user
        form.instance.modified_by = self.request.user
        return super().form_valid(form)

class EditEventView(CRMAccessMixin, UpdateView):
    model = Event
    form_class = EventForm
    template_name = 'crm/event_form.html'
    success_url = reverse_lazy('crm:planned_events')

    def form_valid(self, form):
        form.instance.modified_by = self.request.user
        response = super().form_valid(form)
        messages.success(self.request, 'Event updated successfully!')
        return response

class StartEventView(CRMAccessMixin, BaseUpdateView):
    model = Event
    http_method_names = ['post', 'get']

    def get(self, request, *args, **kwargs):
        return self.post(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        event = get_object_or_404(Event, pk=kwargs['pk'], status='PLANNED')
        event.status = 'ACTIVE'
        event.save()

        if event.type == 'MAIL':
            return HttpResponseRedirect(
                reverse_lazy('crm:setup_email_campaign', kwargs={'event_id': event.id})
            )
        elif event.type == 'SMS':
            return HttpResponseRedirect(
                reverse_lazy('crm:setup_sms_campaign', kwargs={'event_id': event.id})
            )
        elif event.type == 'PRESS':
            return HttpResponseRedirect(
                reverse_lazy('crm:setup_press_release', kwargs={'event_id': event.id})
            )

        messages.success(request, 'Event started successfully!')
        return HttpResponseRedirect(reverse_lazy('crm:planned_events'))

class EventListView(CRMAccessMixin, ListView):
    model = Event
    template_name = 'crm/events.html'
    context_object_name = 'events'  # We won't use this since we're providing custom context

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['planned_events'] = Event.objects.filter(
            status='PLANNED'
        ).order_by('date')
        context['completed_events'] = Event.objects.filter(
            status='COMPLETED'
        ).order_by('-date')
        return context

class ProspectListView(CRMAccessMixin, ListView):
    model = Prospect
    template_name = 'crm/prospect_list.html'
    context_object_name = 'prospects'
    filterset_class = ProspectFilter

    def get_queryset(self):
        return super().get_queryset().prefetch_related('prospectstatus_set__status')

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['filter'] = self.filterset_class(
            self.request.GET,
            queryset=self.get_queryset()
        )
        return context

class CSVImportView(CRMAccessMixin, FormView):
    template_name = 'crm/csv_import.html'
    form_class = CSVImportForm
    success_url = reverse_lazy('prospect-list')

    def form_valid(self, form):
        csv_file = TextIOWrapper(
            form.cleaned_data['csv_file'].file,
            encoding='utf-8-sig'  # Handle potential BOM in CSV
        )
        reader = csv.reader(csv_file, delimiter=';')  # Using semicolon delimiter

        # Skip header if exists
        next(reader, None)

        created_count = 0
        updated_count = 0
        error_count = 0

        for row in reader:
            try:
                if len(row) < 10:  # Ensure we have enough columns
                    continue

                # Extract data from correct columns
                entity_name = row[0].strip()
                last_name = row[1].strip()
                first_name = row[2].strip()
                email = row[3].strip()
                phone = row[4].strip()
                zip_code = row[8].strip()
                city = row[9].strip()

                # Try to update existing prospect or create new one
                prospect, created = Prospect.objects.update_or_create(
                    email=email,  # Use email as unique identifier
                    defaults={
                        'entity_name': entity_name,
                        'first_name': first_name,
                        'last_name': last_name,
                        'phone': phone,
                        'zip_code': zip_code,
                        'city': city,
                        'modified_by': self.request.user,
                    }
                )

                if created:
                    prospect.created_by = self.request.user
                    prospect.save()
                    created_count += 1
                else:
                    updated_count += 1

            except Exception as e:
                error_count += 1
                messages.error(
                    self.request,
                    f"Error processing row with email {email}: {str(e)}"
                )

        # Add success message
        messages.success(
            self.request,
            f"Import completed: {created_count} created, {updated_count} updated, {error_count} errors"
        )

        return super().form_valid(form)

class SendBulkEmailView(CRMAccessMixin, FormView):
    template_name = 'crm/send_bulk_email.html'
    form_class = BulkEmailForm
    success_url = reverse_lazy('crm:prospect-list')

    def form_valid(self, form):
        prospects = form.cleaned_data['prospects']
        subject = form.cleaned_data['subject']
        content = form.cleaned_data['content']

        # Create Event for this email campaign
        event = Event.objects.create(
            date=datetime.now(),
            type=EventType.MAILING,
            description=f"Bulk email: {subject}",
            status='COMPLETED',
            created_by=self.request.user,
            modified_by=self.request.user
        )
        event.prospects.set(prospects)

        # Send emails
        success_count, error_count = send_bulk_email(
            subject=subject,
            content=content,
            prospects=prospects
        )

        # Show result message
        messages.success(
            self.request,
            f"Sent {success_count} emails successfully. {error_count} failed."
        )

        return super().form_valid(form)
