from django.shortcuts import render, get_object_or_404
from django.contrib.auth.decorators import login_required
from .models import Business, Service, Call, Booking, Contact
from django.db.models import Count
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
import json
from twilio.twiml.voice_response import VoiceResponse, Gather
from django.urls import reverse
from ai.local_ai_api import LocalAIApi
from .booking import create_booking

from datetime import datetime

#@login_required
def dashboard(request):
    """Render the main admin dashboard."""
    businesses = Business.objects.annotate(
        service_count=Count('services', distinct=True),
        call_count=Count('calls', distinct=True),
        booking_count=Count('services__bookings', distinct=True)
    )
    recent_calls = Call.objects.order_by('-start_time')[:10]
    upcoming_bookings = Booking.objects.filter(start_time__gte=datetime.now()).order_by('start_time')[:10]

    context = {
        'businesses': businesses,
        'recent_calls': recent_calls,
        'upcoming_bookings': upcoming_bookings,
        'page_title': 'Dashboard - Xfront'
    }
    return render(request, 'core/index.html', context)


def business_detail(request, business_id):
    """Display a detailed view of a business."""
    business = get_object_or_404(Business, pk=business_id)
    services = business.services.all()
    calls = business.calls.all().order_by('-start_time')[:10]
    bookings = Booking.objects.filter(service__business=business).order_by('-start_time')[:10]

    context = {
        'business': business,
        'services': services,
        'calls': calls,
        'bookings': bookings,
        'page_title': f'{business.business_name} - Details'
    }
    return render(request, 'core/business_detail.html', context)

@csrf_exempt
def inbound_call_webhook(request):
    """Handle inbound calls from Twilio."""
    if request.method == 'POST':
        from_number = request.POST.get('From')
        to_number = request.POST.get('To')

        try:
            business = Business.objects.get(phone_number=to_number)
        except Business.DoesNotExist:
            response = VoiceResponse()
            response.say("The number you have called is not associated with a business.")
            return HttpResponse(str(response), content_type='text/xml')

        contact, _ = Contact.objects.get_or_create(phone_number=from_number)

        call = Call.objects.create(
            business=business,
            contact=contact,
        )

        response = VoiceResponse()
        response.say(f"Hello and welcome to {business.business_name}. Please wait while we connect you to our AI assistant.")
        response.redirect(reverse('ai_call_handler', args=[call.id]))
        return HttpResponse(str(response), content_type='text/xml')

    return HttpResponse(status=400)

tools = [
    {
        "type": "function",
        "function": {
            "name": "create_booking",
            "description": "Creates a booking for a given service at a specific time.",
            "parameters": {
                "type": "object",
                "properties": {
                    "service_name": {
                        "type": "string",
                        "description": "The name of the service to book.",
                    },
                    "booking_time_str": {
                        "type": "string",
                        "description": "The desired time for the booking in ISO 8601 format.",
                    },
                },
                "required": ["service_name", "booking_time_str"],
            },
        },
    }
]

@csrf_exempt
def ai_call_handler(request, call_id):
    """Handle the AI-powered conversation."""
    call = get_object_or_404(Call, pk=call_id)
    response = VoiceResponse()

    if 'SpeechResult' in request.POST:
        user_speech = request.POST['SpeechResult']
        call.conversation_history.append({'role': 'user', 'content': user_speech})

        services = Service.objects.filter(business=call.business)
        services_prompt = "\n".join([f"- {s.name}: {s.description}" for s in services])

        # Get AI response
        ai_response = LocalAIApi.create_response(
            {
                "input": [
                    {
                        "role": "system",
                        "content": f"You are a friendly and helpful AI assistant for {call.business.business_name}. Available services are:\n{services_prompt}"
                    },
                    *call.conversation_history
                ],
                "tools": tools,
                "tool_choice": "auto",
            },
            {
                "poll_interval": 5,
                "poll_timeout": 300,
            },
        )

        if ai_response.get("success") and ai_response.get("data", {}).get("output", [{}])[0].get("content", [{}])[0].get("type") == "tool_calls":
            tool_calls = ai_response["data"]["output"][0]["content"][0]["tool_calls"]
            call.conversation_history.append({"role": "assistant", "content": None, "tool_calls": tool_calls})

            for tool_call in tool_calls:
                function_name = tool_call['function']['name']
                if function_name == 'create_booking':
                    args = json.loads(tool_call['function']['arguments'])
                    result = create_booking(
                        contact_phone_number=call.contact.phone_number,
                        service_name=args.get("service_name"),
                        booking_time_str=args.get("booking_time_str"),
                    )
                    call.conversation_history.append({"role": "tool", "tool_call_id": tool_call['id'], "name": function_name, "content": result})

            # Get AI response after tool call
            ai_response = LocalAIApi.create_response(
                {
                    "input": [
                        {
                            "role": "system",
                            "content": f"You are a friendly and helpful AI assistant for {call.business.business_name}. Available services are:\n{services_prompt}"
                        },
                        *call.conversation_history
                    ],
                    "tools": tools,
                    "tool_choice": "auto",
                },
                {
                    "poll_interval": 5,
                    "poll_timeout": 300,
                },
            )
            ai_text = LocalAIApi.extract_text(ai_response)
        else:
            ai_text = LocalAIApi.extract_text(ai_response)

        if not ai_text:
            ai_text = "I am sorry, I am having trouble understanding. Please try again."

        call.conversation_history.append({'role': 'assistant', 'content': ai_text})
        response.say(ai_text)

    else:
        # First turn of the conversation
        response.say("How can I help you today?")

    gather = Gather(input='speech', action=reverse('ai_call_handler', args=[call.id]), speechTimeout='auto')
    response.append(gather)

    call.save()

    return HttpResponse(str(response), content_type='text/xml')
