import cv2
import pandas as pd
import datetime
from django.core.mail import EmailMessage
from django.core.files.base import ContentFile
from django.core.management.base import BaseCommand
from multiprocessing import Process
from myprofile.models import *
from ultralytics import YOLO
from django.conf import settings
# Define a function to process the camera feed and detect objects
def process_device(camera_id):
    # Retrieve camera information from the database
    camera = Camera.objects.get(id=camera_id)
    # Retrieve events associated with the camera
    camera_events = CameraEvent.objects.filter(camera=camera)
    # Retrieve ROI information for the camera
    roi_data = Roi.objects.filter(camera=camera_id)

    # Open the video capture device (e.g., RTSP stream)
    cap = cv2.VideoCapture(camera.rtsp_url)

    # Load the YOLO object detection model
    model = YOLO('model/yolov8s.pt')

    # Read class names from the file
    with open('/home/savan/kalpesh/visnx-backend/Nettyfy_visnx/myprofile/management/commands/coco.txt', 'r') as file:
        class_list = file.read().split('\n')

    while True:
        # Read a frame from the camera feed
        ret, frame = cap.read()

        if not ret:
            break
        
        # Resize the frame
        frame = cv2.resize(frame, (1000, 700))
        
        # Perform object detection
        result = model.predict(frame, conf=0.15)
        results = result[0].boxes.data
        px = pd.DataFrame(results).astype("float")

        for roi in roi_data:
            roi_name = roi.roi_name
            roi_x1 = roi.x1
            roi_y1 = roi.y1
            roi_width = roi.width
            roi_height = roi.width
            
            # Draw the ROI rectangle on the frame
            cv2.rectangle(frame, (roi_x1, roi_y1), (roi_x1 + roi_width, roi_y1 + roi_height), (0, 255, 0), 2)
            cv2.putText(frame, roi_name, (roi_x1, roi_y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)

            # Check if any objects are detected within the ROI

            for index, row in px.iterrows():
                x1, y1, x2, y2, d = map(int, row[:5])
                c = class_list[d]

                if 'person' in c and roi_x1 < x1 < roi_x1 + roi_width and roi_y1 < y1 < roi_y1 + roi_height:

                    print(f'Person detected in {roi_name}',"========================================================")
                    cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 0, 255), 2)
                    cv2.putText(frame, 'Person', (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2)
                    cv2.putText(frame, 'Danger', (x1, y1 - 30), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2)

                    # Create an alert for the detected object
                    alert = Alert(camera=camera, alert_message=f'Person detected in {roi_name}')
                    alert.save()

                    # save camera Incharge in alert
                    alert.camera_incharge.set(camera.camera_user.all())

                    # Create a CameraEvent object for FallDetected
                    danzer_event = CameraEvent.objects.get_or_create(camera_event="DanzerZone")[0]

                    # Save the CameraEvent object to the alert
                    alert.camera_events = danzer_event
                    alert.save()

                    # Save alert image to the database
                    _, encoded_frame = cv2.imencode('.jpg', frame)
                    image_file = ContentFile(encoded_frame.tobytes())
                    alert.frame.save('alert.jpg', image_file)

                    # Send an email notification to the camera incharge
                    # subject = f'Alert: Person detected in {roi_name}'
                    # message = f'A person has been detected in {roi_name} at {datetime.datetime.now()}'
                    # from_email = settings.EMAIL_HOST_USER
                    # recipient_list = ['kuldip.nettyfy@gmail.com']
                    # email = EmailMessage(subject, message, from_email, recipient_list)
                    # email.attach_file(alert.frame.path)
                    # email.send()


        # Display the frame
        cv2.imshow('Frame', frame)

        # Check for the 'q' key to exit the loop
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    # Release the video capture device and close the window
    cap.release()
    cv2.destroyAllWindows()










# Define a custom management command to start the camera feed processing
class Command(BaseCommand):
    help = 'Triggers alerts based on video analysis'

    def handle(self, *args, **options):
        camera = Camera.objects.filter(is_enabled=True)

        processes = []

        for cam in camera:
            process = Process(target=process_device, args=(cam.id,))
            process.start()
            processes.append(process)

        for process in processes:
            process.join()
