from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.models import User
from acces.models import DefaultUserScreen, Screen, Camera, CameraRole, CustomUser
# camera_app/views.py
import cv2
from django.http import StreamingHttpResponse, HttpResponse
from django.views.decorators import gzip
import pprint
from django.contrib.auth.decorators import login_required
from .forms import CustomUserCreationForm, CustomLoginForm
from django.contrib import messages
from django.contrib.auth import logout
from django.contrib.auth import views as auth_views

class VideoCamera:
    def __init__(self, rtsp_url):
        self.rtsp_url = rtsp_url
        self.stream = cv2.VideoCapture(self.rtsp_url, cv2.CAP_FFMPEG)

    def __del__(self):
        if self.stream.isOpened():
            self.stream.release()

    def get_frame(self):
        if not self.stream.isOpened():
            self.stream.open(self.rtsp_url)
        success, frame = self.stream.read()
        if not success or frame is None:
            return None
        _, jpeg = cv2.imencode('.jpg', frame)
        return jpeg.tobytes()


def gen(camera):
    while True:
        frame = camera.get_frame()
        if frame:
            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
        else:
            time.sleep(0.5)  # évite de boucler dans le vide

def stream_view(request, id):
    camera = get_object_or_404(Camera, id=id)
    username = camera.username  
    password = camera.password
    ip = camera.ip_address
    port = camera.port if camera.port else 554
    rtsp_url = f"rtsp://{username}:{password}@{ip}:{port}/stream"
    return StreamingHttpResponse(gen(VideoCamera(rtsp_url)), content_type='multipart/x-mixed-replace; boundary=frame')
    
def index(request, id=None):
    user_id = request.user.id
    if id is None or id == 'null':
        try:
            default_screen_setting = DefaultUserScreen.objects.get(user_id=user_id)
            default_screen = default_screen_setting.screen
            camera_list = Camera.objects.filter(
                screencamera__screen=default_screen
            ).distinct()
            screen_type_name = default_screen.type.name
        except DefaultUserScreen.DoesNotExist:
            camera_list = []
            screen_type_name = None
    else:
        try:
            screen = Screen.objects.get(id=id)
            camera_list = Camera.objects.filter(
                screencamera__screen=screen
            ).distinct()
            screen_type_name = screen.type.name
        except Screen.DoesNotExist:
            camera_list = []
            screen_type_name = None
        
    Screens = (
        Screen.objects
        .filter(role_id=CustomUser.objects.get(id=user_id).role_id)
        .values('id', 'designation', 'status', 'default', 'type', 'role')
    )
    # 3. Toutes les caméras accessibles à l'utilisateur via son rôle
    camers = (
        Camera.objects
        .filter(id__in=CameraRole.objects.filter(role_id=CustomUser.objects.get(id=user_id).role_id).values('camera_id'))
        .values()
    )

    context = {
        'camera_list': camera_list,
        'Screens': Screens,
        'camers': camers,
        'screen_type_name': screen_type_name,
    }

    match screen_type_name:
        case '1':
            template_name = 'acces/camera/pages/home.html'
        case "2":
            template_name = 'acces/screen/pages/4.html'
        case "4":
            template_name = 'acces/screen/pages/4.html'
        case "6": 
            template_name = 'acces/screen/pages/6.html'
        case _:
            # Default case if no other case matches
            template_name = 'acces/screen/pages/6.html'
            
    return render(request, template_name, context)

def camera(request, id):
    user_id = request.user.id
    default_camera = Camera.objects.get(id=id)
    Screens = (
        Screen.objects
        .filter(role_id=CustomUser.objects.get(id=user_id).role_id)
        .values('id', 'designation', 'status', 'default', 'type', 'role')
    )
    camers = (
        Camera.objects
        .filter(id__in=CameraRole.objects.filter(role_id=CustomUser.objects.get(id=user_id).role_id).values('camera_id'))
        .values()
    )
    context = {
        'Screens': Screens,
        'camers': camers,
        'default_camera': default_camera,
    }
    return render(request, 'acces/camera/pages/home.html', context)


def fr_dashboard(request):
    return render(request, 'blog/fr/index.html')

def ar_dashboard(request):    
    return render(request, 'blog/ar/index.html')

def en_dashboard(request):    
    return render(request, 'blog/en/index.html')

def custom_login_view(*args, **kwargs):
    return auth_views.LoginView.as_view(
        template_name='auth/login.html',
        authentication_form=CustomLoginForm,
        redirect_authenticated_user=True,
        next_page='/home/2/'
    )(*args, **kwargs)


    
def register(request):
    if request.method == 'POST':
        form = CustomUserCreationForm(request.POST)
        if form.is_valid():
            form.save()
            email = form.cleaned_data.get('email')
            messages.success(request, f'Account created for {email}!')
            return redirect('login')
    else:
        form = CustomUserCreationForm()
    return render(request, 'auth/register.html', {'form': form})

def logout_view(request):
    logout(request)
    return redirect('dashboard')

def map(request):
    user_id = request.user.id
    Screens = (
        Screen.objects
        .filter(role_id=CustomUser.objects.get(id=user_id).role_id)
        .values('id', 'designation', 'status', 'default', 'type', 'role')
    )
    camers = (
        Camera.objects
        .filter(id__in=CameraRole.objects.filter(role_id=CustomUser.objects.get(id=user_id).role_id).values('camera_id'))
        .values()
    )
    context = {
        'Screens': Screens,
        'camers': camers,
    }
    return render(request, 'acces/map/home.html', context)