import sys
import os
import json
import inspect
from pathlib import Path
from datetime import datetime
import base64
import tempfile

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

        # Seçim değişkenlerini başlat
        self.__aktifEksen = None
        self.__aktifBody = None

        # 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()

        # Başlangıçta UI durumlarını ayarla
        self._update_ui_state()

    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)

        # Eksen Seçimi Butonları
        if hasattr(self.ui, 'btnEksenSec'):
            self.ui.btnEksenSec.clicked.connect(self._on_btnEksenSec_clicked)
        if hasattr(self.ui, 'btnEksenSil'):
            self.ui.btnEksenSil.clicked.connect(self._on_btnEksenSil_clicked)

        # Body Seçimi Butonları
        if hasattr(self.ui, 'btnBodySec'):
            self.ui.btnBodySec.clicked.connect(self._on_btnBodySec_clicked)
        if hasattr(self.ui, 'btnBodySil'):
            self.ui.btnBodySil.clicked.connect(self._on_btnBodySil_clicked)

        # Malzeme ve Yoğunluk Senkronizasyonu
        if hasattr(self.ui, 'comboMalzeme'):
            self.ui.comboMalzeme.currentTextChanged.connect(self._on_comboMalzeme_changed)

        if hasattr(self.ui, 'spinYogunluk'):
            self.ui.spinYogunluk.valueChanged.connect(self._on_spinYogunluk_changed)

    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 _update_ui_state(self):
        """UI durumlarını güncelle (buton aktif/pasif durumları)"""
        try:
            # Eksen ve body seçim durumuna göre UI'ı güncelle
            eksen_secili = self.__aktifEksen is not None
            body_secili = self.__aktifBody is not None

            # Buton durumlarını güncelle
            if hasattr(self.ui, 'textEksen'):
                self.ui.textEksen.setText(
                    self.__aktifEksen.ismi if self.__aktifEksen else "Eksen seçilmedi"
                )
                # Border rengini seçim durumuna göre değiştir
                if eksen_secili:
                    self.ui.textEksen.setStyleSheet("background-color: #1a1f3a; border: 1px solid #00ff88; border-radius: 2px; color: #ffffff; font-size: 8pt; padding: 2px;")
                else:
                    self.ui.textEksen.setStyleSheet("background-color: #1a1f3a; border: 1px solid #666666; border-radius: 2px; color: #ffffff; font-size: 8pt; padding: 2px;")

            if hasattr(self.ui, 'textBody'):
                self.ui.textBody.setText(
                    self.__aktifBody.ismi if self.__aktifBody else "Body seçilmedi"
                )
                # Border rengini seçim durumuna göre değiştir
                if body_secili:
                    self.ui.textBody.setStyleSheet("background-color: #1a1f3a; border: 1px solid #00ff88; border-radius: 2px; color: #ffffff; font-size: 8pt; padding: 2px;")
                else:
                    self.ui.textBody.setStyleSheet("background-color: #1a1f3a; border: 1px solid #666666; border-radius: 2px; color: #ffffff; font-size: 8pt; padding: 2px;")

            self.app.processEvents()

        except Exception as e:
            print(f"[ERROR] UI durum güncelleme hatası: {e}")

    @property
    def aktifEksen(self):
        """Aktif eksen nesnesi"""
        return self.__aktifEksen

    @aktifEksen.setter
    def aktifEksen(self, value):
        """Aktif eksen nesnesini ayarla"""
        self.__aktifEksen = value
        self._update_ui_state()
        print(f"[DEBUG] Aktif eksen güncellendi: {value.ismi if value else 'None'}")

    @aktifEksen.deleter
    def aktifEksen(self):
        """Aktif eksen nesnesini temizle"""
        self.__aktifEksen = None
        self._update_ui_state()
        print("[DEBUG] Aktif eksen temizlendi")

    @property
    def aktifBody(self):
        """Aktif body nesnesi"""
        return self.__aktifBody

    @aktifBody.setter
    def aktifBody(self, value):
        """Aktif body nesnesini ayarla"""
        self.__aktifBody = value
        self._update_ui_state()
        print(f"[DEBUG] Aktif body güncellendi: {value.ismi if value else 'None'}")

    @aktifBody.deleter
    def aktifBody(self):
        """Aktif body nesnesini temizle"""
        self.__aktifBody = None
        self._update_ui_state()
        print("[DEBUG] Aktif body temizlendi")

    def _on_btnEksenSec_clicked(self):
        """Eksen seçme butonu tıklandığında çağrılır"""
        try:
            self.setVisible(False)
            secililer = self.__dokuman.secililer
            self.__fikatia.aktifEt()
            durum = secililer.sec2(["AxisSystem"], Mesaj="Lütfen Eksen Seçiniz")
            if durum == "Normal":
                # Seçilen nesneyi doğrudan IEksen olarak sakla
                catia_eksen = secililer.item2(0).nesne
                from IEksen import IEksen
                self.aktifEksen = IEksen(obj=catia_eksen.catNesne, sahip=self.__fikatia)
                self.__fikatia.durumCubugu = f"Eksen seçildi: {self.aktifEksen.ismi}"
            else:
                self.__fikatia.durumCubugu = "Seçim İptal Edildi"
                self.aktifEksen = None  # Temizle
            self.setVisible(True)
            print("[DEBUG] Eksen seçme işlemi tamamlandı")
        except Exception as e:
            print(f"[ERROR] Eksen seçme hatası: {e}")
            self.__fikatia.durumCubugu = f"Hata: {str(e)}"
            self.setVisible(True)

    def _on_btnEksenSil_clicked(self):
        """Eksi temizle butonu tıklandığında çağrılır"""
        try:
            self.aktifEksen = None
            self.__fikatia.durumCubugu = "Eksen temizlendi"
            print("[DEBUG] Eksen temizlendi")
        except Exception as e:
            print(f"[ERROR] Eksen temizleme hatası: {e}")

    def _on_btnBodySec_clicked(self):
        """Body seçme butonu tıklandığında çağrılır"""
        try:
            self.setVisible(False)
            secililer = self.__dokuman.secililer
            self.__fikatia.aktifEt()
            durum = secililer.sec2(["HybridBody", "Body"], Mesaj="Lütfen Body Seçiniz")
            if durum == "Normal":
                self.aktifBody = secililer.item2(0).nesne
                self.__fikatia.durumCubugu = f"Body seçildi: {self.aktifBody.ismi}"
            else:
                self.__fikatia.durumCubugu = "Seçim İptal Edildi"
                self.aktifBody = None  # Temizle
            self.setVisible(True)
            print("[DEBUG] Body seçme işlemi tamamlandı")
        except Exception as e:
            print(f"[ERROR] Body seçme hatası: {e}")
            self.__fikatia.durumCubugu = f"Hata: {str(e)}"
            self.setVisible(True)

    def _on_btnBodySil_clicked(self):
        """Body temizle butonu tıklandığında çağrılır"""
        try:
            self.aktifBody = None
            self.__fikatia.durumCubugu = "Body temizlendi"
            print("[DEBUG] Body temizlendi")
        except Exception as e:
            print(f"[ERROR] Body temizleme hatası: {e}")

    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.rsplit('.', 1)[0]}</span></span>
        <span style="color: #888; margin: 0 8px;">|</span>
        <span>📐<span  style="color: red; text-shadow: 0 0 8px rgba(255,107,157,0.8);"> X: {f"{float(olculer_parts[0]):.3f}" if len(olculer_parts) > 0 and olculer_parts[0] != '-' else '---'}</span>
        <span style="color: green; text-shadow: 0 0 8px rgba(0,255,136,0.8); margin-left: 5px;">Y: {f"{float(olculer_parts[1]):.3f}" if len(olculer_parts) > 1 and olculer_parts[1] != '-' else '---'}</span>
        <span style="color: teal; text-shadow: 0 0 8px rgba(0,212,255,0.8); margin-left: 5px;">Z: {f"{float(olculer_parts[2]):.3f}" if len(olculer_parts) > 2 and 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 _on_comboMalzeme_changed(self, malzeme_text):
        """
        ComboBox malzeme seçimi değiştiğinde SpinBox'ı güncelle
        """
        try:
            # Malzeme-Yoğunluk eşleştirmesi
            malzemeler = {
                "Alm 2710": 2710,
                "Zamak 6710": 6710,
                "Ç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
            }

            # Seçilen malzemenin yoğunluğunu al
            yogunluk = malzemeler.get(malzeme_text, 2710)

            # SpinBox'ı güncelle (signal döngüsünü engellemek için blockedSignals kullan)
            if hasattr(self.ui, 'spinYogunluk'):
                self.ui.spinYogunluk.blockSignals(True)
                self.ui.spinYogunluk.setValue(int(yogunluk))
                self.ui.spinYogunluk.blockSignals(False)

            print(f"[DEBUG] Malzeme seçildi: {malzeme_text}, Yoğunluk: {yogunluk}")

        except Exception as e:
            print(f"[ERROR] Malzeme değişim hatası: {e}")

    def _on_spinYogunluk_changed(self, yogunluk_degeri):
        """
        SpinBox yoğunluk değeri değiştiğinde ComboBox'ı güncelle
        """
        try:
            # Ters Malzeme-Yoğunluk eşleştirmesi
            yogunluk_to_malzeme = {
                2710: "Alm 2710",
                6710: "Zamak 6710",
                7850: "Çelik 7850",
                8000: "P.Çelik 8000",
                8960: "Bakır 8960",
                4500: "Titanyum 4500",
                1040: "ABS 1040",
                1200: "PLA 1200",
                1800: "Mg 1800",
                8902: "Ni 8902",
                8470: "Pirinç 8470",
                8700: "Bronz 8700",
                7874: "Fe 7874",
                3950: "Al2O3 3950"
            }

            # Değeri tam sayı olarak kontrol et
            yogunluk_int = int(yogunluk_degeri)

            # Eğer değer eşleşiyorsa ComboBox'ı güncelle
            if yogunluk_int in yogunluk_to_malzeme:
                malzeme_adi = yogunluk_to_malzeme[yogunluk_int]

                # ComboBox'ı güncelle (signal döngüsünü engellemek için blockedSignals kullan)
                if hasattr(self.ui, 'comboMalzeme'):
                    self.ui.comboMalzeme.blockSignals(True)
                    # İlgili öğeyi bul ve seç
                    for i in range(self.ui.comboMalzeme.count()):
                        if self.ui.comboMalzeme.itemText(i) == malzeme_adi:
                            self.ui.comboMalzeme.setCurrentIndex(i)
                            break
                    self.ui.comboMalzeme.blockSignals(False)

                print(f"[DEBUG] Yoğunluk değişti: {yogunluk_int}, Malzeme: {malzeme_adi}")
            else:
                # Özel bir değer girilmişse, ComboBox'ı "Özel" olarak işaretle
                print(f"[DEBUG] Özel yoğunluk değeri: {yogunluk_int}")

        except Exception as e:
            print(f"[ERROR] Yoğunluk değişim hatası: {e}")

    def _malzeme_yogunluk_al(self):
        """
        SpinBox'tan mevcut yoğunluk değerini al (ComboBox'tan veya kullanıcı girişinden)

        Returns:
            float: Mevcut yoğunluk değeri (kg/m³)
        """
        try:
            # Öncelikle SpinBox değerini al
            if hasattr(self.ui, 'spinYogunluk'):
                yogunluk = self.ui.spinYogunluk.value()
            else:
                # Fallback: ComboBox'tan al (eski mantık)
                malzemeler = {
                    "Alm 2710": 2710,
                    "Zamak 6710": 6710,
                    "Ç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
                }
                secilen_text = self.ui.comboMalzeme.currentText()
                yogunluk = malzemeler.get(secilen_text, 2710)

            print(f"[DEBUG] Kullanılan yoğunluk: {yogunluk} kg/m³")
            return yogunluk

        except Exception as e:
            print(f"[ERROR] Yoğunluk alma hatası: {e}")
            return 2710  # Varsayılan değer

    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 seçimi (checkbox'a göre)
            print("[DEBUG] Klasör seçimi yapılıyor...")
            self._update_progress(0.5, 5, "Klasör seçimi")

            # Checkbox kontrolü
            if hasattr(self.ui, 'checkFikoyt') and self.ui.checkFikoyt.isChecked():
                # .fikoyt klasörünü kullan
                kullanilacak_klasor = self.FikoytKlasoru
                if not self._fikoyt_klasoru_kontrol_et():
                    return
                print(f"[DEBUG] .fikoyt klasörü kullanılıyor: {kullanilacak_klasor}")
            else:
                # Windows temp klasörünü kullan
                kullanilacak_klasor = os.path.join(tempfile.gettempdir(), "FikoYT")
                if not os.path.exists(kullanilacak_klasor):
                    os.makedirs(kullanilacak_klasor)
                print(f"[DEBUG] Temp klasörü kullanılıyor: {kullanilacak_klasor}")

            # 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(kullanilacak_klasor, "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(kullanilacak_klasor, "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 - SADECE SEÇİLEN BODY İÇİN
                if not agirlik and hasattr(doc_com, 'Part'):
                    try:
                        part_com = doc_com.Part
                        hacim = 0.0

                        # SPAWorkbench ile SADECE SEÇİLEN BODY'nin hacmini al
                        try:
                            spa_workbench = doc_com.GetWorkbench("SPAWorkbench")

                            # Seçili Body varsa onu kullan, yoksa ilk Body'yi kullan
                            if self.__aktifBody:
                                # Kullanıcının seçtiği özel Body'yi kullan
                                body_com = self.__aktifBody.catNesne
                                print(f"[DEBUG] Seçili Body kullanılıyor: {self.__aktifBody.ismi}")

                                try:
                                    body_ref = part_com.CreateReferenceFromObject(body_com)
                                    measurable = spa_workbench.GetMeasurable(body_ref)
                                    hacim = measurable.Volume
                                    print(f"[DEBUG] Seçili Body Volume = {hacim} m³")
                                except Exception as e:
                                    print(f"[DEBUG] Seçili Body hacim hesaplama hatası: {e}")
                                    hacim = 0.0

                            elif hasattr(part_com, 'Bodies') and part_com.Bodies.Count > 0:
                                # Body seçilmemişse TÜM Body'lerin hacmini topla
                                bodies = part_com.Bodies
                                hacim = 0.0
                                print(f"[DEBUG] Body seçilmemiş, tüm {bodies.Count} Body'nin hacmi toplanıyor")

                                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} ({body.Name}) Volume = {body_vol} m³")
                                    except Exception as e:
                                        print(f"[DEBUG] Body {i} hacim hesaplama hatası: {e}")

                                print(f"[DEBUG] Tüm Body'lerin toplam hacmi = {hacim} m³")

                            if hacim > 0:
                                print(f"[DEBUG] Kullanılan hacim = {hacim} m³")

                        except Exception as e:
                            print(f"[DEBUG] SPAWorkbench hatası: {e}")
                            # Fallback: Part'ın toplam hacmini kullan (son çare)
                            if hasattr(part_com, 'Volume'):
                                hacim = part_com.Volume
                                print(f"[DEBUG] Fallback - part_com.Volume = {hacim}")

                        # Ağırlık hesapla
                        if hacim and secilen_yogunluk:
                            agirlik = hacim * secilen_yogunluk
                            body_adi = self.__aktifBody.ismi if self.__aktifBody else "İlk Body"
                            print(f"[DEBUG] {body_adi} için 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']:.3f} Y:{olculer['y']:.3f} Z:{olculer['z']:.3f}"
                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,
                "kullanilan_klasor": kullanilacak_klasor,
                "fikoyt_modu": self.ui.checkFikoyt.isChecked() if hasattr(self.ui, 'checkFikoyt') else True,
                "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(kullanilacak_klasor, "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ığı)
        Seçilen eksen varsa onu kullan, yoksa mevcut sistemin eksenlerini kullan
        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)
            # Eğer body seçilmişse seçilen body'yi, yoksa ilk body'yi kullan
            if self.__aktifBody:
                body = self.__aktifBody.catNesne
                print(f"[DEBUG] Seçilen body kullanılıyor: {self.__aktifBody.ismi}")
            else:
                body = bodies.Item(1)
                print(f"[DEBUG] İlk body kullanılıyor: {body.Name}")

            # 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
            # Seçilen eksen varsa onu kullan, yoksa mevcut sistemin eksenlerini/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)
            try:
                measurable.GetCOG(cog)
                print(f"[DEBUG] COG: {cog}")
            except Exception as e:
                print(f"[WARNING] COG hesaplanamadı ({e}), orijin noktası kullanılıyor")
                cog = (0.0, 0.0, 0.0)  # Orijin noktası kullan

            # Eğer seçilen eksen varsa onu kullan
            if self.__aktifEksen:
                print(f"[DEBUG] Seçilen eksen kullanılıyor: {self.__aktifEksen.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]

                # Seçilen eksenin X, Y, Z yönlerini al (artık IEksen nesnesi olduğu için doğrudan kullan)
                try:
                    x_dir = self.__aktifEksen.x
                    y_dir = self.__aktifEksen.y
                    z_dir = self.__aktifEksen.z
                    print(f"[DEBUG] Eksen vektörleri alındı: X={x_dir.X}, Y={x_dir.Y}, Z={x_dir.Z}")
                except Exception as e:
                    print(f"[ERROR] Eksen vektörleri alınırken hata: {e}")
                    # Hata durumunda global axes kullan
                    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
                    print(f"[DEBUG] Hata nedeniyle global axes kullanılıyor")
                    # continue kaldırıldı - bu bir döngüde değil

                # 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ı (seçilen eksen kullanıldı)")
            else:
                # Eksen seçilmemişse, mevcut sistemin eksenlerini kullan (eski mantık)
                print(f"[DEBUG] Eksen seçilmemiş, mevcut sistem eksenleri kullanılıyor")

                # 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
                    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:.3f}mm, Y={y_olcu:.3f}mm, Z={z_olcu:.3f}mm")

            # Hangi eksen kullanıldığını göster
            eksen_info = f" (Seçilen Eksen)" if self.__aktifEksen else f" (Sistem Ekseni)"
            olculer_text = f"📐 X:{x_olcu:.3f} Y:{y_olcu:.3f} Z:{z_olcu:.3f}{eksen_info}"
            self.ui.labelOlculer.setText(olculer_text)

            # Ölçüleri return et (JSON'a eklemek için)
            return {
                "x": round(x_olcu, 3),
                "y": round(y_olcu, 3),
                "z": round(z_olcu, 3),
                "kullanilan_eksen": self.__aktifEksen.ismi if self.__aktifEksen else "sistem_ekseni"
            }

        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())
