#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
qbrowser.py - A Qt6-based browser that wraps and extends the Playwright browser class

This module provides a Qt6-based browser interface that wraps the Playwright browser
API and launches Chromium browser instances without decorations using the --app flag.
Each new page is opened as a new tab in the Qt6 window, and the interface includes
URL input, home button, and browser extension management.
"""

import os
import shutil
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import (
    QDialog, QVBoxLayout, QLabel, QListWidget, QHBoxLayout,
    QPushButton, QInputDialog, QMessageBox, QListWidgetItem
)




class ProfileDialog(QDialog):
    """
    Dialog for selecting or creating a browser profile.
    """
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("Select Profile")
        self.setMinimumWidth(400)
        self.selected_profile_path = None
        self.profiles_dir = "data"
        
        if not os.path.exists(self.profiles_dir):
            os.makedirs(self.profiles_dir)

        layout = QVBoxLayout(self)
        
        layout.addWidget(QLabel("Select a profile to launch:"))
        
        self.profile_list = QListWidget()
        self.profile_list.itemDoubleClicked.connect(self.accept_selection)
        layout.addWidget(self.profile_list)
        
        button_layout = QHBoxLayout()
        
        self.new_button = QPushButton("Create New")
        self.new_button.clicked.connect(self.create_new_profile)
        button_layout.addWidget(self.new_button)

        self.delete_button = QPushButton("Delete")
        self.delete_button.clicked.connect(self.delete_profile)
        button_layout.addWidget(self.delete_button)

        button_layout.addStretch()

        self.select_button = QPushButton("Launch")
        self.select_button.setDefault(True)
        self.select_button.clicked.connect(self.accept_selection)
        button_layout.addWidget(self.select_button)
        
        layout.addLayout(button_layout)
        
        self.load_profiles()
        self.update_button_states()

    def update_button_states(self):
        has_selection = len(self.profile_list.selectedItems()) > 0
        self.select_button.setEnabled(has_selection)
        self.delete_button.setEnabled(has_selection)

    def load_profiles(self):
        self.profile_list.clear()
        profiles = []
        for item in os.listdir(self.profiles_dir):
            if os.path.isdir(os.path.join(self.profiles_dir, item)) and item.startswith("browser_profile_"):
                profiles.append(item)
        
        for profile_dir_name in sorted(profiles):
            profile_name = profile_dir_name.replace("browser_profile_", "")
            list_item = QListWidgetItem(profile_name)
            list_item.setData(Qt.ItemDataRole.UserRole, os.path.join(self.profiles_dir, profile_dir_name))
            self.profile_list.addItem(list_item)
        
        if self.profile_list.count() > 0:
            self.profile_list.setCurrentRow(0)
        
        self.profile_list.itemSelectionChanged.connect(self.update_button_states)
        self.update_button_states()

    def create_new_profile(self):
        while True:
            profile_name, ok = QInputDialog.getText(self, "Create New Profile", "Enter a name for the new profile:")
            if not ok:
                return  # User cancelled
            
            if not profile_name.strip():
                QMessageBox.warning(self, "Invalid Name", "Profile name cannot be empty.")
                continue

            profile_path = os.path.join(self.profiles_dir, f"browser_profile_{profile_name.strip()}")
            if not os.path.exists(profile_path):
                try:
                    os.makedirs(profile_path)
                    self._install_default_extensions(profile_path)
                    self.load_profiles()
                    # Select the new profile
                    for i in range(self.profile_list.count()):
                        if self.profile_list.item(i).text() == profile_name.strip():
                            self.profile_list.setCurrentRow(i)
                            break
                    return
                except OSError as e:
                    QMessageBox.critical(self, "Error", f"Could not create profile directory: {e}")
                    return
            else:
                QMessageBox.warning(self, "Profile Exists", "A profile with that name already exists.")

    def delete_profile(self):
        selected_items = self.profile_list.selectedItems()
        if not selected_items:
            return
        
        item = selected_items[0]
        profile_name = item.text()
        profile_path = item.data(Qt.ItemDataRole.UserRole)

        reply = QMessageBox.question(self, "Confirm Deletion", f"Are you sure you want to delete the profile '{profile_name}'?\nThis will permanently delete all its data.",
                                     QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No, QMessageBox.StandardButton.No)

        if reply == QMessageBox.StandardButton.Yes:
            try:
                shutil.rmtree(profile_path)
                self.load_profiles()
                self.update_button_states()
            except Exception as e:
                QMessageBox.critical(self, "Error", f"Could not delete profile: {e}")

    def accept_selection(self):
        selected_items = self.profile_list.selectedItems()
        if not selected_items:
            return
        
        item = selected_items[0]
        self.selected_profile_path = item.data(Qt.ItemDataRole.UserRole)
        self.accept()

    @staticmethod
    def _install_default_extensions(profile_path):
        """Copies default extensions from assets to a new profile directory."""
        source_extensions_dir = "assets/browser/extensions"
        if not os.path.isdir(source_extensions_dir):
            print(f"Default extensions directory not found: {source_extensions_dir}")
            return

        dest_extensions_dir = os.path.join(profile_path, "Default", "Extensions")
        
        try:
            os.makedirs(dest_extensions_dir, exist_ok=True)
            
            for item_name in os.listdir(source_extensions_dir):
                source_item_path = os.path.join(source_extensions_dir, item_name)
                dest_item_path = os.path.join(dest_extensions_dir, item_name)
                
                if os.path.isdir(source_item_path):
                    if not os.path.exists(dest_item_path):
                        shutil.copytree(source_item_path, dest_item_path)
                        print(f"Installed default extension '{item_name}' to profile.")
        except (OSError, IOError) as e:
            QMessageBox.warning(None, "Extension Installation Error",
                                f"Could not install default extensions: {e}")

    @staticmethod
    def get_profile_path(parent=None):
        profiles_dir = "data"
        if not os.path.exists(profiles_dir):
            os.makedirs(profiles_dir)
            
        profiles = [p for p in os.listdir(profiles_dir) if p.startswith("browser_profile_")]

        if not profiles:
            # First run experience: must create a profile to continue.
            while True:
                profile_name, ok = QInputDialog.getText(parent, "Create First Profile", "Welcome! Please create a profile to begin:")
                if not ok:
                    return None  # User cancelled initial creation, so exit.
                
                if not profile_name.strip():
                    QMessageBox.warning(parent, "Invalid Name", "Profile name cannot be empty.")
                    continue

                profile_path = os.path.join(profiles_dir, f"browser_profile_{profile_name.strip()}")
                
                if os.path.exists(profile_path):
                    QMessageBox.warning(parent, "Profile Exists", "A profile with that name already exists. Please choose another name.")
                    continue

                try:
                    os.makedirs(profile_path)
                    ProfileDialog._install_default_extensions(profile_path)
                    return profile_path  # Success!
                except OSError as e:
                    QMessageBox.critical(parent, "Error", f"Could not create profile directory: {e}")
                    return None
        else:
            # Profiles exist, show the manager dialog.
            dialog = ProfileDialog(parent)
            if dialog.exec() == QDialog.DialogCode.Accepted:
                return dialog.selected_profile_path
            else:
                return None  # User closed the manager.


