import sys
import os
import json
import inspect
from pathlib import Path
from datetime import datetime

from PyQt6.QtWidgets import (QApplication, QMainWindow, QMessageBox,
                             QFileDialog, QProgressBar, QLabel)
from PyQt6.QtCore import Qt, pyqtSignal, pyqtSlot, QUrl, QVariant
from PyQt6.QtGui import QMovie, QPixmap
from PyQt6.uic import loadUi
from win32com.client import CDispatch

# Proje modüllerini import et
sys.path.append(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()) + "\\..\\..")))
_current_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
_project_root = os.path.dirname(os.path.dirname(os.path.dirname(_current_dir)))
sys.path.insert(0, _project_root)
sys.path.insert(0, _current_dir)

from IFikatia import IFikatia
from threadManager import Async


class IFikoCikariciDialog(QMainWindow):
    """
    FikoYT Çıkarıcı Dialog

    CATIA dökümanlarından aşağıdaki işlemleri gerçekleştirir:
    - WRL (VRML) formatında 3D dosya dışa aktarma
    - Kamera görüntülerinden PNG/JPG resim çekme
    - Teknik dokümantasyon oluşturma
    - Tüm verileri .fikoyt gizli klasöründe saklama
    """

    # PyQt Signal'i - işlem tamamlandığında emit edilir
    sinyal = pyqtSignal(str, QVariant)

    def __init__(self, parent=None, flags=0, Catia=None):
        """
        Dialog constructor

        Args:
            parent: Parent widget (None - standalone)
            flags: Qt window flags
            Catia: CATIA COM Application nesnesi
        """
        # CATIA COM nesnesi kontrolü
        if Catia is None:
            raise ValueError("CATIA parametresi boş olamaz!")

        # CATIA COM nesnesi sarmalama
        self.__fikatia = IFikatia(obj=Catia)
        self.__dokuman = self.__fikatia.aktifDokuman

        # PyQt6 initialization
        if not QApplication.instance():
            self.app = QApplication([sys.argv])
        else:
            self.app = QApplication.instance()

        super(IFikoCikariciDialog, self).__init__(parent, flags)

        # Script dosyasının yolu
        self.ScriptYolu = str(Path(__file__).parent)

        # Proje kök dizini
        self.ProjeKlasoru = self.__dokuman.klasoru if self.__dokuman else ""

        # .fikoyt gizli klasörü yolu (henüz oluşturulmamış)
        self.FikoytKlasoru = os.path.join(self.ProjeKlasoru, ".fikoyt")

        # PyQt6 UI dosyasını yükle
        try:
            ui_path = os.path.join(self.ScriptYolu, "formAna.ui")
            self.ui = loadUi(ui_path, self)
        except Exception as e:
            QMessageBox.critical(self, "Hata", f"UI dosyası yüklenemedi: {e}")
            self.close()
            return

        # Pencere özelliklerini ayarla
        self.setWindowFlags(
            Qt.WindowType.Window |
            Qt.WindowType.WindowCloseButtonHint |
            Qt.WindowType.CustomizeWindowHint |
            Qt.WindowType.WindowStaysOnTopHint
        )

        self.setWindowTitle("FikoYT - Çıkarıcı Dialog")
        self.setGeometry(100, 100, 600, 500)

        # Loading animasyonu
        self._setup_loading_animation()

        # Signal-slot bağlantıları
        self._connect_signals()

        # Mevcut durum
        self.islem_devamda = False

    def _setup_loading_animation(self):
        """Loading GIF animasyonunu ekle"""
        try:
            # Resimler klasöründen GIF dosyasını yükle
            gif_path = os.path.join(self.ScriptYolu, "Resimler", "hiper.gif")
            if hasattr(self.ui, 'labelLoading') and os.path.exists(gif_path):
                movie = QMovie(gif_path)
                self.ui.labelLoading.setMovie(movie)
                self.ui.labelLoading.hide()  # Başlangıçta gizli
                self.loading_movie = movie
        except Exception as e:
            print(f"Loading animasyonu yüklenemedi: {e}")

    def _connect_signals(self):
        """PyQt6 signal-slot bağlantılarını kur"""
        # İç signal
        self.sinyal.connect(self.sinyalGeldi)

        # Dialog butonları (formAna.ui'de tanımlandığını varsayıyoruz)
        if hasattr(self.ui, 'btnWrlKaydet'):
            self.ui.btnWrlKaydet.clicked.connect(self.wrl_kaydet)

        if hasattr(self.ui, 'btnResimCek'):
            self.ui.btnResimCek.clicked.connect(self.resim_cek)

        if hasattr(self.ui, 'btnDokumanOlustur'):
            self.ui.btnDokumanOlustur.clicked.connect(self.dokuman_olustur)

        if hasattr(self.ui, 'btnCikis'):
            self.ui.btnCikis.clicked.connect(self.close)

        # Checkbox'lar (seçenekler)
        if hasattr(self.ui, 'checkWrlKaydet'):
            self.ui.checkWrlKaydet.stateChanged.connect(self.ozellik_degisti)

        if hasattr(self.ui, 'checkResimCek'):
            self.ui.checkResimCek.stateChanged.connect(self.ozellik_degisti)

        if hasattr(self.ui, 'checkDokumanOlustur'):
            self.ui.checkDokumanOlustur.stateChanged.connect(self.ozellik_degisti)

    @pyqtSlot()
    def wrl_kaydet(self):
        """WRL (VRML) formatında 3D dosya dışa aktarma"""
        if self.islem_devamda:
            QMessageBox.warning(self, "Uyarı", "Başka bir işlem devam ediyor.")
            return

        self._fikoyt_klasoru_kontrol_et()

        # Async işlem başlat
        self._wrl_kaydet_async()

    @Async()
    def _wrl_kaydet_async(self):
        """WRL kaydetme işlemi (thread'de çalışır)"""
        try:
            self.islem_devamda = True
            self.sinyal.emit("Durum", "WRL dosyası kaydediliyor...")

            # CATIA'daki aktif belge
            doc = self.__dokuman.catNesne

            # WRL dosyasının yolu
            wrl_dosya = os.path.join(self.FikoytKlasoru, "model.wrl")

            # ExportData ile WRL formatında dışa aktar
            # CATIA format kodu: "wrl" veya "3DREP"
            doc.ExportData(wrl_dosya, "wrl")

            self.sinyal.emit("Basarili",
                           {"dosya": wrl_dosya, "tip": "WRL"})
            self.islem_devamda = False

        except Exception as e:
            self.sinyal.emit("Hata", {"mesaj": f"WRL kaydedilemedi: {str(e)}"})
            self.islem_devamda = False

    @pyqtSlot()
    def resim_cek(self):
        """Belge görüntüsünden PNG/JPG resim çekme"""
        if self.islem_devamda:
            QMessageBox.warning(self, "Uyarı", "Başka bir işlem devam ediyor.")
            return

        self._fikoyt_klasoru_kontrol_et()

        # Async işlem başlat
        self._resim_cek_async()

    @Async()
    def _resim_cek_async(self):
        """Resim çekme işlemi (thread'de çalışır)"""
        try:
            self.islem_devamda = True
            self.sinyal.emit("Durum", "Resim çekiliyor...")

            doc = self.__dokuman.catNesne
            pencere = self.__dokuman.pencere.catNesne
            gosterim = self.__dokuman.gosterim.catNesne

            # Screenshot'ı almak için CATIA API kullanılır
            # ExportData ile PNG formatında dışa aktar
            png_dosya = os.path.join(self.FikoytKlasoru, "screenshot.png")

            # Seçilen görüntüyü PNG olarak kaydet
            gosterim.ExportData(png_dosya, "png")

            self.sinyal.emit("Basarili",
                           {"dosya": png_dosya, "tip": "PNG"})
            self.islem_devamda = False

        except Exception as e:
            self.sinyal.emit("Hata", {"mesaj": f"Resim çekilemedi: {str(e)}"})
            self.islem_devamda = False

    @pyqtSlot()
    def dokuman_olustur(self):
        """Teknik dokümantasyon JSON dosyası oluşturma"""
        if self.islem_devamda:
            QMessageBox.warning(self, "Uyarı", "Başka bir işlem devam ediyor.")
            return

        self._fikoyt_klasoru_kontrol_et()

        # Async işlem başlat
        self._dokuman_olustur_async()

    @Async()
    def _dokuman_olustur_async(self):
        """Dokümantasyon oluşturma işlemi (thread'de çalışır)"""
        try:
            self.islem_devamda = True
            self.sinyal.emit("Durum", "Dokümantasyon oluşturuluyor...")

            # Dokümantasyon veri yapısı
            dokumantasyon = {
                "olusturma_tarihi": datetime.now().isoformat(),
                "dokuman_adi": self.__dokuman.ismi,
                "dokuman_tam_yolu": self.__dokuman.tamIsmi,
                "belge_turu": self.__dokuman.turu,
                "kaydedilmis": self.__dokuman.kaydedilmismi,
                "proje_klasoru": self.ProjeKlasoru,
                "fikoyt_klasoru": self.FikoytKlasoru,
                "islemler": {
                    "wrl_kayit": os.path.exists(os.path.join(self.FikoytKlasoru, "model.wrl")),
                    "resim_cikti": os.path.exists(os.path.join(self.FikoytKlasoru, "screenshot.png"))
                }
            }

            # JSON dosyası olarak kaydet
            json_dosya = os.path.join(self.FikoytKlasoru, "dokumantasyon.json")
            with open(json_dosya, 'w', encoding='utf-8') as f:
                json.dump(dokumantasyon, f, indent=2, ensure_ascii=False)

            self.sinyal.emit("Basarili",
                           {"dosya": json_dosya, "tip": "JSON"})
            self.islem_devamda = False

        except Exception as e:
            self.sinyal.emit("Hata", {"mesaj": f"Dokümantasyon oluşturulamadı: {str(e)}"})
            self.islem_devamda = False

    @pyqtSlot()
    def ozellik_degisti(self):
        """Checkbox seçenekleri değiştiğinde çağrılır"""
        pass

    def _fikoyt_klasoru_kontrol_et(self):
        """
        .fikoyt gizli klasörünü kontrol et ve oluştur
        """
        if not os.path.exists(self.FikoytKlasoru):
            try:
                os.makedirs(self.FikoytKlasoru)
                # Windows'ta gizli klasör yap
                import ctypes
                ctypes.windll.kernel32.SetFileAttributesW(self.FikoytKlasoru, 2)
            except Exception as e:
                QMessageBox.critical(self, "Hata",
                                   f".fikoyt klasörü oluşturulamadı: {e}")
                return False
        return True

    @pyqtSlot(str, QVariant)
    def sinyalGeldi(self, olay, veri):
        """
        Async işlemlerden gelen signal'leri işle

        Args:
            olay: "Durum", "Basarili", "Hata"
            veri: Olay ile ilişkili veri
        """
        if olay == "Durum":
            self.ui.statusBar().showMessage(veri)
            if hasattr(self, 'loading_movie'):
                self.loading_movie.start()
                self.ui.labelLoading.show()

        elif olay == "Basarili":
            if hasattr(self, 'loading_movie'):
                self.loading_movie.stop()
                self.ui.labelLoading.hide()

            dosya = veri.get("dosya", "")
            tip = veri.get("tip", "")
            self.ui.statusBar().showMessage(f"✓ {tip} kaydedildi: {dosya}")
            QMessageBox.information(self, "Başarılı",
                                  f"{tip} dosyası başarıyla kaydedildi.\n\nKonum: {dosya}")

        elif olay == "Hata":
            if hasattr(self, 'loading_movie'):
                self.loading_movie.stop()
                self.ui.labelLoading.hide()

            mesaj = veri.get("mesaj", "Bilinmeyen hata")
            self.ui.statusBar().showMessage(f"✗ Hata: {mesaj}")
            QMessageBox.critical(self, "Hata", f"İşlem başarısız:\n\n{mesaj}")

    def closeEvent(self, event):
        """Pencere kapatılırken çağrılır"""
        if self.islem_devamda:
            reply = QMessageBox.question(self, "Uyarı",
                                        "İşlem devam ediyor. Çıkmak istediğinize emin misiniz?",
                                        QMessageBox.StandardButton.Yes |
                                        QMessageBox.StandardButton.No)
            if reply == QMessageBox.StandardButton.No:
                event.ignore()
                return

        event.accept()

    def __str__(self):
        return f"IFikoCikariciDialog(dokuman={self.__dokuman.ismi})"

if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setStyle("fusion")

    cizgiYumusatici = IFikoCikariciDialog(Catia=Dispatch("Catia.Application"))
    cizgiYumusatici.show()

    sys.exit(app.exec())
