from django.shortcuts import render, get_object_or_404, redirect
from django.views.generic import ListView, CreateView, UpdateView, DetailView, DeleteView
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.urls import reverse_lazy
from django.contrib import messages
from django.db import transaction
from django.http import JsonResponse
from django.db import models
import secrets
import string
from .models import Source, IntegrationLog
from .forms import SourceForm, generate_api_key, generate_api_secret

class SourceListView(LoginRequiredMixin, UserPassesTestMixin, ListView):
    """List all sources"""
    model = Source
    template_name = 'recruitment/source_list.html'
    context_object_name = 'sources'
    paginate_by = 10

    def test_func(self):
        return self.request.user.is_staff

    def get_queryset(self):
        queryset = super().get_queryset().order_by('name')

        # Search functionality
        search_query = self.request.GET.get('search', '')
        if search_query:
            queryset = queryset.filter(
                models.Q(name__icontains=search_query) |
                models.Q(source_type__icontains=search_query) |
                models.Q(description__icontains=search_query)
            )

        return queryset

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['search_query'] = self.request.GET.get('search', '')
        return context

class SourceCreateView(LoginRequiredMixin, UserPassesTestMixin, CreateView):
    """Create a new source"""
    model = Source
    form_class = SourceForm
    template_name = 'recruitment/source_form.html'
    success_url = reverse_lazy('source_list')

    def test_func(self):
        return self.request.user.is_staff

    def form_valid(self, form):
        # Set initial values
        form.instance.created_by = self.request.user.get_full_name() or self.request.user.username

        # Check if we need to generate API keys
        if form.cleaned_data.get('generate_keys') == 'true':
            form.instance.api_key = generate_api_key()
            form.instance.api_secret = generate_api_secret()

            # Log the key generation
            IntegrationLog.objects.create(
                source=form.instance,
                action=IntegrationLog.ActionChoices.CREATE,
                endpoint='/api/sources/',
                method='POST',
                request_data={'name': form.instance.name},
                ip_address=self.request.META.get('REMOTE_ADDR'),
                user_agent=self.request.META.get('HTTP_USER_AGENT', '')
            )

        response = super().form_valid(form)

        # Add success message
        messages.success(self.request, f'Source "{form.instance.name}" created successfully!')

        return response

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['title'] = 'Create New Source'
        context['generate_keys'] = self.request.GET.get('generate_keys', 'false')
        return context

class SourceDetailView(LoginRequiredMixin, UserPassesTestMixin, DetailView):
    """View source details"""
    model = Source
    template_name = 'recruitment/source_detail.html'
    context_object_name = 'source'

    def test_func(self):
        return self.request.user.is_staff

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        # Mask API keys in display
        source = self.object
        if source.api_key:
            masked_key = source.api_key[:8] + '*' * 24
            context['masked_api_key'] = masked_key
        else:
            context['masked_api_key'] = 'Not generated'

        if source.api_secret:
            masked_secret = source.api_secret[:12] + '*' * 52
            context['masked_api_secret'] = masked_secret
        else:
            context['masked_api_secret'] = 'Not generated'

        # Get recent integration logs
        context['recent_logs'] = IntegrationLog.objects.filter(
            source=source
        ).order_by('-created_at')[:10]

        return context

class SourceUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
    """Update an existing source"""
    model = Source
    form_class = SourceForm
    template_name = 'recruitment/source_form.html'
    success_url = reverse_lazy('source_list')

    def test_func(self):
        return self.request.user.is_staff

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['title'] = f'Edit Source: {self.object.name}'
        context['generate_keys'] = self.request.GET.get('generate_keys', 'false')
        return context

    def form_valid(self, form):
        # Check if we need to generate new API keys
        if form.cleaned_data.get('generate_keys') == 'true':
            form.instance.api_key = generate_api_key()
            form.instance.api_secret = generate_api_secret()

            # Log the key regeneration
            IntegrationLog.objects.create(
                source=self.object,
                action=IntegrationLog.ActionChoices.CREATE,
                endpoint=f'/api/sources/{self.object.pk}/',
                method='PUT',
                request_data={'name': form.instance.name, 'regenerated_keys': True},
                ip_address=self.request.META.get('REMOTE_ADDR'),
                user_agent=self.request.META.get('HTTP_USER_AGENT', '')
            )

            messages.success(self.request, 'New API keys generated successfully!')

        response = super().form_valid(form)
        messages.success(self.request, f'Source "{form.instance.name}" updated successfully!')
        return response

class SourceDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
    """Delete a source"""
    model = Source
    template_name = 'recruitment/source_confirm_delete.html'
    success_url = reverse_lazy('source_list')

    def test_func(self):
        return self.request.user.is_staff

    def delete(self, request, *args, **kwargs):
        self.object = self.get_object()
        success_url = self.get_success_url()

        # Log the deletion
        IntegrationLog.objects.create(
            source=self.object,
            action=IntegrationLog.ActionChoices.SYNC,  # Using SYNC for deletion
            endpoint=f'/api/sources/{self.object.pk}/',
            method='DELETE',
            request_data={'name': self.object.name},
            ip_address=self.request.META.get('REMOTE_ADDR'),
            user_agent=self.request.META.get('HTTP_USER_AGENT', '')
        )

        messages.success(request, f'Source "{self.object.name}" deleted successfully!')
        return super().delete(request, *args, **kwargs)

def generate_api_keys_view(request, pk):
    """Generate new API keys for a specific source"""
    if not request.user.is_staff:
        return JsonResponse({'error': 'Permission denied'}, status=403)

    try:
        source = get_object_or_404(Source, pk=pk)
    except Source.DoesNotExist:
        return JsonResponse({'error': 'Source not found'}, status=404)

    if request.method == 'POST':
        # Generate new API keys
        new_api_key = generate_api_key()
        new_api_secret = generate_api_secret()

        # Update the source with new keys
        old_api_key = source.api_key
        source.api_key = new_api_key
        source.api_secret = new_api_secret
        source.save()

        # Log the key regeneration
        # IntegrationLog.objects.create(
        #     source=source,
        #     action=IntegrationLog.ActionChoices.CREATE,
        #     endpoint=f'/api/sources/{source.pk}/generate-keys/',
        #     method='POST',
        #     request_data={
        #         'name': source.name,
        #         'old_api_key': old_api_key[:8] + '...' if old_api_key else None,
        #         'new_api_key': new_api_key[:8] + '...'
        #     },
        #     ip_address=request.META.get('REMOTE_ADDR'),
        #     user_agent=request.META.get('HTTP_USER_AGENT', '')
        # )

        return redirect('source_detail', pk=source.pk)
        # return JsonResponse({
        #     'success': True,
        #     'api_key': new_api_key,
        #     'api_secret': new_api_secret,
        #     'message': 'API keys regenerated successfully'
        # })

    return JsonResponse({'error': 'Invalid request method'}, status=405)

def toggle_source_status_view(request, pk):
    """Toggle the active status of a source"""
    if not request.user.is_staff:
        return JsonResponse({'error': 'Permission denied'}, status=403)

    try:
        source = get_object_or_404(Source, pk=pk)
    except Source.DoesNotExist:
        return JsonResponse({'error': 'Source not found'}, status=404)

    if request.method == 'POST':
        # Toggle the status
        old_status = source.is_active
        source.is_active = not source.is_active
        source.save()

        # Log the status change
        # IntegrationLog.objects.create(
        #     source=source,
        #     action=IntegrationLog.ActionChoices.SYNC,
        #     endpoint=f'/api/sources/{source.pk}/toggle-status/',
        #     method='POST',
        #     request_data={
        #         'name': source.name,
        #         'old_status': old_status,
        #         'new_status': source.is_active
        #     },
        #     ip_address=request.META.get('REMOTE_ADDR'),
        #     user_agent=request.META.get('HTTP_USER_AGENT', '')
        # )

        status_text = 'activated' if source.is_active else 'deactivated'

        return redirect('source_detail', pk=source.pk)
        # return JsonResponse({
        #     'success': True,
        #     'is_active': source.is_active,
        #     'message': f'Source "{source.name}" {status_text} successfully'
        # })

def copy_to_clipboard_view(request):
    """HTMX endpoint to copy text to clipboard"""
    if request.method == 'POST':
        text_to_copy = request.POST.get('text', '')

        return render(request, 'includes/copy_to_clipboard.html', {
            'text': text_to_copy
        })

    return JsonResponse({'error': 'Invalid request method'}, status=405)
