import cv2
import os
import numpy as np
import csv
from datetime import datetime

# Initialize the face detector
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

# Font for displaying the user ID on the image
font = cv2.FONT_HERSHEY_SIMPLEX

# Function to recognize the user from the registered faces
def recognize_user():
    # Load all registered user folders
    registered_users = os.listdir("registered_faces")
    
    # Initialize webcam for live detection
    cap = cv2.VideoCapture(0)

    print("Starting face recognition. Please look at the camera...")

    # Path to the CSV log file
    log_file = "user_log.csv"

    # Initialize the CSV file with headers if it doesn't exist
    if not os.path.exists(log_file):
        with open(log_file, mode='w', newline='') as file:
            writer = csv.writer(file)
            writer.writerow(["user_id", "timestamp", "status"])

    while True:
        ret, frame = cap.read()
        if not ret:
            print("Failed to grab frame!")
            break

        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))

        for (x, y, w, h) in faces:
            face = gray[y:y + h, x:x + w]

            # Compare the live face with each registered user face
            recognized_user_id = None
            for user_id in registered_users:
                user_folder = f"registered_faces/{user_id}"
                if not os.path.exists(user_folder):
                    continue

                user_faces = []
                for filename in os.listdir(user_folder):
                    if filename.endswith(".jpg"):
                        img = cv2.imread(f"{user_folder}/{filename}")
                        user_faces.append(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY))

                for stored_face in user_faces:
                    res = cv2.matchTemplate(face, stored_face, cv2.TM_CCOEFF_NORMED)
                    threshold = 0.7
                    if np.max(res) > threshold:
                        recognized_user_id = user_id
                        break

                if recognized_user_id:
                    break

            if recognized_user_id:
                # Get the current date for logging
                current_date = datetime.now().date()

                # Read existing logs to check if the user has already checked in today
                user_logged_in_today = False
                updated_rows = []
                checkout_found = False
                checkin_found = False

                with open(log_file, mode='r', newline='') as file:
                    reader = csv.reader(file)
                    for row in reader:
                        # If the user has already logged in today
                        if row[0] == recognized_user_id and row[1].startswith(str(current_date)):
                            user_logged_in_today = True
                            if row[2] == "Checkout":
                                # If a "Checkout" row exists, replace it
                                row[2] = "Checkout"
                                row[1] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")  # Update timestamp for Checkout
                                checkout_found = True
                            elif row[2] == "Check-in":
                                checkin_found = True  # Mark Check-in found
                        updated_rows.append(row)

                # If user hasn't checked in yet, log as "Check-in"
                if not user_logged_in_today and not checkin_found:
                    updated_rows.append([recognized_user_id, datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "Check-in"])
                
                # If no "Checkout" row was found for today, add it or replace if already exists
                if user_logged_in_today and not checkout_found:
                    updated_rows.append([recognized_user_id, datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "Checkout"])

                # Write updated rows back to CSV
                with open(log_file, mode='w', newline='') as file:
                    writer = csv.writer(file)
                    writer.writerows(updated_rows)

                # Display the user ID and status
                status = "Checkout" if user_logged_in_today else "Check-in"
                cv2.putText(frame, f"User ID: {recognized_user_id} {status}", (x, y - 10), font, 1, (0, 255, 0), 2, cv2.LINE_AA)
                cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
            else:
                cv2.putText(frame, "Unknown User", (x, y - 10), font, 1, (0, 0, 255), 2, cv2.LINE_AA)

        cv2.imshow("Face Recognition", frame)

        # Exit if 'q' is pressed
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    cap.release()
    cv2.destroyAllWindows()

# Run face recognition and user ID detection
recognize_user()
