import os
import cv2
import shutil
import requests

# Setează căile absolute către fișierele de model
current_directory = os.path.dirname(os.path.abspath(__file__))
model_path = os.path.join(current_directory, 'res10_300x300_ssd_iter_140000.caffemodel')
config_path = os.path.join(current_directory, 'deploy.prototxt')

# Link-urile de descărcare pentru modelele de detectare a fețelor
model_url = "https://github.com/opencv/opencv_3rdparty/raw/dnn_samples_face_detector_20170830/res10_300x300_ssd_iter_140000.caffemodel"
config_url = "https://github.com/opencv/opencv/raw/4.x/samples/dnn/face_detector/deploy.prototxt"

# Funcție pentru descărcarea fișierului dacă nu este prezent
def download_file(url, path):
    response = requests.get(url, stream=True)
    if response.status_code == 200:
        with open(path, 'wb') as file:
            for chunk in response.iter_content(chunk_size=8192):
                file.write(chunk)
        print(f"Fișierul a fost descărcat: {path}")
    else:
        print(f"Eroare la descărcarea fișierului de la {url}. Status code: {response.status_code}")

# Verifică și descarcă modelul dacă lipsește
if not os.path.exists(model_path):
    print("Model file not found. Downloading...")
    download_file(model_url, model_path)
else:
    print("Model file found.")

# Verifică și descarcă configurația dacă lipsește
if not os.path.exists(config_path):
    print("Config file not found. Downloading...")
    download_file(config_url, config_path)
else:
    print("Config file found.")

# Încearcă să încarci modelul
try:
    net = cv2.dnn.readNetFromCaffe(config_path, model_path)
    print("Model loaded successfully.")
except Exception as e:
    print(f"Error loading model: {e}")
    exit()

# Cere utilizatorului să introducă numele folderului sursă
input_folder_name = input("Introdu numele folderului sursă cu poze (în același director cu scriptul): ")

# Creează căile absolute pentru folderele sursă și destinație
input_folder = os.path.join(current_directory, input_folder_name)
output_folder = os.path.join(current_directory, 'humanfacial')

# Crează folderul de destinație dacă nu există
if not os.path.exists(output_folder):
    os.makedirs(output_folder)

# Verifică dacă folderul sursă există
if not os.path.exists(input_folder):
    print("Folderul sursă nu există. Te rog să verifici numele introdus.")
else:
    # Parcurge toate fișierele din folderul sursă
    for filename in os.listdir(input_folder):
        if filename.lower().endswith('.jpg') or filename.lower().endswith('.jpeg'):
            # Încarcă imaginea
            img_path = os.path.join(input_folder, filename)
            img = cv2.imread(img_path)
            
            # Verifică dacă imaginea a fost încărcată corect
            if img is None:
                print(f"Nu s-a putut încărca imaginea: {filename}. Verifică dacă fișierul este valid.")
                continue
            
            # Obține dimensiunile imaginii
            h, w = img.shape[:2]

            # Pregătește imaginea pentru rețea
            blob = cv2.dnn.blobFromImage(img, 1.0, (300, 300), (104.0, 177.0, 123.0))

            # Folosește modelul pentru a detecta fețele
            net.setInput(blob)
            detections = net.forward()

            # Verifică dacă există detecții de fețe
            face_detected = False
            for i in range(detections.shape[2]):
                confidence = detections[0, 0, i, 2]
                # Filtrează detecțiile cu un nivel de încredere scăzut
                if confidence > 0.6:
                    face_detected = True
                    break

            # Dacă sunt detectate fețe, mută imaginea în folderul de destinație
            if face_detected:
                shutil.move(img_path, os.path.join(output_folder, filename))
                print(f'Mut imaginea: {filename}')
            else:
                print(f'Nu s-au găsit fețe în: {filename}')

    print(f"Imaginile cu fețe au fost mutate în folderul '{output_folder}'.")
