#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
from gi.repository import Gtk, Gdk, GLib, Adw

import cv2
import sys
import subprocess
import numpy as np

class FaceIDGTK(Gtk.ApplicationWindow):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.set_title("FaceID GTK")
        self.set_default_size(640, 560)
        self.set_resizable(False)

        # Main layout box
        self.main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)
        self.main_box.set_margin_top(12)
        self.main_box.set_margin_bottom(12)
        self.main_box.set_margin_start(12)
        self.main_box.set_margin_end(12)
        self.set_child(self.main_box)

        # Header bar
        header = Gtk.HeaderBar()
        self.set_titlebar(header)
        
        # Webcam Picture widget
        self.picture = Gtk.Picture()
        self.picture.set_content_fit(Gtk.ContentFit.CONTAIN)
        self.main_box.append(self.picture)

        # --- Buttons for Howdy Actions ---
        grid = Gtk.Grid()
        grid.set_column_spacing(6)
        grid.set_halign(Gtk.Align.CENTER)
        self.main_box.append(grid)
        
        btn_add = Gtk.Button(label="Add Face Model")
        btn_add.connect("clicked", self.on_add_face)
        grid.attach(btn_add, 0, 0, 1, 1)

        btn_list = Gtk.Button(label="List Models")
        btn_list.connect("clicked", self.on_list_faces)
        grid.attach(btn_list, 1, 0, 1, 1)

        btn_config = Gtk.Button(label="Edit Config")
        btn_config.connect("clicked", self.on_edit_config)
        grid.attach(btn_config, 2, 0, 1, 1)

        # --- Webcam Initialization ---
        self.cap = cv2.VideoCapture(0)
        if not self.cap.isOpened():
            print("Cannot open webcam")
            self.show_error_dialog("Webcam Error", "Could not open webcam. Ensure it is connected and not in use by another application.")
        else:
            GLib.timeout_add(30, self.update_frame)
        
    def run_command(self, command):
        """Runs a command and shows output or error."""
        try:
            full_command = ["pkexec"] + command
            result = subprocess.run(full_command, capture_output=True, text=True, check=True)
            self.show_info_dialog("Command Succeeded", result.stdout)
        except subprocess.CalledProcessError as e:
            self.show_error_dialog("Command Failed", e.stderr)
        except FileNotFoundError:
            self.show_error_dialog("Error", "The 'pkexec' command was not found. Please ensure 'polkit' is installed.")

    def on_add_face(self, widget):
        self.run_command(["howdy", "add"])

    def on_list_faces(self, widget):
        self.run_command(["howdy", "list"])

    def on_edit_config(self, widget):
        self.run_command(["gedit", "/lib/security/howdy/config.ini"])

    def update_frame(self):
        if not self.cap.isOpened():
            return False
        ret, frame = self.cap.read()
        if not ret:
            return True
        rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        height, width, channels = rgb.shape
        bytes_data = GLib.Bytes.new(rgb.tobytes())
        texture = Gdk.MemoryTexture.new(width, height, Gdk.MemoryFormat.R8G8B8, bytes_data, width * channels)
        self.picture.set_paintable(texture)
        return True

    def show_error_dialog(self, title, message):
        dialog = Adw.MessageDialog.new(self, title, message)
        dialog.add_response("ok", "OK")
        dialog.set_response_appearance("ok", Adw.ResponseAppearance.DESTRUCTIVE)
        dialog.connect("response", lambda d, r: d.close())
        dialog.present()
        
    def show_info_dialog(self, title, message):
        dialog = Adw.MessageDialog.new(self, title, message)
        dialog.add_response("ok", "OK")
        dialog.connect("response", lambda d, r: d.close())
        dialog.present()

    def on_close_request(self, *args):
        if self.cap.isOpened():
            self.cap.release()
        self.get_application().quit()

# This class was missing in the previous version, causing the syntax error.
class FaceIDApp(Adw.Application):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.connect('activate', self.on_activate)

    def on_activate(self, app):
        self.win = FaceIDGTK(application=app)
        self.win.present()

# This is the entry point that runs the application.
if __name__ == "__main__":
    app = FaceIDApp(application_id="com.github.yourusername.faceidgtk")
    sys.exit(app.run(sys.argv))
