import os
import cv2
import base64
from datetime import datetime
from openpyxl import Workbook
from openpyxl.drawing.image import Image as xlImage
from openpyxl.styles import Protection
from openpyxl.worksheet.protection import SheetProtection
from tkinter import Tk, Button, Label, filedialog, messagebox, Frame, Toplevel, Entry
from tkinter import ttk
from PIL import Image, ImageTk, ImageDraw, ImageFont
import numpy as np
from mtcnn import MTCNN
#import google.auth
#from google.auth.transport.requests import Request
#from google.oauth2.credentials import Credentials
#from google_auth_oauthlib.flow import InstalledAppFlow
#from googleapiclient.discovery import build
#from googleapiclient.http import MediaFileUpload
import webbrowser


from flask import Flask , render_template, url_for, request

application = Flask(__name__)



@application.route("/")
def main():
    #person = {"name":"website", "website":"gtsstech.com"}
    #return person
    return render_template("index.html")
    
    
'''
SCOPES = ['https://www.googleapis.com/auth/drive.file']

def authenticate_google_drive():
    creds = None
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        with open('token.json', 'w') as token:
            token.write(creds.to_json())
    return creds
'''

'''
def upload_to_drive(file_path, creds):
    service = build('drive', 'v3', credentials=creds)
    file_metadata = {'name': os.path.basename(file_path)}
    media = MediaFileUpload(file_path, resumable=True)
    file = service.files().create(body=file_metadata, media_body=media, fields='id').execute()
    file_id = file.get('id')
    service.permissions().create(
        fileId=file_id,
        body={'type': 'anyone', 'role': 'writer'},
    ).execute()
    public_url = f"https://drive.google.com/file/d/{file_id}/view?usp=sharing"
    return public_url
'''

def image_to_base64(image):
    _, buffer = cv2.imencode('.jpg', image)
    encoded_image = base64.b64encode(buffer).decode('utf-8')
    return encoded_image

def detect_faces(input_image_path, frame):
    frame.clear()

    now = datetime.now()
    current_date = now.strftime("%Y-%m-%d-%H-%M-%S")
    output_folder = "detected_faces_" + current_date
    
    dir_path = os.path.dirname(os.path.realpath(__file__))
    output_folder = dir_path + "\\"+output_folder 
    
    os.makedirs(output_folder, exist_ok=True)

    

    wb = Workbook()
    ws = wb.active

    ws.column_dimensions['A'].width = 30
    ws.column_dimensions['B'].width = 20
    ws.column_dimensions['C'].width = 20

    ws.append(["IMAGE", "NAME", "ID"])

    detected_faces = set()
    row_number = 2

 #   detector = MTCNN(min_face_size=20, scale_factor=0.7, steps_threshold=[0.6, 0.7, 0.7])
    detector = MTCNN()
    
    
    input_image = cv2.imread(input_image_path)
    faces = detector.detect_faces(input_image)
    total_faces = len(faces)

    for i, face_info in enumerate(faces):
        x, y, w, h = face_info['box']
        cv2.rectangle(input_image, (x, y), (x + w, y + h), (0, 255, 0), 2)

        # Add enumeration text for each face
        cv2.putText(input_image, f"Face {i + 1}", (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.3, (0, 0, 255), 1)

    # Add total face count text
    cv2.putText(input_image, f"Total Faces: {total_faces}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)

    original_image_path = os.path.join(output_folder, f"original_with_faces_{current_date}.jpg")
    cv2.imwrite(original_image_path, input_image)

    for i, face_info in enumerate(faces):
        x, y, w, h = face_info['box']
        face_image = input_image[y:y + h, x:x + w]

        face_image_rgb = cv2.cvtColor(face_image, cv2.COLOR_BGR2RGB)
        pil_image = Image.fromarray(face_image_rgb)
        draw = ImageDraw.Draw(pil_image)

        font = ImageFont.load_default()
        face_text = f"Face {i + 1}/{total_faces}"
        text_width, text_height = draw.textbbox((0, 0), face_text, font=font)[2:]
        position = (w - text_width - 10, 10)

        draw.text(position, face_text, font=font, fill=(255, 0, 0))
        pil_image = pil_image.resize((100, 100), Image.ADAPTIVE)

        tk_image = ImageTk.PhotoImage(pil_image)
        label = Label(frame, image=tk_image)
        label.image = tk_image
        label.pack(side='left', padx=5, pady=5)

        face_image = cv2.cvtColor(np.array(pil_image), cv2.COLOR_RGB2BGR)
        encoded_image_string = image_to_base64(face_image)
        if encoded_image_string not in detected_faces:
            img_data = base64.b64decode(encoded_image_string)
            img_file = os.path.join(output_folder, f"face_{current_date}_{i + 1}.png")
            with open(img_file, 'wb') as f:
                f.write(img_data)
            img = xlImage(img_file)

            ws.add_image(img, f"A{row_number}")
            ws.cell(row=row_number, column=2).value = ""
            ws.cell(row=row_number, column=3).value = ""

            ws.cell(row=row_number, column=1).protection = Protection(locked=True)
            row_number += 6
            detected_faces.add(encoded_image_string)

    for row in ws.iter_rows(min_row=1, max_col=ws.max_column, max_row=ws.max_row):
        for cell in row:
            cell.protection = Protection(locked=False)
    for row in ws.iter_rows(min_row=2, max_col=1, max_row=ws.max_row):
        for cell in row:
            cell.protection = Protection(locked=True)
    ws.protection = SheetProtection(sheet=True, objects=True, scenarios=True, password='password')

    
    
    excel_file_path = current_date + ".xlsx"
    excel_file_path = os.path.join(output_folder, excel_file_path)
    wb.save(excel_file_path)
    wb.close()

 #   creds = authenticate_google_drive()
 #   public_url = upload_to_drive(excel_file_path, creds)
    show_success_message(excel_file_path)

def show_success_message(public_url):
    success_window = Toplevel()
    success_window.title("Success")
    success_window.geometry("400x200")

    label = Label(success_window, text="Face detection completed and results saved.", pady=10)
    label.pack()

    link_entry = Entry(success_window, width=50, fg="blue", cursor="hand2")
    link_entry.insert(0, public_url)
    link_entry.config(state="readonly")
    link_entry.pack()

    link_entry.bind("<Button-1>", lambda e: webbrowser.open_new(public_url))

    button = Button(success_window, text="OK", command=success_window.destroy, pady=5)
    button.pack(pady=20)

def select_image():
    #filename = filedialog.askopenfilename(initialdir="/", title="Select Image File", filetypes=(("JPEG files", "*.jpg"), ("PNG files", "*.png"), ("All files", "*.*")))
    
    filename = filedialog.askopenfilename( title="Select Image File", filetypes=(("JPEG files", "*.jpg"), ("PNG files", "*.png"), ("All files", "*.*")))

    if filename:
        try:
            detect_faces(filename, face_frame)
        except Exception as e:
            messagebox.showerror("Error", f"An error occurred: {str(e)}")

class CustomFrame(Frame):
    def clear(self):
        for widget in self.winfo_children():
            widget.destroy()

root = Tk()
root.title("Face Detection")

select_button = Button(root, text="Select Image", command=select_image, padx=10, pady=5)
select_button.pack(pady=20)

face_frame = CustomFrame(root)
face_frame.pack()

root.mainloop()


if __name__ == "__main__":
    application.run(debug=True)
