from django.db import connection
from django.db.models import Q
from django.http import Http404
from django.shortcuts import render, redirect
from django.conf import settings
from django.http import JsonResponse, HttpResponse, HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from django.contrib.auth import logout
from django.views.decorators.http import require_POST
from django.urls import reverse


from .serializers import HotmailSerializer, PhoneSerializer, AccountSerializer
from rest_framework import status
from rest_framework import generics, permissions
from rest_framework.views import APIView
from rest_framework.decorators import api_view
from rest_framework.response import Response

import random
from .models import Hotmail, Phone, Account
from django.contrib.auth import authenticate, login
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator

    
# Get data hotmail
class HotmailItemListAPI(generics.ListAPIView):
    queryset = Hotmail.objects.all()
    serializer_class = HotmailSerializer
    permission_classes = [permissions.IsAuthenticated]

# Get data phone 
class PhoneItemListAPI(generics.ListAPIView):
    queryset = Phone.objects.all()
    serializer_class = PhoneSerializer
    permission_classes = [permissions.IsAuthenticated]

# Get random hotmail
class RandomHotmailItemListAPI(generics.ListAPIView):
    def get(self, request, format=None):
        hotmails_with_status = Hotmail.objects.exclude(status__isnull=False)
        random_hotmail = hotmails_with_status.order_by('?').first()  
        serializer = HotmailSerializer(random_hotmail)
        return Response(serializer.data)    

# Get random phone
class RandomPhoneItemListAPI(generics.ListAPIView):
    def get(self, request, format=None):
        phone_with_status = Phone.objects.exclude(status__isnull=False)
        random_phone = phone_with_status.order_by('?').first()  
        serializer = PhoneSerializer(random_phone)
        return Response(serializer.data)  

class AccountView(APIView):
    def post(self, request, format=None):
        serializer = AccountSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

# Home
@login_required
def home(request):
    return render(request, 'import_phone.html')

# Home
@login_required
def api(request):
     return render(request, 'api.html')

# Login
def login_view(request):
    # Nếu người dùng đã đăng nhập, chuyển hướng họ đi nơi khác
    if request.user.is_authenticated:
        return redirect('import-phone')

    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        
        user = authenticate(request, username=username, password=password)
        
        if user is not None:
            login(request, user)
            # Chuyển hướng đến trang chủ sau khi đăng nhập thành công
            return redirect('import-phone')
        else:
            # Trả về một thông báo lỗi nếu đăng nhập không thành công
            return render(request, 'login.html', {'error': 'Tên đăng nhập hoặc mật khẩu không đúng'})

    return render(request, 'login.html')

@require_POST
def logout_view(request):
    logout(request) 
    return HttpResponseRedirect(reverse('login'))
    
# Import hotmail from txt    
@login_required
def import_hotmail(request):
    total_running = total_done = total_null = 0   

    if request.method == 'POST':
       
        # Xử lý file .txt và lưu dữ liệu mới
        file = request.FILES['datafile']
        file_data = file.read().decode('utf-8')
        lines = file_data.split('\n')
        for line in lines:            
            if line.strip(): 
                line = line.replace("\r","")              
                Hotmail.objects.create(data_content=line)                

        # Thay đổi này thiết lập biến session khi upload thành công
        request.session['upload_success'] = True   
        total_data = Hotmail.objects.count()  
        total_running = Hotmail.objects.filter(status='Running').count()
        total_done = Hotmail.objects.filter(status='Done').count()
        total_null = Hotmail.objects.filter(status__isnull=True).count()  
         
        # Thêm thông tin tổng số vào context
        return render(request, 'import_hotmail.html', {
            'success': True,
            'total_data': total_data,           
            'total_running': total_running,
            'total_done': total_done,
            'total_null': total_null
        })       

    # Kiểm tra nếu trang được load sau một upload thành công
    success = request.session.pop('upload_success', False)
    # Nếu không có session 'upload_success', có thể là một GET request thông thường
    
    total_data = Hotmail.objects.count()  
    total_running = Hotmail.objects.filter(status='Running').count()
    total_done = Hotmail.objects.filter(status='Done').count()
    total_null = Hotmail.objects.filter(status__isnull=True).count()

    # Trả về template với context chứa thông tin tổng số
    return render(request, 'import_hotmail.html', {
        'success': success,
        'total_data': total_data,
        'total_running': total_running,
        'total_done': total_done,
        'total_null': total_null
    })

# Import phone from txt 
@login_required
def import_phone(request):
    total_running = total_done = total_null = total_success = total_exist = 0
    imported_count = 0
   
    if request.method == 'POST': 
        # Xử lý file .txt và lưu dữ liệu mới
        file = request.FILES['datafile']
        file_data = file.read().decode('utf-8')
        lines = file_data.split('\n')
        for line in lines:
            if line.strip():
                line = line.replace("\r","") 
                #Phone.objects.create(data_content=line)       
                obj, created = Phone.objects.get_or_create(data_content=line)
                if created:
                    imported_count += 1   

        # Thay đổi này thiết lập biến session khi upload thành công
        request.session['upload_success'] = True   
        total_data = Phone.objects.count()  
        total_running = Phone.objects.filter(status='Running').count()
        total_done = Phone.objects.filter(status='Done').count()
        total_success = Phone.objects.filter(status='Success').count()
        total_exist = Phone.objects.filter(status='Exist').count()
        total_null = Phone.objects.filter(status__isnull=True).count()  
         
        # Thêm thông tin tổng số vào context
        return render(request, 'import_phone.html', {
            'success': True,
            'total_data': total_data,
            'imported_count': imported_count,  
            'total_running': total_running,
            'total_done': total_done,
            'total_success': total_success,
            'total_exist': total_exist,
            'total_null': total_null
        })       

    # Kiểm tra nếu trang được load sau một upload thành công
    success = request.session.pop('upload_success', False)
    # Nếu không có session 'upload_success', có thể là một GET request thông thường
    
    total_data = Phone.objects.count()  
    total_running = Phone.objects.filter(status='Running').count()
    total_done = Phone.objects.filter(status='Done').count()
    total_success = Phone.objects.filter(status='Success').count()
    total_exist = Phone.objects.filter(status='Exist').count()
    total_null = Phone.objects.filter(status__isnull=True).count()

    # Trả về template với context chứa thông tin tổng số
    return render(request, 'import_phone.html', {
        'success': success,
        'total_data': total_data,
        'total_running': total_running,
        'total_done': total_done,
        'total_success': total_success,
        'total_exist': total_exist,
        'total_null': total_null
    })

# HOTMAIL: Update status item
def hotmail_status_null(request, id):     
    try:      
        hotmail = Hotmail.objects.get(id=id)     
        hotmail.status = None
        hotmail.save()      
        return JsonResponse({'message': 'Hotmail Status updated successfully.'}, status=200)
    except Hotmail.DoesNotExist:      
        return JsonResponse({'message': 'Hotmail object not found.'}, status=404)
    except Exception as e:       
        return JsonResponse({'message': str(e)}, status=500)

def hotmail_status_running(request, id):     
    try:      
        hotmail = Hotmail.objects.get(id=id)     
        hotmail.status = "Running"
        hotmail.save()      
        return JsonResponse({'message': 'Hotmail Status updated successfully.'}, status=200)
    except Hotmail.DoesNotExist:      
        return JsonResponse({'message': 'Hotmail object not found.'}, status=404)
    except Exception as e:       
        return JsonResponse({'message': str(e)}, status=500)

def hotmail_status_done(request, id):     
    try:      
        hotmail = Hotmail.objects.get(id=id)     
        hotmail.status = "Done"
        hotmail.save()      
        return JsonResponse({'message': 'Hotmail Status updated successfully.'}, status=200)
    except Hotmail.DoesNotExist:      
        return JsonResponse({'message': 'Hotmail object not found.'}, status=404)
    except Exception as e:       
        return JsonResponse({'message': str(e)}, status=500)       

# PHONE: Update status item
def phone_status_null(request, id):     
    try:      
        phone = Phone.objects.get(id=id)     
        phone.status = None
        phone.save()      
        return JsonResponse({'message': ' Phone Status updated successfully.'}, status=200)
    except Phone.DoesNotExist:      
        return JsonResponse({'message': 'Phone object not found.'}, status=404)
    except Exception as e:       
        return JsonResponse({'message': str(e)}, status=500)

def phone_status_running(request, id):     
    try:      
        phone = Phone.objects.get(id=id)     
        phone.status = "Running"
        phone.save()      
        return JsonResponse({'message': 'Phone Status updated successfully.'}, status=200)
    except Phone.DoesNotExist:      
        return JsonResponse({'message': 'Phone object not found.'}, status=404)
    except Exception as e:       
        return JsonResponse({'message': str(e)}, status=500)

def phone_status_done(request, id):     
    try:      
        phone = Phone.objects.get(id=id)     
        phone.status = "Done"
        phone.save()      
        return JsonResponse({'message': 'Phone Status updated successfully.'}, status=200)
    except Phone.DoesNotExist:      
        return JsonResponse({'message': 'Phone object not found.'}, status=404)
    except Exception as e:       
        return JsonResponse({'message': str(e)}, status=500)      


def phone_status_success(request, id):     
    try:      
        phone = Phone.objects.get(id=id)     
        phone.status = "Success"
        phone.save()      
        return JsonResponse({'message': 'Phone Status updated successfully.'}, status=200)
    except Phone.DoesNotExist:      
        return JsonResponse({'message': 'Phone object not found.'}, status=404)
    except Exception as e:       
        return JsonResponse({'message': str(e)}, status=500)     
 

def phone_status_exist(request, id):     
    try:      
        phone = Phone.objects.get(id=id)     
        phone.status = "Exist"
        phone.save()      
        return JsonResponse({'message': 'Phone Status updated successfully.'}, status=200)
    except Phone.DoesNotExist:      
        return JsonResponse({'message': 'Phone object not found.'}, status=404)
    except Exception as e:       
        return JsonResponse({'message': str(e)}, status=500)      

# Cập các trường status running -> null
def update_status_to_null(request):
    # Cập nhật trường status từ "Running" sang None trong bảng Hotmail
    Hotmail.objects.filter(status='Running').update(status=None)
    
    # Cập nhật trường status từ "Running" sang None trong bảng Phone
    Phone.objects.filter(status='Running').update(status=None)
    
    return JsonResponse({'success': True})

# Kiểm tra dữ liệu 2 bảng 
def check_data_null(request):  
    if not Hotmail.objects.exists():
        return JsonResponse({'exists': False})
  
    if not Phone.objects.exists():
        return JsonResponse({'exists': False})
    
    # Kiểm tra bảng Hotmail
    hotmail_null_status_count = Hotmail.objects.filter(Q(status__isnull=True) | Q(status__exact='')).count()
    
    # Kiểm tra bảng Phone
    phone_null_status_count = Phone.objects.filter(Q(status__isnull=True) | Q(status__exact='')).count()

    # Count records with status 'Running'
    hotmail_running_status_count = Hotmail.objects.filter(status__iexact='Running').count()

    phone_running_status_count = Phone.objects.filter(status__iexact='Running').count()
    
    
    if hotmail_null_status_count == 0 and hotmail_running_status_count <= 100:
        return JsonResponse({'exists': False})
    
    if phone_null_status_count == 0 and phone_running_status_count <= 100:
        return JsonResponse({'exists': False})
    
    # Nếu 1 trong hai bảng đều không có trường status là null hoặc rỗng
    # if hotmail_null_status_count == 0 or phone_null_status_count == 0:
    #     return JsonResponse({'exists': False})
    
    return JsonResponse({'exists': True})
    

# Delete all data Hotmail
@login_required
def delete_all_hotmail(request):  
    Hotmail.objects.all().delete()  
    return HttpResponse('All hotmail records have been deleted.')

# Delete all data Phone
@login_required
def delete_all_phone(request):  
    Phone.objects.all().delete()  
    return HttpResponse('All phone records have been deleted.')

@login_required
def delete_specific_phones(request):
    # Lấy giá trị prefix từ tham số GET (ví dụ: /delete_phones?prefix=84944)
    prefix = request.GET.get('prefix', '')

    if prefix:
        # Lọc và xóa tất cả các bản ghi trong bảng Phone có data_content bắt đầu bằng prefix
        count, _ = Phone.objects.filter(data_content__startswith=prefix).delete()

        # Trả về thông báo cho người dùng với số lượng bản ghi đã xóa
        return HttpResponse(f"All records with data_content starting with '{prefix}' have been deleted. (Total: {count})")
    else:
        # Nếu không có prefix được cung cấp, trả về thông báo
        return HttpResponse("Please provide a prefix -> Exp: /delete_phones?prefix=84944")
        
# Delete hotmail by ID
@api_view(['DELETE'])
def delete_hotmail_id(request, pk):
    """
    Delete an item by id.
    """
    try:
        item = Hotmail.objects.get(pk=pk)
    except Hotmail.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    item.delete()
    return Response(status=status.HTTP_204_NO_CONTENT)

# Delete phone by ID
@api_view(['DELETE'])
def delete_phone_id(request, pk):
    """
    Delete an item by id.
    """
    try:
        item = Phone.objects.get(pk=pk)
    except Phone.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    item.delete()
    return Response(status=status.HTTP_204_NO_CONTENT)

@login_required
def export_phones_by_status(request, status):
    # Filter records by status, handling the special case of status being 'null'
    if status == 'null':
        records = Phone.objects.filter(status__isnull=True)
    else:
        records = Phone.objects.filter(status=status)
    
    # Create content to export
    #content = '\n'.join([f'{record.id} - {record.data_content}' for record in records])
    content = '\n'.join([f'{record.data_content}' for record in records])
    
    # Create HttpResponse with content type as text/plain
    response = HttpResponse(content, content_type='text/plain')
    response['Content-Disposition'] = f'attachment; filename="{status}_phones.txt"'
    
    return response

@login_required
def export_accounts(request):
    # Fetch all accounts
    accounts = Account.objects.all()

    # Create content for the .txt file
    content = '\n'.join([f'{account.data_content}|{account.twoFA}' for account in accounts])
    
    # Set up the HttpResponse with the text content
    response = HttpResponse(content, content_type='text/plain')
    response['Content-Disposition'] = 'attachment; filename="all_accounts.txt"'
    
    return response