import os
import shutil
from PyQt5.QtWidgets import QFileDialog, QMessageBox, QApplication
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QImage, QPixmap
import cv2

class FileService:
    def __init__(self, main_window, upload_dir):
        self.main_window = main_window
        self.upload_dir = upload_dir
        self.destination = None
        self._camera_was_active = False  # Track if camera was active before upload
        
    def upload_file(self):
        """處理檔案上傳流程"""
        try:
            # 1. 先完全停止相機（如果正在運行）
            if hasattr(self.main_window, 'media_controller') and self.main_window.media_controller.video_thread is not None:
                print("上傳前停止相機")
                try:
                    # 儲存狀態以指示相機正在運行
                    self._camera_was_active = True
                    # 顯示上傳中提示
                    if hasattr(self.main_window, 'canvas_label'):
                        self.main_window.canvas_label.setText("準備上傳檔案...")
                        self.main_window.canvas_label.setAlignment(Qt.AlignCenter)
                        self.main_window.canvas_label.setStyleSheet("color: white; font-size: 24px;")
                        # 確保 UI 更新
                        QApplication.processEvents()
                    
                    # 只暫停推論，不完全停止相機
                    if not self.main_window.media_controller._inference_paused:
                        self.main_window.media_controller.toggle_inference_pause()
                    
                    # 斷開信號連接但不停止相機執行緒
                    if hasattr(self.main_window.media_controller, '_signal_was_connected') and self.main_window.media_controller._signal_was_connected:
                        try:
                            self.main_window.media_controller.video_thread.change_pixmap_signal.disconnect()
                            self.main_window.media_controller._signal_was_connected = False
                            print("已暫時斷開相機信號連接")
                        except Exception as e:
                            print(f"斷開信號連接時發生錯誤: {e}")
                except Exception as e:
                    print(f"準備上傳時發生錯誤: {e}")
                    import traceback
                    print(traceback.format_exc())
                    # 即使發生錯誤，也繼續嘗試上傳
            else:
                self._camera_was_active = False
                
            print("呼叫 QFileDialog.getOpenFileName")
            options = QFileDialog.Options()
            file_path, _ = QFileDialog.getOpenFileName(
                self.main_window, 
                "上傳檔案", 
                "", 
                "所有檔案 (*)", 
                options=options
            )
            print("檔案路徑取得:", file_path)
            
            if file_path:
                print("檢查上傳目錄是否存在")
                if not os.path.exists(self.upload_dir):
                    os.makedirs(self.upload_dir)
                    print(f"建立上傳目錄: {self.upload_dir}")
                    
                print("檢查原始檔案是否存在:", file_path)
                if not os.path.exists(file_path):
                    self.show_message(QMessageBox.Critical, "錯誤", "選擇的檔案不存在")
                    return None
                    
                file_name = os.path.basename(file_path)
                self.destination = os.path.join(self.upload_dir, file_name)
                print("目標路徑:", self.destination)
                
                # 檢查目標路徑是否可寫入
                try:
                    print("測試檔案寫入權限")
                    with open(self.destination, 'wb') as test_file:
                        pass
                    os.remove(self.destination)
                    print("測試檔案建立和刪除成功")
                except PermissionError:
                    self.show_message(QMessageBox.Critical, "錯誤", "無法寫入目標目錄")
                    return None
                    
                print("開始檔案複製")
                try:
                    shutil.copy2(file_path, self.destination)
                    print("檔案複製成功")
                    
                    # 更新主視窗目的地
                    self.main_window.destination = self.destination
                    print(f"更新主視窗目的地: {self.main_window.destination}")
                    
                    # 處理上傳的影像
                    if self.main_window.inference_controller.current_tool_config:
                        print("使用推論控制器處理上傳的影像")
                        # 先在畫布上顯示影像
                        try:
                            # 載入和顯示影像
                            image = cv2.imread(self.destination)
                            if image is not None:
                                # 轉換為 RGB 顯示
                                image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
                                height, width, channel = image_rgb.shape
                                bytes_per_line = channel * width
                                qt_image = QImage(image_rgb.data, width, height, bytes_per_line, QImage.Format_RGB888)
                                
                                # 將影像縮放以適應畫布
                                canvas_size = self.main_window.canvas_label.size()
                                scaled_image = qt_image.scaled(
                                    int(canvas_size.width() * 0.95),
                                    int(canvas_size.height() * 0.95),
                                    Qt.KeepAspectRatio,
                                    Qt.SmoothTransformation
                                )
                                self.main_window.canvas_label.setPixmap(QPixmap.fromImage(scaled_image))
                                print("影像顯示在畫布上")
                        except Exception as e:
                            print(f"顯示影像時發生錯誤: {e}")
                            import traceback
                            print(traceback.format_exc())
                        
                        # 然後使用推論處理它
                        self.main_window.inference_controller.process_uploaded_image(self.destination)
                    
                    return self.destination
                except Exception as e:
                    import traceback
                    print("檔案複製過程中發生錯誤:\n", traceback.format_exc())
                    self.show_message(QMessageBox.Critical, "錯誤", f"上傳錯誤: {str(e)}")
                    return None
                
            return None
            
        except Exception as e:
            import traceback
            print("上傳過程中發生錯誤:\n", traceback.format_exc())
            self.show_message(QMessageBox.Critical, "錯誤", f"上傳錯誤: {str(e)}")
            return None
        finally:
            # 如果相機之前是活動的，嘗試恢復相機連接
            if self._camera_was_active and hasattr(self.main_window, 'media_controller'):
                try:
                    # 延遲一點時間以確保處理完成
                    QApplication.processEvents()
                    
                    # 如果相機執行緒仍然存在但信號已斷開，重新連接信號
                    if (self.main_window.media_controller.video_thread is not None and 
                        not self.main_window.media_controller._signal_was_connected):
                        try:
                            self.main_window.media_controller.video_thread.change_pixmap_signal.connect(
                                self.main_window.media_controller.update_image
                            )
                            self.main_window.media_controller._signal_was_connected = True
                            print("已重新連接相機信號")
                        except Exception as e:
                            print(f"重新連接相機信號時發生錯誤: {e}")
                    
                    # 如果推論被暫停，恢復推論
                    if self.main_window.media_controller._inference_paused:
                        self.main_window.media_controller.toggle_inference_pause()
                        print("已恢復推論")
                        
                except Exception as e:
                    print(f"恢復相機時發生錯誤: {e}")
                    import traceback
                    print(traceback.format_exc())
                    
    def show_message(self, icon, title, message):
        """顯示自訂樣式的訊息盒"""
        msgBox = QMessageBox(self.main_window)
        msgBox.setIcon(icon)
        msgBox.setWindowTitle(title)
        msgBox.setText(message)
        msgBox.setStyleSheet("""
            QLabel { color: white; }
            QPushButton { color: white; }
            QMessageBox { background-color: #2b2b2b; }
        """)
        msgBox.exec_()