import json
import requests
from django.conf import settings
from django.shortcuts import render, redirect, get_object_or_404
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from .forms import SignupForm, ConsultantProfileForm, CustomerProfileForm, ServiceSelectionForm
from .models import OTP, CustomUser, ConsultantProfile, CustomerProfile, VesselSubType, RankSubType, State, City, ServiceBooking, VerticalSubCategory, VerticalService,ConsultantCertificate,Salutation,ConsultantService
#from .whatsapp import send_whatsapp_transaction
from .email_utils import send_otp_email,send_email
from django.contrib.auth import authenticate,get_user_model, login, logout
from django.contrib.auth.forms import AuthenticationForm
from .decorators import consultant_required, customer_required
from django.http import JsonResponse
import random
from django.contrib import messages
import re
from django.views.decorators.http import require_POST
from django.utils import timezone


User = get_user_model()


def home(request):
    return redirect('login')
    
    
def generate_otp():
    return str(random.randint(100000, 999999))
    
    
def signup_view(request):   
        form = SignupForm()
        salutations = Salutation.objects.all()
        return render(request, 'signup.html', {'form': form,'salutations':salutations})  

        
def send_otps(request):
    if request.method == 'POST':
        data = json.loads(request.body)
        email = data.get('email')
        country_code = data.get('country_code')        
        mobile = data.get('mobile')   
        full_mobile = f"{country_code}{mobile}"

        email_otp = str(random.randint(100000, 999999))
        mobile_otp = str(random.randint(100000, 999999))

        # Save OTP in DB
        OTP.objects.create(
            email=email,
            mobile=mobile,
            email_code=email_otp,
            mobile_code=mobile_otp
        )

        # Send Email OTP via Brevo
        requests.post("https://api.brevo.com/v3/smtp/email", json={
            "sender": {"name": "Charismight", "email": settings.BREVO_SENDER_EMAIL},
            "to": [{"email": email}],
            "subject": "Your Email OTP",
            "htmlContent": f"<p>Your OTP is <b>{email_otp}</b></p>"
        }, headers={"api-key": settings.BREVO_API_KEY})

        #send_whatsapp_transaction(full_mobile, mobile_otp)

        return JsonResponse({"status": "ok", "message": "OTPs sent successfully"})
    return JsonResponse({"status": "error", "message": "Invalid request"})



def register(request):
    if request.method == "POST":
           
        data = json.loads(request.body)
        salutation_id = data.get("salutation")
        first_name = data.get("first_name")
        last_name = data.get("last_name")
        email = data.get("email")
        mobile = data.get("mobile")
        password = data.get("password")
        password2 = data.get("password2")
        role = data.get("role")
      
        if not all([first_name,last_name,role, email, mobile]):
            return JsonResponse({"status": "error", "message": "All fields are required."}, status=400)

        
        if CustomUser.objects.filter(email=email).exists():
            return JsonResponse({"status": "error", "message": "Email already registered."}, status=400)
            
        
        if CustomUser.objects.filter(mobile=mobile).exists():
            return JsonResponse({"status": "error", "message": "Mobile already registered."}, status=400)
            
        if password != password2:
            return JsonResponse({"status": "error", "message": "Passwords do not match."}, status=400)

            
        password_pattern = r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$'

        if not re.match(password_pattern, password):
            return JsonResponse({
                "status": "error",
                "message": "Password must be at least 8 characters, include uppercase, lowercase, number, and special character."
            }, status=400)
        salutation_obj = Salutation.objects.get(id=salutation_id)
        user = CustomUser.objects.create_user(
            username=email,
            email=email,
            salutation=salutation_obj,
            first_name=first_name,
            last_name=last_name,
            mobile=mobile,
            password=password,
            role=role,
        )
        
        if role == 'customer':
           subject = "Welcome to Charismight"
           html_content = f"""
           <p>Hello {first_name},</p>
           <p>Thank you for registering with <b>Charismight</b>. 
           You can now book services quickly and easily through our platform.</p>
           <p><a href="https://charismightone.com:9091/">Login to your Account</a></p>
           <p>We’re excited to serve you!<br>Best regards,<br>Charismight</p>
           """
           send_email(subject, html_content, user.email)
        else:
           subject = f"Welcome aboard, {first_name}!"
           html_content = f"""
           <p>Hello {first_name},</p>
           <p>Thank you for registering as a service provider on <b>Charismight</b>.</p>
           <p><a href="https://charismightone.com:9091/">Login to provider dashboard</a></p>
           <p>We’re glad to onboard you!<br>Best regards,<br>Charismight</p>
           """
           send_email(subject, html_content, provider.email)
           
    
        return JsonResponse({"status": "success", "message": "Registration successful! Please Login"})

           
    return JsonResponse({"status": "error", "message": "Invalid request method."}, status=405)




def verify_otps(request):
    if request.method == 'POST':
        data = json.loads(request.body)
        email_otp = data.get('email_otp')
        mobile_otp = data.get('mobile_otp')
        email = data.get('email')       
        mobile = data.get('mobile')       
        
        otp_record = OTP.objects.filter(
            email=email,
            mobile=mobile,
            email_code=email_otp            
        ).order_by('-created_at').first()
        
        if otp_record:
            return JsonResponse({"status": "verified"})
        else:
            return JsonResponse({"status": "error", "message": "Invalid or expired OTP"})


     
        

def verify_otp_view(request):
    if request.method == 'POST':
        entered_otp = request.POST.get('otp')       
        otp_obj = OTP.objects.filter(code=entered_otp).last()
        if otp_obj:
            data = request.session.get('signup_data')
            if data:
                full_mobile = f"{data['country_code']}{data['mobile']}"
                user = CustomUser.objects.create_user(
                    username=data['email'],
                    email=data['email'],
                    password=data['password'],
                    first_name=data['first_name'],
                    last_name=data['last_name'],
                    country_code=data['country_code'],
                    mobile=full_mobile,
                    role=data['role']
                )
                login(request, user)
                if user.role == 'consultant':
                    return redirect('consultant_profile_update')                    
                elif user.role == 'customer':
                    return redirect('customer_profile_update')                
                
                
    return render(request, 'verify_otp.html')


def login_combined_view(request):  
        
    if request.method == 'POST':
        method = request.POST.get('method')

        if method == 'password':
            email = request.POST.get('email')
            password = request.POST.get('password')
            user = authenticate(request, username=email, password=password)
            if user:
                login(request, user)                
                if user.role == 'consultant':
                    try:
                        if ConsultantProfile.objects.get(user=user):
                            return redirect('consultant_dashboard')
                    except ConsultantProfile.DoesNotExist:
                        return redirect('consultant_profile_update')
                elif user.role == 'customer':
                    try:
                        if CustomerProfile.objects.get(user=user):
                            return redirect('customer_dashboard')
                    except CustomerProfile.DoesNotExist:
                        return redirect('customer_profile_update')
                return render(request, 'login.html', {'error': 'Please Try again!'})                
            else:
                return render(request, 'login.html', {'error': 'Invalid email or password'})

        elif method == 'otp':
            mobile = request.POST.get('mobile')
            otp = request.POST.get('otp')

            try:
                user = CustomUser.objects.get(mobile=mobile)
                valid_otp = OTP.objects.filter(mobile=mobile, code=otp).last()
                if valid_otp:
                    login(request, user)                    
                    if user.role == 'consultant':
                        try:
                            if ConsultantProfile.objects.get(user=user):
                                return redirect('consultant_dashboard')
                        except ConsultantProfile.DoesNotExist:
                            return redirect('consultant_profile_update')
                    elif user.role == 'customer':
                        try:
                            if CustomerProfile.objects.get(user=user):
                                return redirect('customer_dashboard')
                        except CustomerProfile.DoesNotExist:
                            return redirect('customer_profile_update')
                    return redirect('default_dashboard')  # fallback
                else:
                    return render(request, 'login.html', {'error': 'Invalid OTP'})
            except CustomUser.DoesNotExist:
                return render(request, 'login.html', {'error': 'Mobile number not registered'})
    else:
         user = request.user
         if user.is_authenticated:
             if user.role == 'consultant':
                return redirect('consultant_dashboard')
             elif user.role == 'customer':
                return redirect('customer_dashboard')
    return render(request, 'login.html')
    

def send_mobile_otp(request):
    if request.method == 'POST':
        email = request.POST.get('email')
        mobile = request.POST.get('mobile')
        try:
            user = CustomUser.objects.get(mobile=mobile)
            otp = generate_otp()
            send_otp_gupshup(mobile, otp)
            OTP.objects.create(user=user, mobile=mobile, email=email, code=otp)
            return JsonResponse({'status': 'ok'})
        except CustomUser.DoesNotExist:
            return JsonResponse({'status': 'error', 'message': 'Mobile number not registered'})
            
def send_signup_email_otp(request):
    if request.method == 'POST':
        email = request.POST.get('email')
        mobile = request.POST.get('mobile')
        otp = generate_otp()
        try:
            send_otp_email(email, otp)
            OTP.objects.create(user=None, mobile=mobile, email=email, code=otp)
            return JsonResponse({'status': 'ok'})
        except Exception as e:
            return JsonResponse({'status': 'error', 'message': str(e)})



@login_required
def book_service(request):
    return render(request, 'book_service.html')



    
def handlelogout(request):
    logout(request)    
    return redirect('/')

@login_required
def consultant_profile_update(request):
    try:
        profile = ConsultantProfile.objects.get(user=request.user)
    except ConsultantProfile.DoesNotExist:
        profile = None

    if request.method == 'POST':
        form = ConsultantProfileForm(request.POST, request.FILES, instance=profile)
        if form.is_valid():
            profile = form.save(commit=False)
            profile.user = request.user
            profile.save()
            files = request.FILES.getlist('certificates')  # field name in HTML
            for f in files:
                ConsultantCertificate.objects.create(consultant=profile, file=f)
            
            return redirect('consultant_dashboard')
    else:
        form = ConsultantProfileForm(instance=profile)

    return render(request, 'consultant_profile_update.html', {'form': form,'certificates': profile.certificates.all() if profile else []})


@login_required
def customer_profile_update(request):
    try:
        profile = CustomerProfile.objects.get(user=request.user)
    except CustomerProfile.DoesNotExist:
        profile = None

    if request.method == 'POST':
        form = CustomerProfileForm(request.POST, request.FILES, instance=profile)
        if form.is_valid():
            profile = form.save(commit=False)
            profile.user = request.user
            profile.save()
            return redirect('customer_dashboard')
    else:
        form = CustomerProfileForm(instance=profile)

    return render(request, 'customer_profile_update.html', {'form': form})



@login_required
@consultant_required
def consultant_dashboard(request):
    bookings = ServiceBooking.objects.filter(consultant=request.user)

   
    total_in_progress = ServiceBooking.objects.filter(consultant=request.user, status="In progress").count()
    total_assigned = ServiceBooking.objects.filter(consultant=request.user, status="assigned").count()
    total_closed = ServiceBooking.objects.filter(consultant=request.user, status="closed").count()

    context = {
        'total_bookings': bookings,       
        'total_in_progress': total_in_progress,
        'total_assigned': total_assigned,
        'total_closed': total_closed,
    }
    return render(request, 'consultant_dashboard.html', context)
    
@login_required
@customer_required
def customer_dashboard(request):
    total_booked = ServiceBooking.objects.filter(customer=request.user).count()
    total_new = ServiceBooking.objects.filter(customer=request.user,status="new").count()
    total_in_progress = ServiceBooking.objects.filter(customer=request.user, status="In progress").count()
    total_assigned = ServiceBooking.objects.filter(customer=request.user, status="assigned").count()
    total_closed = ServiceBooking.objects.filter(customer=request.user, status="closed").count()

    context = {
        'total_booked': total_booked,
        'total_new': total_new,
        'total_in_progress': total_in_progress,
        'total_assigned': total_assigned,
        'total_closed': total_closed,
    }
    return render(request, 'customer_dashboard.html',context)
    

@login_required
@consultant_required
def consultant_my_services(request):
    return render(request, 'cunsultent_my_services.html')
    
    
@login_required
@consultant_required
def consultant_assigned_services(request):
    return render(request, 'consultent_assignied_services.html')

   
def get_subtypes(request):
    type_id = request.GET.get('type_id')
    subtypes = VesselSubType.objects.filter(vessel_type_id=type_id).values('id', 'name')
    return JsonResponse(list(subtypes), safe=False)
    
def get_rank_subtypes(request):
    rank_id = request.GET.get('rank_id')
    subtypes = RankSubType.objects.filter(rank_id=rank_id).values('id', 'name')
    return JsonResponse(list(subtypes), safe=False)
    
def get_states(request):
    country_id = request.GET.get('country_id')
    states = State.objects.filter(country_id=country_id).values('id', 'name')
    return JsonResponse(list(states), safe=False)

def get_cities(request):
    state_id = request.GET.get('state_id')
    cities = City.objects.filter(state_id=state_id).values('id', 'name')
    return JsonResponse(list(cities), safe=False)
    
    
def book_services_view(request):
    if request.method == 'POST':
        service_ids = request.POST.getlist('services')
        subcategory_id = request.POST.get('subcategory')
        vertical_id = request.POST.get('vertical')
        comments = request.POST.get('comments')
        
        bookings = []
        
        for sid in service_ids:
            service = VerticalService.objects.get(id=sid)
            booking = ServiceBooking.objects.create(customer=request.user, service=service,vertical_id=vertical_id,verticalsubcategory_id=subcategory_id,comments=comments)
            bookings.append(booking)
            
        services_html = "".join([
            f"<li><b>Service:</b> {b.service.name} "            
            for b in bookings
        ])
            
        if request.user.role == 'customer':
            subject = "Your service booking has been confirmed!"
            html_content = f"""
            <p>Hello {request.user.first_name},</p>
            <p>Thank you for booking with us 🎉</p>
            <p>We’re happy to inform you that your booking is confirmed. 
            For more details, we will get in touch with you.</p>

            <h3>Booking Details:</h3>
            <ul>
               {services_html}  
            </ul>

            <p>Thank You for choosing us.<br>Best regards,<br>Charismight</p>
            """
            send_email(subject, html_content, request.user.email)
            
            admin_email = "operations@charismight.com"
            #admin_email = "shivikaagarwal1992@gmail.com"
            admin_subject = "New booking on your platform"
            admin_html_content = f"""
            <p>Hello Admin,</p>
            <p>You have received a new booking on your platform. Please review the details and take the necessary action.</p>
            <h3>Booking Details:</h3>
            <ul>
            <li>Customer Name: {request.user.first_name} {request.user.last_name}</li>               
               {services_html}  
            </ul>

            <p>Please log in to the admin dashboard to view complete booking information and manage further steps.</p>
            <br><br>
            <p>Thank you,<br>
            <b>Team Charismight</b><br>
            """
            send_email(admin_subject, admin_html_content, admin_email)
        
        return redirect('booking_success')

    form = ServiceSelectionForm()
    return render(request, 'book_services.html', {'form': form})

def edit_service_booking(request, booking_id):
    booking = ServiceBooking.objects.get(id=booking_id)

    if request.method == 'POST':
        service_id = request.POST.get('services')
        comments = request.POST.get('comments')

        if service_id:
            service = VerticalService.objects.get(id=service_id)
            booking.service = service
        booking.comments = comments
        booking.save()
        return redirect('booking_success')

    form = ServiceSelectionForm()
    selected_service_id = booking.service.id  # single selected service
    return render(request, 'edit_booking.html', {
        'form': form,
        'selected_service_id': selected_service_id
    })

    
def booking_success_view(request):
    return render(request, 'booking_success.html')
    
    
def load_subcategories(request):
    vertical_id = request.GET.get('vertical_id')
    subcategories = VerticalSubCategory.objects.filter(vertical_id=vertical_id).values('id', 'name')
    return JsonResponse(list(subcategories), safe=False)

def load_services(request):
    subcategory_id = request.GET.get('subcategory_id')
    services = VerticalService.objects.filter(subcategory_id=subcategory_id).values('id', 'name')
    return JsonResponse(list(services), safe=False)
    
    
@login_required
def my_bookings_view(request):
    bookings = ServiceBooking.objects.filter(customer=request.user)
    return render(request, 'my_bookings.html', {'bookings': bookings})
    
    
@login_required
@require_POST
def cancel_booking_view(request, booking_id):
    booking = get_object_or_404(ServiceBooking, id=booking_id, customer=request.user)
    booking.delete()
    return redirect('my_bookings')
    
    
def send_email(subject, html_content, to_email, sender_name="Charismight"):
    url = "https://api.brevo.com/v3/smtp/email"
    payload = {
        "sender": {"name": sender_name, "email": settings.BREVO_SENDER_EMAIL},
        "to": [{"email": to_email}],
        "subject": subject,
        "htmlContent": html_content
    }
  
    headers = {"api-key": settings.BREVO_API_KEY}

    response = requests.post(url, json=payload, headers=headers)
    return response
    
def consultant_my_services(request):
    if request.method == 'POST':
            service_ids = request.POST.getlist('services')
            subcategory_id = request.POST.get('subcategory')
            vertical_id = request.POST.get('vertical')
            for sid in service_ids:
                service = VerticalService.objects.get(id=sid)
                ConsultantService.objects.create(
                    consultant=request.user,
                    service=service,
                    vertical_id=vertical_id,
                    subcategory_id=subcategory_id
                )            
            return redirect('consultant_services_list')
        
    else:
        form = ServiceSelectionForm()
    return render(request, 'cunsultent_my_services.html', {'form': form})


def consultant_services_list(request):
    my_services = ConsultantService.objects.filter(consultant=request.user)
    return render(request, 'my_services_list.html', {'my_services': my_services})


def consultant_service_delete(request, pk):
    cs = get_object_or_404(ConsultantService, pk=pk, consultant=request.user)
    cs.delete()    
    return redirect('consultant_services_list')
    
    
@login_required
def consultant_assigned_bookings(request):
    # Fetch only bookings assigned to the logged-in consultant
    assigned_bookings = ServiceBooking.objects.filter(
        consultant=request.user
    ).order_by('-booked_at')

    return render(request, 'consultant_assigned_bookings.html', {
        'assigned_bookings': assigned_bookings
    })