"""
Shared utility functions and helpers
"""

from pathlib import Path
import os
from typing import Optional
from PySide6.QtWidgets import (
    QLineEdit,
    QSpinBox,
    QCheckBox,
    QComboBox,
    QHBoxLayout,
    QFileDialog,
    QPushButton,
)


class Utils:
    def __init__(self, app):
        self.app = app

    def get_output_extension(self, command: str) -> str:
        """Get the appropriate output extension for the current command"""
        if command.startswith("create") or command == "copy":
            return ".chd"
        elif command == "extractcd":
            return ".cue"
        elif command == "extractdvd":
            return ".iso"
        elif command == "extractld":
            return ".cue"
        elif command == "extracthd" or command == "extractraw":
            return ".img"
        elif command == "dumpmeta":
            return ".xml"
        return ""

    def update_output_path(self, app, input_path: str) -> Optional[str]:
        """Generate output path based on input path and current command"""
        if not input_path:
            return None

        command = app.command_combo.currentText()
        output_ext = self.get_output_extension(command)
        if not output_ext:
            return None

        input_dir = os.path.dirname(input_path)
        input_base = os.path.splitext(os.path.basename(input_path))[0]
        return os.path.join(input_dir, input_base + output_ext)

    def add_file_param(
        self, app, name: str, label: str, required: bool = False, is_save: bool = False
    ):
        """Add a file selection parameter to the form"""
        layout = QHBoxLayout()
        line_edit = QLineEdit()
        browse_button = QPushButton("Browse...")

        def browse():
            current_path = line_edit.text()
            start_dir = (
                os.path.dirname(current_path) if current_path else str(Path.home())
            )

            if is_save:
                file_path, _ = QFileDialog.getSaveFileName(
                    app, f"Select {label}", start_dir
                )
            else:
                file_path, _ = QFileDialog.getOpenFileName(
                    app, f"Select {label}", start_dir
                )

            if file_path:
                line_edit.setText(file_path)
                if name == "input" and not app.bulk_checkbox.isChecked():
                    self.update_output_path(app, file_path)

        browse_button.clicked.connect(browse)
        layout.addWidget(line_edit)
        layout.addWidget(browse_button)
        app.params_layout.addRow(f"{label}{'*' if required else ''}:", layout)
        app.param_widgets[name] = line_edit

    def add_directory_param(self, app, name: str, label: str, required: bool = False):
        """Add a directory selection parameter to the form"""
        layout = QHBoxLayout()
        line_edit = QLineEdit()
        browse_button = QPushButton("Browse...")

        def browse():
            current_path = line_edit.text()
            start_dir = current_path if current_path else str(Path.home())
            directory = QFileDialog.getExistingDirectory(
                app, f"Select {label}", start_dir
            )
            if directory:
                line_edit.setText(directory)

        browse_button.clicked.connect(browse)
        layout.addWidget(line_edit)
        layout.addWidget(browse_button)
        app.params_layout.addRow(f"{label}{'*' if required else ''}:", layout)
        app.param_widgets[name] = line_edit

    def add_str_param(self, app, name: str, label: str, default: str = ""):
        """Add a string parameter to the form"""
        line_edit = QLineEdit(default)
        app.params_layout.addRow(f"{label}:", line_edit)
        app.param_widgets[name] = line_edit

    def add_int_param(
        self,
        app,
        name: str,
        label: str,
        default: int = 0,
        min_val: int = 0,
        max_val: int = 9999,
    ):
        """Add an integer parameter to the form"""
        spin_box = QSpinBox()
        spin_box.setMinimum(min_val)
        spin_box.setMaximum(max_val)
        spin_box.setValue(default)
        app.params_layout.addRow(f"{label}:", spin_box)
        app.param_widgets[name] = spin_box

    def add_checkbox_param(self, app, name: str, label: str):
        """Add a checkbox parameter to the form"""
        checkbox = QCheckBox()
        app.params_layout.addRow(f"{label}:", checkbox)
        app.param_widgets[name] = checkbox
