import sys
import os
import json
import inspect
from pathlib import Path
from datetime import datetime
import base64

from PyQt6.QtWidgets import (QApplication, QMainWindow, QMessageBox,
                             QFileDialog, QProgressBar, QLabel)
from PyQt6.QtCore import Qt, pyqtSignal, pyqtSlot, QUrl, QVariant, QTimer, QIODevice, QByteArray, QBuffer
from PyQt6.QtGui import QMovie, QPixmap, QClipboard, QImage
from PyQt6.uic import loadUi
from win32com.client import CDispatch, Dispatch

# 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 IGosterim3d import IGosterim3d


class IFikoCikariciDialog(QMainWindow):
    """
    FikoYT Çıkarıcı Dialog - Minimal & Futuristik

    CATIA dökümanlarından aşağıdaki işlemleri gerçekleştirir:
    - WRL (VRML) formatında 3D dosya dışa aktarma
    - Görüntüyü ekranda gösterme
    - Teknik dokümantasyon oluşturma
    - Ağırlık hesaplama
    """

    def __init__(self, parent=None, flags=None, Catia=None):
        """
        Dialog constructor

        Args:
            parent: Parent widget (None - standalone)
            flags: Qt window flags (Qt.WindowType)
            Catia: CATIA COM Application nesnesi
        """
        # CATIA COM nesnesi kontrolü
        if Catia is None:
            raise ValueError("CATIA parametresi boş olamaz!")

        # PyQt6 initialization (super çağrısından önce)
        if not QApplication.instance():
            self.app = QApplication([sys.argv])
        else:
            self.app = QApplication.instance()

        # Default flags ayarla
        if flags is None:
            flags = Qt.WindowType.Window

        # Parent widget olmamalı (standalone dialog)
        super(IFikoCikariciDialog, self).__init__(None)

        # CATIA COM nesnesi sarmalama
        self.__fikatia = IFikatia(obj=Catia)
        self.__dokuman = self.__fikatia.aktifDokuman

        # 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")
        self.setGeometry(100, 100, 300, 320)

        # Signal-slot bağlantıları
        self._connect_signals()

    def _show_loading(self, show=True, message=""):
        """Loading animasyonu - Artık kullanılmıyor, legacy compatibility için bırakıldı"""
        # Eski loading animasyonu artık kullanılmıyor
        # Tüm loading mesajları artık _update_progress ve statusbar üzerinden yapılıyor
        pass

    def _update_progress(self, current_step, total_steps=5, message=""):
        """Progress bar ve aktif işlem göstergesini güncelle"""
        try:
            # Progress bar güncelle
            if hasattr(self.ui, 'progressIslem'):
                progress_value = int((current_step / total_steps) * 100)
                self.ui.progressIslem.setValue(progress_value)
                self.app.processEvents()

            # Aktif işlem göstergesini güncelle
            if hasattr(self.ui, 'labelAktifIslem'):
                if message:
                    self.ui.labelAktifIslem.setText(f"🔄 {message}")
                    self.ui.labelAktifIslem.setStyleSheet("color: #00d4ff; font-size: 7pt; font-weight: bold; padding: 2px;")
                elif current_step >= total_steps:
                    # Tüm işlemler tamamlandığında
                    self.ui.labelAktifIslem.setText("✅ İşlemler Tamamlandı")
                    self.ui.labelAktifIslem.setStyleSheet("color: #00ff88; font-size: 7pt; font-weight: bold; padding: 2px;")
                else:
                    # Normal durumda
                    self.ui.labelAktifIslem.setText("✅ Hazır")
                    self.ui.labelAktifIslem.setStyleSheet("color: #00d4ff; font-size: 7pt; font-weight: bold; padding: 2px;")

            self.app.processEvents()

        except Exception as e:
            print(f"Progress güncelleme hatası: {e}")

    def _animate_button_state(self, is_processing=True):
        """Buton state'ine göre animasyon ve ikon değişimi ekle"""
        try:
            if hasattr(self.ui, 'btnIslemYap'):
                if is_processing:
                    # İşlem sırasında butonu disable yap ve pause ikonu
                    self.ui.btnIslemYap.setEnabled(False)
                    self.ui.btnIslemYap.setText("⏸️")
                    self.ui.btnIslemYap.setStyleSheet("""
                        QPushButton {
                            background-color: #666666;
                            color: #cccccc;
                            border: 2px solid #555555;
                            border-radius: 6px;
                            font-size: 9pt;
                            font-weight: bold;
                            padding: 2px;
                            outline: none;
                            box-shadow: none;
                        }
                    """)
                else:
                    # İşlem tamamlandı - butonu normal yap ve play ikonu
                    self.ui.btnIslemYap.setEnabled(True)
                    self.ui.btnIslemYap.setText("▶️")
                    self.ui.btnIslemYap.setStyleSheet("""
                        QPushButton {
                            background-color: #00d4ff;
                            color: #0a0e27;
                            border: 2px solid #00d4ff;
                            border-radius: 6px;
                            font-size: 9pt;
                            font-weight: bold;
                            padding: 2px;
                            outline: none;
                        }
                        QPushButton:hover {
                            background-color: #00ffff;
                            border-color: #00ffff;
                        }
                        QPushButton:pressed {
                            background-color: #0099cc;
                            border-color: #0099cc;
                        }
                        QPushButton:!disabled:focus {
                            border-color: #ffffff;
                        }
                    """)

                self.app.processEvents()

        except Exception as e:
            print(f"Buton animasyonu hatası: {e}")

    def _animate_data_update(self, widget, new_value, prefix="", suffix=""):
        """Veri güncellemesi için animasyonlu transition ekle"""
        try:
            if hasattr(widget, 'setText'):
                # Mevcut değeri al
                current_text = widget.text()

                # Yeni animasyonlu değeri ayarla
                if new_value is not None:
                    animated_value = f"{prefix}{new_value}{suffix}"
                else:
                    animated_value = "-"

                widget.setText(animated_value)

                # Flash efekti
                original_style = widget.styleSheet()
                widget.setStyleSheet(f"color: #00ff88; font-weight: bold; {original_style}")

                # Flash efektini geri al (geciktirilmiş)
                QTimer.singleShot(500, lambda: widget.setStyleSheet(original_style))

                self.app.processEvents()

        except Exception as e:
            print(f"Veri animasyonu hatası: {e}")

    def _animate_image_transition(self, image_path, operation="loading"):
        """Resim alanı için transition animasyonu ekle"""
        try:
            if hasattr(self.ui, 'labelResim'):
                if operation == "loading":
                    # Yükleme sırasında gradient efekti
                    self.ui.labelResim.setStyleSheet("""
                        background-color: #1a1f3a;
                        border: 1px solid #00d4ff;
                        border-radius: 3px;
                        color: #555555;
                        font-size: 8pt;
                        background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
                            stop:0 #1a1f3a, stop:0.5 #0a0e27, stop:1 #1a1f3a);
                    """)
                    self.ui.labelResim.setText("🖼️ Yükleniyor...")
                elif operation == "success":
                    # Başarılı yükleme - resim kalacak sadece border rengi değişecek
                    self.ui.labelResim.setStyleSheet("""
                        background-color: #1a1f3a;
                        border: 1px solid #00ff88;
                        border-radius: 3px;
                        color: transparent;
                        font-size: 8pt;
                    """)
                    self.ui.labelResim.setText("")  # Metni kaldır
                elif operation == "error":
                    # Hata durumunda
                    self.ui.labelResim.setStyleSheet("""
                        background-color: #1a1f3a;
                        border: 1px solid #ff6b9d;
                        border-radius: 3px;
                        color: #ff6b9d;
                        font-size: 8pt;
                    """)
                    self.ui.labelResim.setText("❌ Hata")

                self.app.processEvents()

        except Exception as e:
            print(f"Resim animasyonu hatası: {e}")

    def _connect_signals(self):
        """PyQt6 signal-slot bağlantılarını kur"""
        # Ana İşlem Butonu
        if hasattr(self.ui, 'btnIslemYap'):
            self.ui.btnIslemYap.clicked.connect(self.islem_yap)

        # Kopyala Butonu
        if hasattr(self.ui, 'btnKopyala'):
            self.ui.btnKopyala.clicked.connect(self._sonuclari_kopyala)

    def _sonuclari_kopyala(self):
        """Sonuçları ve resmi renkli, kaliteli formatında clipboard'a kopyala"""
        try:
            # Gerekli bilgileri al
            dosya_ismi = self.ui.labelDosyaIsmi.text().replace("📁 ", "")
            agirlik_text = self.ui.labelAgirlik.text().replace("⚖️ ", "")
            olculer_text = self.ui.labelOlculer.text().replace("📐 ", "")

            # Eğer boş değerler varsa varsayılan değerler ata
            if dosya_ismi == "-" or dosya_ismi == "":
                dosya_ismi = "Bilinmeyen Dosya"
            if agirlik_text == "-" or agirlik_text == "":
                agirlik_text = "Hesaplanamadı"
            if olculer_text == "X:- Y:- Z:-" or olculer_text == "":
                olculer_text = "X:- Y:- Z:-"

            # Hem metin hem de resmi içeren kopyalama
            self._copy_with_image(dosya_ismi, olculer_text, agirlik_text)

            # Kullanıcıya bildirim
            self.ui.statusBar().showMessage("✅ Sonuçlar ve resim kopyalandı!")
            QTimer.singleShot(3000, lambda: self.ui.statusBar().clearMessage())

            print(f"[DEBUG] Clipboard içeriği ve resim kopyalandı")

        except Exception as e:
            print(f"[ERROR] Kopyalama hatası: {e}")
            self.ui.statusBar().showMessage(f"❌ Kopyalama hatası: {str(e)}")
            QTimer.singleShot(3000, lambda: self.ui.statusBar().clearMessage())

    def _copy_with_image(self, dosya_ismi, olculer_text, agirlik_text):
        """Resim ve metni birlikte yüksek kaliteli şekilde clipboard'a kopyala"""
        try:
            clipboard = QApplication.clipboard()

            # Önce metin clipboard'a yaz (fallback olarak)
            text_content = f"""{dosya_ismi}
{olculer_text} | Ağırlık: {agirlik_text}"""
            clipboard.setText(text_content, QClipboard.Mode.Clipboard)

            # Resmi clipboard'a kopyalamaya çalış
            if hasattr(self.ui, 'labelResim') and self.ui.labelResim.pixmap():
                pixmap = self.ui.labelResim.pixmap()
                if not pixmap.isNull():
                    # Resmi yüksek kalitede işlemek için orijinal resmi al
                    image = pixmap.toImage()

                    # Eğer resim çok küçükse, orijinal boyutunu koru
                    if image.width() < 800:
                        # Daha yüksek çözünürlük için resmi ölçekle
                        image = image.scaled(1200, 800, Qt.AspectRatioMode.KeepAspectRatio,
                                           Qt.TransformationMode.SmoothTransformation)

                    # Resmi yüksek kaliteli JPEG olarak kaydet
                    byte_array = QByteArray()
                    buffer = QBuffer(byte_array)
                    buffer.open(QIODevice.OpenModeFlag.WriteOnly)

                    # Yüksek kaliteli JPEG (90 kalite)
                    image.save(buffer, "JPG", 90)
                    buffer.close()

                    base64_data = byte_array.toBase64().data().decode('utf-8')

                    # HTML formatında içerik oluştur (renkli ve profesyonel)
                    html_content = self._create_html_with_image(
                        base64_data, dosya_ismi, olculer_text, agirlik_text
                    )

                    # HTML clipboard formatunu ayarla
                    mime_data = clipboard.mimeData()
                    if mime_data:
                        mime_data.setHtml(html_content)

                        # Yüksek kaliteli resmi ekle (JPEG olarak)
                        mime_data.setData("image/jpeg", byte_array.data() if isinstance(byte_array, QByteArray) else byte_array)

                        # Başlık ve açıklama bilgileri
                        mime_data.setData("text/plain", text_content)

                        # Resim başlıkları
                        mime_data.setText(f"FikoYT Dokümantasyon - {dosya_ismi}")

                        clipboard.setMimeData(mime_data)

        except Exception as e:
            print(f"[ERROR] Resim kopyalama hatası: {e}")
            # Eğer resim kopyalanamazsa sadece metinle devam et

    def _create_html_with_image(self, base64_data, dosya_ismi, olculer_text, agirlik_text):
        """HTML formatında içerik oluştur (renkli ve profesyonel)"""
        try:
            # Boyutları ve renkleri formatla (kalın ve koyu renkli)
            try:
                olculer_parts = olculer_text.replace("X:", "").replace("Y:", "").replace("Z:", "").split()
                if len(olculer_parts) >= 3:
                    x_val, y_val, z_val = olculer_parts[0], olculer_parts[1], olculer_parts[2]
                    # Farklı koyu renkler
                    olculer_colored = f'<span style="color: #8B4513; font-weight: bold;">X:{x_val}</span> <span style="color: #2F4F4F; font-weight: bold;">Y:{y_val}</span> <span style="color: #800080; font-weight: bold;">Z:{z_val}</span>'
                else:
                    olculer_colored = f'<span style="color: #2c3e50; font-weight: bold;">{olculer_text}</span>'
            except:
                olculer_colored = f'<span style="color: #2c3e50; font-weight: bold;">{olculer_text}</span>'
            try:
                if "Hesaplanamadı" in agirlik_text:
                    agirlik_colored = f'<span style="color: #2c3e50; font-weight: bold;">⚖️ Ağırlık: {agirlik_text.replace("⚖️ ", "")}</span>'
                else:
                    agirlik_colored = f'<span style="color: #2c3e50; font-weight: bold;">⚖️ Ağırlık: {agirlik_text.replace("⚖️ ", "")}</span>'
            except:
                agirlik_colored = f'<span style="color: #2c3e50; font-weight: bold;">⚖️ Ağırlık: {agirlik_text.replace("⚖️ ", "")}</span>'

            # HTML formatı oluştur (Minimal inline style - Word için)
            html_content = f"""<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
</head>
<body>
<div style="font-family: 'Segoe UI', Arial, sans-serif; padding: 15px; background: linear-gradient(135deg, #0a0e27 0%, #1a1f3a 100%); border: 2px solid #00d4ff; box-shadow: 0 0 20px rgba(0,212,255,0.3);">
    <img src="data:image/jpeg;base64,{base64_data}" alt="{dosya_ismi}" style="width: 100%; max-width: 800px; display: block; margin: 0 auto 15px; border: 2px solid #00d4ff; box-shadow: 0 0 15px rgba(0,212,255,0.5);"/>
    <p style="margin: 0; padding: 8px; font-size: 9pt; font-weight: 600; text-align: center; background: rgba(0,0,0,0.4); border-radius: 4px;">
        <span>📁 <span  style="color: teal; text-shadow: 0 0 8px rgba(0,212,255,0.8);">{dosya_ismi}</span></span>
        <span style="color: #888; margin: 0 8px;">|</span>
        <span>📐<span  style="color: #ff6b9d; text-shadow: 0 0 8px rgba(255,107,157,0.8);"> X: {olculer_parts[0] if len(olculer_parts) > 0 else '-'}</span>
        <span style="color: green; text-shadow: 0 0 8px rgba(0,255,136,0.8); margin-left: 5px;">Y: {olculer_parts[1] if len(olculer_parts) > 1 else '-'}</span>
        <span style="color: #00d4ff; text-shadow: 0 0 8px rgba(0,212,255,0.8); margin-left: 5px;">Z: {olculer_parts[2] if len(olculer_parts) > 2 else '-'}</span></span>
        <span style="color: #888; margin: 0 8px;">|</span>
        <span>⚖️ <span  style="color: blue; text-shadow: 0 0 8px rgba(255,0,255,0.8);">{agirlik_text.replace('⚖️ Ağırlık: ', '').replace('⚖️ ', '') if agirlik_text else '-'}</span></span>
    </p>
</div>
</body>
</html>"""

            return html_content

        except Exception as e:
            print(f"[ERROR] HTML oluşturma hatası: {e}")
            # Eğer HTML oluşturulamazsa basit metinle devam et
            return f"""{dosya_ismi}
{olculer_text} | Ağırlık: {agirlik_text}"""

    def _malzeme_yogunluk_al(self):
        """
        ComboBox'tan seçilen malzemenin yoğunluk değerini al

        Returns:
            float: Seçilen malzemenin yoğunluğu (kg/m³)
        """
        # Malzeme-Yoğunluk eşleştirmesi
        malzemeler = {
            "Alm 2710": 2710,
            "Çelik 7850": 7850,
            "P.Çelik 8000": 8000,
            "Bakır 8960": 8960,
            "Titanyum 4500": 4500,
            "ABS 1040": 1040,
            "PLA 1200": 1200,
            "Mg 1800": 1800,
            "Ni 8902": 8902,
            "Pirinç 8470": 8470,
            "Bronz 8700": 8700,
            "Fe 7874": 7874,
            "Al2O3 3950": 3950
        }

        # ComboBox'tan seçilen öğeyi al
        secilen_text = self.ui.comboMalzeme.currentText()
        yogunluk = malzemeler.get(secilen_text, 2710)  # Varsayılan: 2710

        print(f"[DEBUG] Seçilen malzeme: {secilen_text}")
        print(f"[DEBUG] Yoğunluk değeri: {yogunluk} kg/m³")

        return yogunluk

    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()
    def islem_yap(self):
        """
        Tüm işlemleri (WRL, Resim, Dokümantasyon) yapan ana method
        """
        try:
            # Başlangıç animasyonları
            self._animate_button_state(is_processing=True)
            self._show_loading(show=True, message="İşlem başlatılıyor...")
            self._update_progress(0, 5, "Başlatılıyor")
            self.app.processEvents()

            # 1. Klasör kontrol et
            print("[DEBUG] Klasör kontrolü yapılıyor...")
            self._update_progress(0.5, 5, "Klasör kontrolü")
            if not self._fikoyt_klasoru_kontrol_et():
                return

            # 2. WRL kaydet
            print("[DEBUG] WRL kaydediliyor...")
            self.ui.statusBar().showMessage("⏳ WRL kaydediliyor...")
            self._show_loading(show=True, message="WRL kaydediliyor...")
            self._update_progress(1, 5, "WRL Kaydet")
            self.app.processEvents()

            doc_com = self.__dokuman.catNesne
            wrl_dosya = os.path.join(self.FikoytKlasoru, "model.wrl")

            if os.path.exists(wrl_dosya):
                try:
                    os.remove(wrl_dosya)
                except Exception:
                    pass

            doc_com.ExportData(wrl_dosya, "wrl")

            if not os.path.exists(wrl_dosya):
                raise RuntimeError(f"WRL dosyası oluşturulamadı")

            print(f"[DEBUG] ✓ WRL kaydedildi: {wrl_dosya}")
            self._update_progress(2, 5, "Resim Çek")
            self.app.processEvents()

            # 3. Resim çek
            print("[DEBUG] Resim çekiliyor...")
            self.ui.statusBar().showMessage("⏳ Resim çekiliyor...")
            self._show_loading(show=True, message="Resim çekiliyor...")
            self._animate_image_transition("", "loading")
            self.app.processEvents()

            gosterim = self.__dokuman.gosterim

            if gosterim is None:
                raise ValueError("Gosterim nesnesi alınamadı!")

            if hasattr(gosterim, 'catNesne'):
                gosterim_com = gosterim.catNesne
            else:
                gosterim_com = gosterim

            jpeg_dosya = os.path.join(self.FikoytKlasoru, "screenshot.jpg")

            pencere = self.__dokuman.pencere

            # Ürün ağacını gizle
            try:
                if pencere and hasattr(pencere, 'catNesne'):
                    pencere.catNesne.SpecificationPanelVisible = False
            except Exception as e:
                print(f"[DEBUG] Ürün ağacı gizleme hatası: {e}")

            try:
                if not isinstance(gosterim, IGosterim3d):
                    gosterim = IGosterim3d(obj=gosterim_com, sahip=self.__dokuman)
                    gosterim.anaProgram = self.__fikatia

                gosterim.resimDosyaya(
                    jpeg_dosya,
                    Format=5,           # JPEG
                    ArkaPlan=[1, 1, 1], # Beyaz
                    Agac=False
                )
            finally:
                # Ürün ağacını geri göster
                try:
                    if pencere and hasattr(pencere, 'catNesne'):
                        pencere.catNesne.SpecificationPanelVisible = True
                except Exception:
                    pass

            if not os.path.exists(jpeg_dosya):
                raise RuntimeError(f"JPEG dosyası oluşturulamadı")

            print(f"[DEBUG] ✓ JPEG kaydedildi: {jpeg_dosya}")

            # 4. Resmi formda göster
            print("[DEBUG] Resim gösteriliyor...")
            self._show_loading(show=False)  # Loading animasyonu kapat
            self._animate_image_transition(jpeg_dosya, "success")
            self._resim_goster(jpeg_dosya)
            self._update_progress(3, 5, "Ağırlık Hesapla")
            self.app.processEvents()

            # 5. Ağırlık hesapla
            print("[DEBUG] Ağırlık hesaplanıyor...")
            self.ui.statusBar().showMessage("⏳ Ağırlık hesaplanıyor...")
            self._show_loading(show=True, message="Ağırlık hesaplanıyor...")
            self.app.processEvents()

            secilen_yogunluk = self._malzeme_yogunluk_al()
            agirlik = None
            hacim = None

            try:
                # 1. Direkt GetTotalMass() dene
                if hasattr(doc_com, 'GetTotalMass'):
                    try:
                        agirlik = doc_com.GetTotalMass()
                        print(f"[DEBUG] GetTotalMass() = {agirlik}")
                    except Exception as e:
                        print(f"[DEBUG] GetTotalMass() hatası: {e}")

                # 2. Part nesnesi üzerinden ağırlık hesapla
                if not agirlik and hasattr(doc_com, 'Part'):
                    try:
                        part_com = doc_com.Part

                        # SPAWorkbench ile Body hacimlerini topla
                        try:
                            spa_workbench = doc_com.GetWorkbench("SPAWorkbench")
                            hacim = 0.0

                            if hasattr(part_com, 'Bodies'):
                                bodies = part_com.Bodies
                                for i in range(1, bodies.Count + 1):
                                    try:
                                        body = bodies.Item(i)
                                        body_ref = part_com.CreateReferenceFromObject(body)
                                        measurable = spa_workbench.GetMeasurable(body_ref)
                                        body_vol = measurable.Volume
                                        hacim += body_vol
                                        print(f"[DEBUG] Body {i} Volume = {body_vol} m³")
                                    except Exception as e:
                                        print(f"[DEBUG] Body {i} hatası: {e}")

                            if hacim > 0:
                                print(f"[DEBUG] Toplam Volume = {hacim} m³")

                        except Exception as e:
                            print(f"[DEBUG] SPAWorkbench hatası: {e}")
                            if hasattr(part_com, 'Volume'):
                                hacim = part_com.Volume
                                print(f"[DEBUG] part_com.Volume = {hacim}")

                        # Ağırlık hesapla
                        if hacim and secilen_yogunluk:
                            agirlik = hacim * secilen_yogunluk
                            print(f"[DEBUG] Hesaplanan ağırlık = {agirlik} kg")

                    except Exception as e:
                        print(f"[DEBUG] Part işleme hatası: {e}")

            except Exception as e:
                print(f"[ERROR] Ağırlık hesaplama hatası: {e}")
                import traceback
                traceback.print_exc()

            # 6. Ağırlık göster
            self._show_loading(show=False)  # Loading animasyonu kapat
            self._animate_data_update(self.ui.labelAgirlik, agirlik, "⚖️ ", " kg")
            self._update_progress(4, 5, "Ölçü Hesapla")
            self.app.processEvents()

            # 6.5. Ölçüleri hesapla ve göster
            print("[DEBUG] Ölçüler hesaplanıyor...")
            self._show_loading(show=True, message="Ölçüler hesaplanıyor...")
            olculer = self._olculer_hesapla_ve_goster()
            if olculer:
                olculer_text = f"📐 X:{olculer['x']:.1f} Y:{olculer['y']:.1f} Z:{olculer['z']:.1f}"
                self._animate_data_update(self.ui.labelOlculer, olculer_text, prefix="", suffix="")
            self._update_progress(5, 5, "Doküman Oluştur")
            self.app.processEvents()

            # 7. Dosya adı göster
            self._show_loading(show=False)  # Loading animasyonu kapat
            secilen_text = self.ui.comboMalzeme.currentText()
            malzeme_adi = secilen_text.split(" - ")[0] if " - " in secilen_text else secilen_text

            dokuman_adi = self.__dokuman.ismi
            self._animate_data_update(self.ui.labelDosyaIsmi, dokuman_adi, "📁 ", "")

            # 8. Dokümantasyon JSON oluştur
            print("[DEBUG] JSON oluşturuluyor...")
            self.ui.statusBar().showMessage("⏳ Dokümantasyon kaydediliyor...")
            self._show_loading(show=True, message="JSON oluşturuluyor...")
            self.app.processEvents()

            dokumantasyon = {
                "olusturma_tarihi": datetime.now().isoformat(),
                "dokuman_adi": dokuman_adi,
                "dokuman_tam_yolu": self.__dokuman.tamIsmi,
                "belge_turu": self.__dokuman.turu,
                "kaydedilmis": self.__dokuman.kaydedilmismi,
                "proje_klasoru": self.ProjeKlasoru,
                "fikoyt_klasoru": self.FikoytKlasoru,
                "agirlik_kg": agirlik,
                "agirlik_hesaplama": {
                    "malzeme": malzeme_adi,
                    "yogunluk_kg_m3": secilen_yogunluk,
                    "hacim_m3": hacim,
                    "birim": "kg",
                    "hesaplama_metodu": "Volume × Density" if hacim and secilen_yogunluk else "GetTotalMass()"
                },
                "olculer_mm": olculer if olculer else {"x": None, "y": None, "z": None},
                "islemler": {
                    "wrl_kayit": os.path.exists(wrl_dosya),
                    "resim_cikti": os.path.exists(jpeg_dosya),
                    "dokumantasyon": True
                }
            }

            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)

            print(f"[DEBUG] ✓ JSON kaydedildi: {json_dosya}")

            # 9. Başarılı mesaj ve bitiş animasyonları
            self._show_loading(show=False)  # Tüm loading animasyonlarını kapat
            self._animate_button_state(is_processing=False)  # Butonu normale çevir

            # Kopyala butonunu aktif et
            if hasattr(self.ui, 'btnKopyala'):
                self.ui.btnKopyala.setEnabled(True)
                self.ui.btnKopyala.setStyleSheet("""
                    QPushButton {
                        background-color: #00ff88;
                        color: #0a0e27;
                        border: 2px solid #00ff88;
                        border-radius: 6px;
                        font-size: 9pt;
                        font-weight: bold;
                        padding: 2px;
                        outline: none;
                    }
                    QPushButton:hover {
                        background-color: #00ffaa;
                        border-color: #00ffaa;
                    }
                    QPushButton:pressed {
                        background-color: #00cc77;
                        border-color: #00cc77;
                    }
                    QPushButton:!disabled:focus {
                        border-color: #ffffff;
                    }
                """)

            self.ui.statusBar().showMessage("✅ Tüm işlemler tamamlandı!")
            self._animate_image_transition("", "success")
            self._update_progress(5, 5)  # İşlemler tamamlandı mesajı göster
            self.app.processEvents()

        except Exception as e:
            print(f"[ERROR] {str(e)}")
            import traceback
            traceback.print_exc()

            # Hata durumunda animasyonlar
            self._show_loading(show=False)
            self._animate_button_state(is_processing=False)  # Butonu normale çevir
            self._animate_image_transition("", "error")
            self.ui.statusBar().showMessage(f"❌ Hata: {str(e)}")
            QMessageBox.critical(self, "Hata", f"İşlem başarısız:\n{str(e)}")
            self.app.processEvents()

    def _resim_goster(self, jpeg_dosya):
        """
        JPEG resimini formda göster

        Args:
            jpeg_dosya: JPEG dosyasının tam yolu
        """
        try:
            if not os.path.exists(jpeg_dosya):
                print(f"[ERROR] Resim dosyası bulunamadı: {jpeg_dosya}")
                return

            pixmap = QPixmap(jpeg_dosya)
            if pixmap.isNull():
                print(f"[ERROR] Resim yüklenemedi")
                return

            # Resimi label'ın içine sığdır
            label_size = self.ui.labelResim.size()
            scaled_pixmap = pixmap.scaledToWidth(label_size.width() - 10, Qt.TransformationMode.SmoothTransformation)

            self.ui.labelResim.setPixmap(scaled_pixmap)
            print(f"[DEBUG] ✓ Resim gösterildi")

        except Exception as e:
            print(f"[ERROR] Resim gösterme hatası: {e}")

    def _agirlik_goster(self, agirlik):
        """
        Ağırlık değerini formda göster

        Args:
            agirlik: Ağırlık değeri (kg)
        """
        if agirlik:
            agirlik_text = f"⚖️ {agirlik:.2f} kg"
            self.ui.labelAgirlik.setText(agirlik_text)
            print(f"[DEBUG] Ağırlık gösterildi: {agirlik_text}")
        else:
            self.ui.labelAgirlik.setText("⚖️ Ağırlık: -")

    def _olculer_hesapla_ve_goster(self):
        """
        Part'ın gerçek X, Y, Z ölçülerini hesapla (UDF ile - kutukSinirOlculeri mantığı)
        Returns: dict with 'x', 'y', 'z' keys (mm), or None on error
        """
        try:
            from IYardimciSiniflar import SifirKonum, XYZ
            import os

            doc_com = self.__dokuman.catNesne

            if not hasattr(doc_com, 'Part'):
                self.ui.labelOlculer.setText("📐 X:- Y:- Z:-")
                return None

            part_com_obj = doc_com.Part
            bodies = part_com_obj.Bodies

            if bodies.Count == 0:
                self.ui.labelOlculer.setText("📐 X:- Y:- Z:-")
                return None

            # UDF script dosyasının yolunu al
            current_dir = os.path.dirname(__file__)
            idialoglar = os.path.dirname(current_dir)
            fikatia_root = os.path.dirname(idialoglar)
            script_dosya = os.path.join(fikatia_root, "Prg", "FikoDosya", "FikoMfg0.FikoDll")

            print(f"[DEBUG] UDF dosya: {script_dosya}, var: {os.path.exists(script_dosya)}")

            # HybridBody oluştur veya al
            try:
                fiko_body = part_com_obj.hybridBodies.item("FikoMantasyon")
                part_com_obj.InWorkObject = fiko_body
            except:
                fiko_body = part_com_obj.hybridBodies.add()
                fiko_body.name = "FikoMantasyon"

            # İlk body'yi al (COM object olarak)
            body = bodies.Item(1)

            # InstanceFactory ile UDF çağır (kutukSinirOlculeri gibi)
            factory = part_com_obj.GetCustomerFactory("InstanceFactory")
            factory.BeginInstanceFactory("Fiko0", script_dosya)
            factory.BeginInstantiate()

            # Body'nin COM nesnesini gönder (kutukSinirOlculeri gibi)
            factory.PutInputData("ParcaBody", body)

            instance = factory.Instantiate()
            factory.EndInstantiate()
            factory.EndInstanceFactory()

            # UDF'e merkez ve axes gönder (global axes kullan)
            # SPAWorkbench ile COG al
            spa_workbench = doc_com.GetWorkbench("SPAWorkbench")
            body_ref = part_com_obj.CreateReferenceFromObject(body)
            measurable = spa_workbench.GetMeasurable(body_ref)

            # COG al
            cog = (0.0, 0.0, 0.0)
            measurable.GetCOG(cog)
            print(f"[DEBUG] COG: {cog}")

            # Part'ın eksenlerini al (IPart wrapper'ı kullan)
            from IPart import IPart
            part_wrapper = IPart(part_com_obj)
            eksenler = part_wrapper.eksenler

            # Son ekseni bul (son eklenen eksen)
            if eksenler.sayisi > 0:
                son_eksen = eksenler.item(eksenler.sayisi-1)
                print(f"[DEBUG] Son eksen bulundu: {son_eksen.ismi}")

                # Origin (Merkez - COG)
                instance.GetParameter("O.X").value = cog[0]
                instance.GetParameter("O.Y").value = cog[1]
                instance.GetParameter("O.Z").value = cog[2]

                # Son eksenin X, Y, Z yönlerini al
                # son_eksen.x, son_eksen.y, son_eksen.z vektörleri
                x_dir = son_eksen.x
                y_dir = son_eksen.y
                z_dir = son_eksen.z

                # X axis
                instance.GetParameter("X.X").value = x_dir.X
                instance.GetParameter("X.Y").value = x_dir.Y
                instance.GetParameter("X.Z").value = x_dir.Z

                # Y axis
                instance.GetParameter("Y.X").value = y_dir.X
                instance.GetParameter("Y.Y").value = y_dir.Y
                instance.GetParameter("Y.Z").value = y_dir.Z

                # Z axis
                instance.GetParameter("Z.X").value = z_dir.X
                instance.GetParameter("Z.Y").value = z_dir.Y
                instance.GetParameter("Z.Z").value = z_dir.Z

                print(f"[DEBUG] UDF parametreleri ayarlandı (son eksen kullanıldı)")
            else:
                # Eksen yoksa global axes kullan
                print(f"[DEBUG] Eksen yok, global axes kullanılıyor")
                instance.GetParameter("O.X").value = cog[0]
                instance.GetParameter("O.Y").value = cog[1]
                instance.GetParameter("O.Z").value = cog[2]

                instance.GetParameter("X.X").value = 1.0
                instance.GetParameter("X.Y").value = 0.0
                instance.GetParameter("X.Z").value = 0.0

                instance.GetParameter("Y.X").value = 0.0
                instance.GetParameter("Y.Y").value = 1.0
                instance.GetParameter("Y.Z").value = 0.0

                instance.GetParameter("Z.X").value = 0.0
                instance.GetParameter("Z.Y").value = 0.0
                instance.GetParameter("Z.Z").value = 1.0

            # Part'ı güncelle (UDF parametreleri hesaplansın)
            print(f"[DEBUG] Part güncelleniyor...")
            part_com_obj.Update()

            # Parametreleri oku
            xmin = instance.GetParameter("Xmin").value
            xmax = instance.GetParameter("Xmax").value
            ymin = instance.GetParameter("Ymin").value
            ymax = instance.GetParameter("Ymax").value
            zmin = instance.GetParameter("Zmin").value
            zmax = instance.GetParameter("Zmax").value

            print(f"[DEBUG] UDF Params: Xmin={xmin}, Xmax={xmax}, Ymin={ymin}, Ymax={ymax}, Zmin={zmin}, Zmax={zmax}")

            # SifirKonum ile ölçüleri hesapla
            sifrkonum = SifirKonum(xmin, xmax, ymin, ymax, zmin, zmax)

            x_olcu = sifrkonum.XOlcusu
            y_olcu = sifrkonum.YOlcusu
            z_olcu = sifrkonum.ZOlcusu

            print(f"[DEBUG] Ölçüler: X={x_olcu:.1f}mm, Y={y_olcu:.1f}mm, Z={z_olcu:.1f}mm")

            # UI'ye yazdir
            olculer_text = f"📐 X:{x_olcu:.1f} Y:{y_olcu:.1f} Z:{z_olcu:.1f}"
            self.ui.labelOlculer.setText(olculer_text)

            # Ölçüleri return et (JSON'a eklemek için)
            return {
                "x": round(x_olcu, 1),
                "y": round(y_olcu, 1),
                "z": round(z_olcu, 1)
            }

        except Exception as e:
            print(f"[ERROR] Ölçü hesaplama hatası: {e}")
            import traceback
            traceback.print_exc()
            self.ui.labelOlculer.setText("📐 X:- Y:- Z:-")
            return None

    def closeEvent(self, event):
        """Pencere kapatılırken çağrılır"""
        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())
