"""
File Manager - Handle input and output files
"""

from pathlib import Path
from PyQt5.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QTreeWidget, QTreeWidgetItem,
    QPushButton, QLabel, QFileDialog, QMessageBox, QGroupBox,
    QSplitter, QTextEdit, QProgressBar, QCheckBox
)
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QSettings
import json


class FileManager(QWidget):
    """Widget for managing input and output files."""
    
    files_changed = pyqtSignal()
    
    def __init__(self):
        super().__init__()
        # Persistent settings for remembering last-open directory
        try:
            self.settings = QSettings("DazedTranslations", "DazedMTLTool")
        except Exception:
            self.settings = None
        self.input_files = []
        self.output_directory = Path("translated")
        self.init_ui()
        self.refresh_files()
        
    def init_ui(self):
        """Initialize the user interface."""
        layout = QVBoxLayout()
        
        # Create splitter for input and output sections
        splitter = QSplitter(Qt.Horizontal)
        
        # Input files section
        input_group = self.create_input_section()
        splitter.addWidget(input_group)
        
        # Output files section
        output_group = self.create_output_section()
        splitter.addWidget(output_group)
        
        splitter.setSizes([400, 400])
        layout.addWidget(splitter)
        
        # Progress section
        progress_group = self.create_progress_section()
        layout.addWidget(progress_group)
        
        self.setLayout(layout)
        
    def create_input_section(self):
        """Create the input files section."""
        group = QGroupBox("Input Files")
        layout = QVBoxLayout()
        
        # Buttons
        button_layout = QHBoxLayout()
        
        self.add_files_button = QPushButton("Add Files")
        self.add_files_button.clicked.connect(self.add_input_files)
        
        self.add_folder_button = QPushButton("Add Folder")
        self.add_folder_button.clicked.connect(self.add_input_folder)
        
        self.remove_files_button = QPushButton("Remove Selected")
        self.remove_files_button.clicked.connect(self.remove_selected_files)
        
        self.clear_files_button = QPushButton("Clear All")
        self.clear_files_button.clicked.connect(self.clear_input_files)
        
        button_layout.addWidget(self.add_files_button)
        button_layout.addWidget(self.add_folder_button)
        button_layout.addWidget(self.remove_files_button)
        button_layout.addWidget(self.clear_files_button)
        
        layout.addLayout(button_layout)
        
        # File tree
        self.input_tree = QTreeWidget()
        self.input_tree.setHeaderLabels(["File", "Size", "Type"])
        self.input_tree.itemSelectionChanged.connect(self.on_input_selection_changed)
        layout.addWidget(self.input_tree)
        
        # File info
        self.input_info = QTextEdit()
        self.input_info.setMaximumHeight(100)
        self.input_info.setReadOnly(True)
        layout.addWidget(self.input_info)
        
        group.setLayout(layout)
        return group
        
    def create_output_section(self):
        """Create the output files section."""
        group = QGroupBox("Output Files")
        layout = QVBoxLayout()
        
        # Output directory selection
        dir_layout = QHBoxLayout()
        
        self.output_dir_label = QLabel(str(self.output_directory))
        self.output_dir_label.setStyleSheet("border: 1px solid #555; padding: 5px;")
        
        self.browse_output_button = QPushButton("Browse")
        self.browse_output_button.clicked.connect(self.browse_output_directory)
        
        dir_layout.addWidget(QLabel("Output Directory:"))
        dir_layout.addWidget(self.output_dir_label)
        dir_layout.addWidget(self.browse_output_button)
        
        layout.addLayout(dir_layout)
        
        # Output file tree
        self.output_tree = QTreeWidget()
        self.output_tree.setHeaderLabels(["File", "Size", "Modified"])
        self.output_tree.itemSelectionChanged.connect(self.on_output_selection_changed)
        layout.addWidget(self.output_tree)
        
        # Output file preview
        self.output_preview = QTextEdit()
        self.output_preview.setMaximumHeight(100)
        self.output_preview.setReadOnly(True)
        layout.addWidget(self.output_preview)
        
        # Output buttons
        output_button_layout = QHBoxLayout()
        
        self.open_output_button = QPushButton("Open in Editor")
        self.open_output_button.clicked.connect(self.open_output_file)
        
        self.delete_output_button = QPushButton("Delete Selected")
        self.delete_output_button.clicked.connect(self.delete_output_file)
        
        output_button_layout.addWidget(self.open_output_button)
        output_button_layout.addWidget(self.delete_output_button)
        output_button_layout.addStretch()
        
        layout.addLayout(output_button_layout)
        
        group.setLayout(layout)
        return group
        
    def create_progress_section(self):
        """Create the progress monitoring section."""
        group = QGroupBox("Translation Progress")
        layout = QVBoxLayout()
        
        # Progress bar
        self.progress_bar = QProgressBar()
        self.progress_bar.setVisible(False)
        layout.addWidget(self.progress_bar)
        
        # Status and options
        status_layout = QHBoxLayout()
        
        self.status_label = QLabel("Ready")
        self.backup_cb = QCheckBox("Create Backups")
        self.backup_cb.setChecked(True)
        
        status_layout.addWidget(self.status_label)
        status_layout.addStretch()
        status_layout.addWidget(self.backup_cb)
        
        layout.addLayout(status_layout)
        
        group.setLayout(layout)
        return group
        
    def add_input_files(self):
        """Add input files via dialog."""
        # Try to restore last used directory
        start_dir = ""
        try:
            if self.settings:
                start_dir = self.settings.value("last_open_dir", "") or ""
        except Exception:
            start_dir = ""

        files, _ = QFileDialog.getOpenFileNames(
            self,
            "Select Input Files",
            start_dir,
            "JSON Files (*.json);;All Files (*)"
        )
        
        for file_path in files:
            if file_path not in self.input_files:
                self.input_files.append(file_path)

        # Persist directory used
        try:
            if self.settings and len(files) > 0:
                import os
                self.settings.setValue("last_open_dir", os.path.dirname(files[0]))
        except Exception:
            pass
                
        self.refresh_input_files()
        
    def add_input_folder(self):
        """Add all files from a folder."""
        folder = QFileDialog.getExistingDirectory(self, "Select Input Folder")
        
        if folder:
            folder_path = Path(folder)
            for file_path in folder_path.rglob("*.json"):
                file_str = str(file_path)
                if file_str not in self.input_files:
                    self.input_files.append(file_str)
                    
        self.refresh_input_files()
        
    def remove_selected_files(self):
        """Remove selected input files."""
        selected_items = self.input_tree.selectedItems()
        for item in selected_items:
            file_path = item.text(0)
            if file_path in self.input_files:
                self.input_files.remove(file_path)
                
        self.refresh_input_files()
        
    def clear_input_files(self):
        """Clear all input files."""
        self.input_files.clear()
        self.refresh_input_files()
        
    def refresh_input_files(self):
        """Refresh the input files display."""
        self.input_tree.clear()
        
        for file_path in self.input_files:
            path_obj = Path(file_path)
            if path_obj.exists():
                size = path_obj.stat().st_size
                file_type = path_obj.suffix
                
                item = QTreeWidgetItem([
                    path_obj.name,
                    f"{size:,} bytes",
                    file_type
                ])
                item.setToolTip(0, str(path_obj))
                self.input_tree.addTopLevelItem(item)
            else:
                # File doesn't exist - show in red
                item = QTreeWidgetItem([
                    f"{path_obj.name} (Missing)",
                    "0 bytes",
                    "N/A"
                ])
                item.setBackground(0, Qt.red)
                self.input_tree.addTopLevelItem(item)
                
        # Update info
        self.update_input_info()
        
    def refresh_output_files(self):
        """Refresh the output files display."""
        self.output_tree.clear()
        
        if self.output_directory.exists():
            for file_path in self.output_directory.iterdir():
                if file_path.is_file():
                    size = file_path.stat().st_size
                    modified = file_path.stat().st_mtime
                    
                    import datetime
                    modified_str = datetime.datetime.fromtimestamp(modified).strftime("%Y-%m-%d %H:%M")
                    
                    item = QTreeWidgetItem([
                        file_path.name,
                        f"{size:,} bytes",
                        modified_str
                    ])
                    item.setToolTip(0, str(file_path))
                    self.output_tree.addTopLevelItem(item)
                    
    def browse_output_directory(self):
        """Browse for output directory."""
        directory = QFileDialog.getExistingDirectory(
            self, "Select Output Directory", str(self.output_directory)
        )
        
        if directory:
            self.output_directory = Path(directory)
            self.output_dir_label.setText(str(self.output_directory))
            self.refresh_output_files()
            
    def refresh_files(self):
        """Refresh both input and output file displays."""
        self.refresh_input_files()
        self.refresh_output_files()
        
    def on_input_selection_changed(self):
        """Handle input file selection change."""
        selected_items = self.input_tree.selectedItems()
        if selected_items:
            item = selected_items[0]
            file_name = item.text(0)
            
            # Find the full path
            full_path = None
            for file_path in self.input_files:
                if Path(file_path).name == file_name:
                    full_path = file_path
                    break
                    
            if full_path and Path(full_path).exists():
                try:
                    with open(full_path, 'r', encoding='utf-8') as f:
                        content = f.read()
                        
                    # Show preview of file structure
                    if full_path.endswith('.json'):
                        data = json.loads(content)
                        if isinstance(data, dict):
                            keys = list(data.keys())[:10]  # Show first 10 keys
                            preview = f"JSON Object with {len(data)} keys:\n"
                            preview += "\n".join(keys)
                            if len(data) > 10:
                                preview += f"\n... and {len(data) - 10} more"
                        elif isinstance(data, list):
                            preview = f"JSON Array with {len(data)} items"
                        else:
                            preview = f"JSON: {type(data).__name__}"
                    else:
                        preview = content[:500] + "..." if len(content) > 500 else content
                        
                    self.input_info.setPlainText(preview)
                except Exception as e:
                    self.input_info.setPlainText(f"Error reading file: {str(e)}")
                    
    def on_output_selection_changed(self):
        """Handle output file selection change."""
        selected_items = self.output_tree.selectedItems()
        if selected_items:
            item = selected_items[0]
            file_name = item.text(0)
            file_path = self.output_directory / file_name
            
            if file_path.exists():
                try:
                    with open(file_path, 'r', encoding='utf-8') as f:
                        content = f.read()
                        
                    preview = content[:500] + "..." if len(content) > 500 else content
                    self.output_preview.setPlainText(preview)
                except Exception as e:
                    self.output_preview.setPlainText(f"Error reading file: {str(e)}")
                    
    def open_output_file(self):
        """Open selected output file in external editor."""
        selected_items = self.output_tree.selectedItems()
        if selected_items:
            item = selected_items[0]
            file_name = item.text(0)
            file_path = self.output_directory / file_name
            
            if file_path.exists():
                import subprocess
                try:
                    subprocess.run(['notepad.exe', str(file_path)], check=True)
                except subprocess.CalledProcessError:
                    QMessageBox.warning(self, "Warning", "Could not open file in external editor")
                    
    def delete_output_file(self):
        """Delete selected output file."""
        selected_items = self.output_tree.selectedItems()
        if selected_items:
            item = selected_items[0]
            file_name = item.text(0)
            file_path = self.output_directory / file_name
            
            reply = QMessageBox.question(
                self,
                "Confirm Deletion",
                f"Are you sure you want to delete '{file_name}'?",
                QMessageBox.Yes | QMessageBox.No,
                QMessageBox.No
            )
            
            if reply == QMessageBox.Yes and file_path.exists():
                try:
                    file_path.unlink()
                    self.refresh_output_files()
                except Exception as e:
                    QMessageBox.critical(self, "Error", f"Failed to delete file:\n{str(e)}")
                    
    def update_input_info(self):
        """Update the input files information."""
        total_files = len(self.input_files)
        total_size = 0
        
        for file_path in self.input_files:
            path_obj = Path(file_path)
            if path_obj.exists():
                total_size += path_obj.stat().st_size
                
        info = f"Total Files: {total_files}\nTotal Size: {total_size:,} bytes"
        
        # Count by file type
        extensions = {}
        for file_path in self.input_files:
            ext = Path(file_path).suffix
            extensions[ext] = extensions.get(ext, 0) + 1
            
        if extensions:
            info += "\n\nFile Types:"
            for ext, count in sorted(extensions.items()):
                info += f"\n{ext or 'No extension'}: {count}"
                
        self.input_info.setPlainText(info)
        
    def get_input_files(self):
        """Get list of input files."""
        return self.input_files.copy()
        
    def get_output_directory(self):
        """Get output directory path."""
        return self.output_directory
