import sys
import os
import logging
from typing import Optional, Dict
from pathlib import Path
from PyQt6.QtWidgets import (
    QApplication, QMessageBox, QDialog, QListWidget, QVBoxLayout,
    QHBoxLayout, QPushButton, QDialogButtonBox, QInputDialog, QLineEdit,
    QListWidgetItem, QLabel, QSplashScreen
)
import subprocess
import platform
import time
from PyQt6.QtCore import Qt, QTimer
from PyQt6.QtGui import QIcon, QPixmap
from core.config import get_app_data_directory, logger, load_language, get_global_setting
from core.tenant_manager import TenantManager
from ui.tenant_login import TenantLoginDialog
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
class ProfileManagerDialog(QDialog):
    """
    MySQL tabanlı Profil Seçim/Yönetim Ekranı.
    Profil oluşturma, silme ve seçim işlemlerini yönetir.
    """
    def __init__(self, lang: Dict[str, str], db, parent=None):
        super().__init__(parent)
        self.lang = lang
        self.selected_profile_id: Optional[str] = None
        self.selected_profile_name: Optional[str] = None
        self._prompted_create_when_empty: bool = False
        try:
            self.db = db
        except Exception as e:
            QMessageBox.critical(self, "Veritabanı Hatası", f"Veritabanına bağlanılamadı:\n{e}\n\nLütfen veritabanı sunucusunun çalıştığından emin olun.")
            self.reject()
            return
        self.setWindowTitle(self.lang["profile_management"])
        self.setMinimumWidth(450)
        self.setMinimumHeight(450)
        layout = QVBoxLayout(self)
        layout.setSpacing(15)
        lbl_info = QLabel(self.lang.get("select_profile_to_work", "Select the store profile you want to work with:"))
        lbl_info.setStyleSheet("font-size: 14px; font-weight: bold; color: #555;")
        layout.addWidget(lbl_info)
        self.list_widget = QListWidget()
        self.list_widget.setStyleSheet("""
            QListWidget { font-size: 14px; padding: 5px; border: 1px solid #ccc; border-radius: 4px; }
            QListWidget::item { padding: 8px; }
            QListWidget::item:selected { background-color: #3498db; color: white; border-radius: 3px; }
        """)
        self.list_widget.itemDoubleClicked.connect(self.accept)
        layout.addWidget(self.list_widget)
        btn_layout = QHBoxLayout()
        btn_new = QPushButton(self.lang["new_profile"])
        btn_new.setIcon(QIcon.fromTheme("list-add"))
        btn_new.setMinimumHeight(45)
        btn_new.setStyleSheet("font-weight: bold;")
        btn_new.clicked.connect(self.create_new_profile)
        btn_delete = QPushButton(self.lang["delete_profile"])
        btn_delete.setIcon(QIcon.fromTheme("edit-delete"))
        btn_delete.setObjectName("dangerButton")
        btn_delete.setStyleSheet("background-color: #e74c3c; color: white; font-weight: bold; border-radius: 4px;")
        btn_delete.setMinimumHeight(45)
        btn_delete.clicked.connect(self.delete_selected_profile)
        btn_layout.addWidget(btn_new)
        btn_boss = QPushButton(self.lang.get("boss_mode_login", "Boss Login (View All)"))
        btn_boss.setStyleSheet("background-color: #D4AF37; color: black; font-weight: bold; border-radius: 4px;")
        btn_boss.setMinimumHeight(45)
        btn_boss.clicked.connect(self.start_boss_mode)
        btn_layout.addWidget(btn_boss)
        btn_layout.addStretch() # Araya bo?luk
        btn_layout.addWidget(btn_delete)
        layout.addLayout(btn_layout)
        self.buttons = QDialogButtonBox(
            QDialogButtonBox.StandardButton.Ok |
            QDialogButtonBox.StandardButton.Cancel
        )
        self.buttons.button(QDialogButtonBox.StandardButton.Ok).setText(self.lang.get("start_profile", "Start Profile"))
        self.buttons.button(QDialogButtonBox.StandardButton.Cancel).setText(self.lang.get("exit", "Exit"))
        self.buttons.accepted.connect(self.accept)
        self.buttons.rejected.connect(self.reject)
        layout.addWidget(self.buttons)
        self.load_profiles_list()
    
    def load_profiles_list(self):
        """Veritabanındaki aktif profilleri çeker ve listeler."""
        self.list_widget.clear()
        try:
            profiles = self.db.fetch_all(
                """
                SELECT id, name
                FROM profiles
                WHERE is_active = 1 AND COALESCE(is_deleted, 0) = 0
                ORDER BY name ASC
                """
            )
            for prof in profiles:
                item = QListWidgetItem(prof['name'])
                item.setIcon(QIcon.fromTheme("folder")) # Klasör ikonu (varsa)
                item.setData(Qt.ItemDataRole.UserRole, prof['id'])
                self.list_widget.addItem(item)
            if self.list_widget.count() > 0:
                self.list_widget.setCurrentRow(0)
            ok_btn = self.buttons.button(QDialogButtonBox.StandardButton.Ok)
            if ok_btn:
                ok_btn.setEnabled(self.list_widget.count() > 0)
        except Exception as e:
            logger.error(f"Profil listesi yüklenemedi: {e}")
            QMessageBox.warning(self, "Hata", "Profiller yüklenirken bir sorun oluştu.")
    def create_new_profile(self):
        """Yeni bir profil oluşturur (INSERT) ve varsayılan ayarları yükler."""
        name, ok = QInputDialog.getText(
            self, self.lang["new_profile"], self.lang["enter_profile_name"]
        )
        if not ok or not name.strip():
            return
        name = name.strip()
        try:
            from core.profile_sync_service import ProfileSyncService

            ProfileSyncService(self.db).create_local_profile(
                name,
                source="main.ProfileManagerDialog.create_new_profile",
            )
            self.load_profiles_list()
            items = self.list_widget.findItems(name, Qt.MatchFlag.MatchExactly)
            if items:
                self.list_widget.setCurrentItem(items[0])
            QMessageBox.information(self, self.lang["success"], f"'{name}' profili başarıyla oluşturuldu.")
        except Exception as e:
            logger.error(f"Profil oluşturma hatası: {e}")
            QMessageBox.critical(self, self.lang["error"], str(e))

    def delete_selected_profile(self):
        """Seçili profili ve tüm verilerini siler."""
        item = self.list_widget.currentItem()
        if not item:
            return
        
        profile_id = item.data(Qt.ItemDataRole.UserRole)
        profile_name = item.text()
        
        confirm = QMessageBox.question(
            self,
            self.lang["delete_profile"],
            f"'{profile_name}' profilini gerçekten silmek istiyor musunuz?\nBu işlem geri alınamaz.",
            QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
        )
        
        if confirm != QMessageBox.StandardButton.Yes:
            return

        try:
            from core.profile_sync_service import ProfileSyncService

            ProfileSyncService(self.db).delete_local_profile(
                profile_id=profile_id,
                profile_name=profile_name,
                source="main.delete_selected_profile",
            )

            row = self.list_widget.row(item)
            self.list_widget.takeItem(row)
            QMessageBox.information(self, "Başarılı", f"'{profile_name}' silindi. İnternet bağlandığında buluttan da silinecek.")
        except Exception as e:
            QMessageBox.critical(self, "Hata", f"Silinemedi: {e}")

    def start_boss_mode(self):
        """T?m profilleri se?er ve ?ifrelerini do?rular."""
        from core.auth import AuthRepository

        profiles = []
        for i in range(self.list_widget.count()):
            item = self.list_widget.item(i)
            profiles.append({
                "id": item.data(Qt.ItemDataRole.UserRole),
                "name": item.text()
            })

        if not profiles:
            QMessageBox.warning(self, "Hata", "G?r?nt?lenecek ?ube bulunamad?.")
            return

        authorized_profiles = []
        profile_map = {}

        for prof in profiles:
            auth_repo = AuthRepository(self.db, prof["id"])
            if auth_repo.has_admin_password(prof['id']):
                password, ok = QInputDialog.getText(
                    self,
                    "?? Patron G?venlik Onay?",
                    f"'{prof['name']}' ?ubesi kilitli. L?tfen ?ifresini girin:",
                    QLineEdit.EchoMode.Password
                )
                if not ok:
                    return
                if not auth_repo.verify_profile_password(password, profile_id=prof['id']):
                    QMessageBox.critical(self, "Hata", f"'{prof['name']}' ?ubesi i?in ?ifre yanl??! Patron moduna girilemiyor.")
                    return

            authorized_profiles.append(prof['id'])
            profile_map[prof['id']] = prof['name']

        self.selected_profile_id = authorized_profiles
        self.selected_profile_name = profile_map
        super().accept()

    def accept(self):
        """Seçimi onayla ve veriyi ana uygulamaya ilet."""
        item = self.list_widget.currentItem()
        if not item:
            QMessageBox.warning(self, self.lang["warning"], self.lang["select_profile"])
            return
        self.selected_profile_id = item.data(Qt.ItemDataRole.UserRole)
        self.selected_profile_name = item.text()
        super().accept()
def main():
    if hasattr(Qt.ApplicationAttribute, 'AA_EnableHighDpiScaling'):
        QApplication.setAttribute(Qt.ApplicationAttribute.AA_EnableHighDpiScaling, True)
    if hasattr(Qt.ApplicationAttribute, 'AA_UseHighDpiPixmaps'):
        QApplication.setAttribute(Qt.ApplicationAttribute.AA_UseHighDpiPixmaps, True)
    os.environ["QT_ENABLE_HIGHDPI_SCALING"] = "1"
    os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1"
    app = QApplication(sys.argv)
    app.setStyle("Fusion")

    tenant_manager = TenantManager()
    global_lang_code = get_global_setting("language", "TR")
    global_lang = load_language(global_lang_code)
    if not tenant_manager.is_license_valid():
        tenant_dialog = TenantLoginDialog(tenant_manager, global_lang)
        if tenant_dialog.exec() != QDialog.DialogCode.Accepted:
            raise SystemExit(0)
        if not tenant_manager.is_license_valid():
            error_detail = tenant_manager.get_last_validation_error() or "Lisans dogrulamasi basarisiz. Lutfen tekrar giris yapin."
            QMessageBox.critical(
                None,
                "License Error",
                error_detail,
            )
            raise SystemExit(1)

    if platform.system() == "Darwin":
        try:
            logger.info("macOS detected, Local-First mode: starting local MySQL...")
            subprocess.run(["brew", "services", "start", "mysql"], capture_output=True)
            time.sleep(5)
        except Exception as e:
            logger.error(f"MySQL startup command failed: {e}")

    from core.db_factory import get_database_adapter
    db = get_database_adapter()
    try:
        logger.info("Veritabanı bağlantısı başlatılıyor...")
        db.connect()
    except Exception as e:
        error_msg = f"Kritik Hata: Veritabanı başlatılamadı!\n\nDetay: {e}"
        logger.critical(error_msg)
        QMessageBox.critical(None, "Başlatma Hatası", error_msg)
        sys.exit(1)

    if tenant_manager.is_profile_sync_enabled() and not tenant_manager.get_api_token():
        logger.warning(
            "Cloud session is unavailable. App will continue in offline mode and sync will be deferred."
        )

    if tenant_manager.is_profile_sync_enabled() and tenant_manager.get_api_token():
        try:
            from core.profile_sync import ProfileBootstrapService

            ProfileBootstrapService(db, tenant_manager=tenant_manager).run_if_needed()
        except Exception as e:
            logger.warning(f"Profile bootstrap skipped: {e}")

    from core.auth import UserLoginDialog, AuthRepository
    from core.db import DataManager, SettingsManager
    from ui.main_window import JewelryStoreApp

    try:
        def _resolve_user_data(sm: SettingsManager, auth_repo: AuthRepository, force_login: bool = False):
            if not force_login:
                bootstrap_user = auth_repo.get_passwordless_bootstrap_user()
                if bootstrap_user:
                    return {
                        "username": str(bootstrap_user.get("username") or "admin"),
                        "role": "admin",
                        "name": str(bootstrap_user.get("full_name") or bootstrap_user.get("username") or "Yönetici"),
                        "permissions": "ALL",
                        "allowed_depots": None,
                        "allowed_cash_accounts": None,
                        "allowed_card_accounts": None,
                    }
            lang_code = get_global_setting("language", "TR")
            lang = load_language(lang_code)
            login = UserLoginDialog(sm, lang)
            if login.exec() != QDialog.DialogCode.Accepted:
                return None
            return {
                "username": login.selected_username,
                "role": login.selected_user_role,
                "name": login.selected_user_name,
                "permissions": login.selected_user_permissions,
                "allowed_depots": getattr(login, "selected_allowed_depots", []),
                "allowed_cash_accounts": getattr(login, "selected_allowed_cash", []),
                "allowed_card_accounts": getattr(login, "selected_allowed_card", []),
            }

        while True:
            selected_profile_name = None
            dm = None
            while True:
                dialog = ProfileManagerDialog(global_lang, db)
                if dialog.exec() != QDialog.DialogCode.Accepted:
                    raise SystemExit(0)
                selected_profile_name = dialog.selected_profile_name
                if not selected_profile_name:
                    continue
                try:
                    if isinstance(dialog.selected_profile_id, list):
                        from core.db import AggregateDataManager
                        dm = AggregateDataManager(dialog.selected_profile_id, dialog.selected_profile_name)
                        selected_profile_name = "?? Patron G?r?n?m? (T?m ?ubeler)"
                        user_data = {
                            "username": "boss",
                            "role": "admin",
                            "name": "?? Kurucu / Patron",
                            "permissions": "ALL",
                            "allowed_depots": None,
                            "allowed_cash_accounts": None,
                            "allowed_card_accounts": None,
                        }
                        is_boss_mode = True
                    else:
                        dm = DataManager(profile_file_path=selected_profile_name)
                        is_boss_mode = False
                    break
                except ValueError as e:
                    logger.warning(f"Se?ilen profil y?klenemedi: {e}")
                    QMessageBox.warning(None, "Profil Bulunamad?", str(e))
                    continue

            if not dm:
                raise SystemExit(0)

            sm = SettingsManager(dm)
            force_login_screen = False

            while True:
                if is_boss_mode:
                    user_data_local = user_data
                else:
                    auth_repo = AuthRepository(dm.db, dm.profile_id)
                    user_data_local = _resolve_user_data(sm, auth_repo, force_login=force_login_screen)
                    force_login_screen = False
                    if not user_data_local:
                        raise SystemExit(0)

                window = JewelryStoreApp(
                    profile_file_path=selected_profile_name,
                    profile_name=selected_profile_name,
                    user_data=user_data_local,
                    data_manager=dm,
                    settings_manager=sm,
                    tenant_manager=tenant_manager,
                    is_boss_mode=is_boss_mode,
                )
                window.theme_manager.apply_theme()
                window.showMaximized()
                exit_code = app.exec()
                try:
                    window.deleteLater()
                except Exception:
                    pass

                if exit_code == 3:
                    force_login_screen = True
                    continue
                if exit_code == 2:
                    break
                if exit_code == 4:
                    try:
                        tenant_manager.logout_current_desktop_session()
                    except Exception as e:
                        logger.warning(f"Ana kullanıcı çıkışında uzak masaüstü oturumu kapatılamadı: {e}")
                    try:
                        tenant_manager.clear_license()
                    except Exception as e:
                        logger.warning(f"Ana kullanıcı çıkışında lisans temizlenemedi: {e}")
                    try:
                        from core.db_factory import _reset_database_adapter_for_tests
                        _reset_database_adapter_for_tests()
                    except Exception as e:
                        logger.warning(f"DB adapter reset yapılamadı: {e}")
                    try:
                        subprocess.Popen([sys.executable, *sys.argv], cwd=os.getcwd())
                    except Exception as e:
                        logger.error(f"Uygulama yeniden başlatılamadı: {e}")
                    raise SystemExit(0)
                sys.exit(exit_code)
    except SystemExit:
        pass
    except Exception as e:
        error_msg = f"Beklenmeyen bir hata oluştu ve program kapatılıyor:\n{e}"
        logger.error(error_msg, exc_info=True)
        QMessageBox.critical(None, "Kritik Hata", error_msg)
        sys.exit(1)
    finally:
        logger.info("Program kapatılıyor, veritabanı durduruluyor...")
        if 'db' in locals():
            db.close()
if __name__ == "__main__":
    main()
    





