package ffmpeg

import data.Message
import ffprobe.FfprobeStreams
import interfaces.CommandRunner
import interfaces.Streams
import java.awt.*
import java.io.File
import java.util.ResourceBundle
import java.util.logging.Logger
import javax.swing.*

class AudioAdjustmentSelector(
    private val audioStreams: List<Map<String, String>>,
    private val file: File,
    private val messages: ResourceBundle = Message().messages,
    private val stream: Streams = FfprobeStreams(),
    private val commandRunner: CommandRunner
) {
    private val logger = Logger.getLogger(this.javaClass.name)

    fun showAdjustmentDialog() {
        val selectedStreams = mutableListOf<Map<String, String>>()

        // Painel para os checkboxes dos fluxos de áudio
        val panel = JPanel().apply {
            layout = BoxLayout(this, BoxLayout.Y_AXIS)
        }

        val checkboxes = audioStreams.map { stream ->
            val checkbox = createCheckbox(stream)
            panel.add(checkbox)
            checkbox
        }

        // Input para o valor de ajuste (em segundos)
        val adjustmentField = JTextField(10)

        // Botões de rádio para selecionar entre adiantar ou atrasar
        val advanceRadio = JRadioButton(messages["advance"] ?: "Adiantar")
        val delayRadio = JRadioButton(messages["delay"] ?: "Atrasar")
        delayRadio.isSelected = true  // Define "Atrasar" como padrão

        val radioGroup = ButtonGroup().apply {
            add(advanceRadio)
            add(delayRadio)
        }

        val radioPanel = JPanel().apply {
            layout = FlowLayout(FlowLayout.LEFT)
            add(advanceRadio)
            add(delayRadio)
        }

        // Painel principal que combina todos os componentes
        val mainPanel = JPanel()
        mainPanel.layout = BoxLayout(mainPanel, BoxLayout.Y_AXIS)
        mainPanel.add(panel)
        mainPanel.add(Box.createVerticalStrut(10))
        mainPanel.add(JLabel(messages["enter_adjustment_value"] ?: "Insira o valor de ajuste (em segundos):"))
        mainPanel.add(adjustmentField)
        mainPanel.add(Box.createVerticalStrut(10))
        mainPanel.add(radioPanel)

        // Configuração do diálogo
        val dialog = JDialog(null as JFrame?, true).apply {
            title = messages["adjust_audio_streams"] ?: "Ajustar Fluxos de Áudio"
            layout = BorderLayout()
            isResizable = false
            setLocationRelativeTo(null)
            add(mainPanel, BorderLayout.CENTER)
            pack()
            defaultCloseOperation = WindowConstants.DISPOSE_ON_CLOSE
        }

        // Botão para confirmar a ação
        val confirmButton = JButton(messages["confirm"] ?: "Confirmar").apply {
            addActionListener {
                // Coleta os fluxos selecionados
                checkboxes.forEachIndexed { index, checkbox ->
                    if (checkbox.isSelected) {
                        selectedStreams.add(audioStreams[index])
                    }
                }

                // Valida o valor de ajuste inserido
                val adjustmentValue = adjustmentField.text.toDoubleOrNull()
                if (adjustmentValue == null || adjustmentValue <= 0) {
                    JOptionPane.showMessageDialog(
                        dialog,
                        messages["invalid_adjustment_value"] ?: "Por favor, insira um valor de ajuste válido.",
                        messages["error"] ?: "Erro",
                        JOptionPane.ERROR_MESSAGE
                    )
                    return@addActionListener
                }

                // Determina se é para adiantar ou atrasar
                val isAdvance = advanceRadio.isSelected

                // Fecha o diálogo
                dialog.dispose()

                // Chama a função para executar o comando
                executeAdjustment(selectedStreams, adjustmentValue, isAdvance)
            }
        }

        // Botão para cancelar a ação
        val cancelButton = JButton(messages["cancel"] ?: "Cancelar").apply {
            addActionListener {
                dialog.dispose()
            }
        }

        val buttonPanel = JPanel(FlowLayout(FlowLayout.RIGHT)).apply {
            add(cancelButton)
            add(confirmButton)
        }

        dialog.add(buttonPanel, BorderLayout.SOUTH)
        dialog.pack()
        dialog.setLocationRelativeTo(null)
        dialog.isVisible = true
    }

    private fun createCheckbox(stream: Map<String, String>): JCheckBox {
        val language = stream["language"] ?: stream["tags.language"] ?: "Unknown"
        val codec = stream["codec_name"] ?: "Unknown"
        val sampleRate = stream["sample_rate"] ?: "Unknown"
        val channels = stream["channels"] ?: "Unknown"
        val bitrate = stream["bit_rate"] ?: stream["tags.BPS"] ?: stream["tags.BPS-eng"] ?: "Unknown"

        val checkboxText =
            "${messages["language"] ?: "Idioma"}: $language | " +
                    "${messages["codec"] ?: "Codec"}: $codec | " +
                    "${messages["sample_rate"] ?: "Taxa de Amostragem"}: $sampleRate Hz | " +
                    "${messages["channels"] ?: "Canais"}: $channels | " +
                    "${messages["bitrate"] ?: "Taxa de Bits"}: $bitrate"
        return JCheckBox("Stream ${stream["index"]} - $checkboxText")
    }

    private fun executeAdjustment(selectedStreams: List<Map<String, String>>, adjustmentValue: Double, isAdvance: Boolean) {
        val streamIndexes = selectedStreams.map { it["index"] ?: "" }
        if (streamIndexes.isEmpty()) {
            logger.warning("Nenhum fluxo de áudio selecionado para ajuste.")
            return
        }

        // Monta o comando FFmpeg para ajustar os fluxos selecionados
        val inputFile = file.absolutePath
        val outputFile = file.parent + "/output_adjusted.mp4"

        val itsoffsetValue = if (isAdvance) -adjustmentValue else adjustmentValue

        // Construção do comando usando múltiplas entradas
        val command = mutableListOf<String>()
        command.add("ffmpeg")
        command.add("-i")
        command.add(inputFile)
        command.add("-itsoffset")
        command.add(itsoffsetValue.toString())
        command.add("-i")
        command.add(inputFile)
        command.add("-map")
        command.add("0:v")

        // Mapear fluxos de áudio não ajustados
        audioStreams.forEach { stream ->
            val index = stream["index"] ?: ""
            if (!streamIndexes.contains(index)) {
                command.add("-map")
                command.add("0:a:$index")
            }
        }

        // Mapear fluxos de áudio ajustados da segunda entrada
        streamIndexes.forEach { index ->
            command.add("-map")
            command.add("1:a:$index")
        }

        // Configurações de codificação
        command.add("-c:v")
        command.add("copy")

        // Copiar fluxos de áudio não ajustados
        audioStreams.forEach { stream ->
            val index = stream["index"] ?: ""
            if (!streamIndexes.contains(index)) {
                command.add("-c:a:$index")
                command.add("copy")
            }
        }

        // Reencodar fluxos de áudio ajustados
        streamIndexes.forEach { index ->
            command.add("-c:a:$index")
            command.add("aac")
            command.add("-b:a:$index")
            command.add("256k")  // Define a taxa de bits conforme necessário
        }

        command.add(outputFile)

        // Chama a função runCommand()
        commandRunner.runCommand(
            command.toTypedArray(),
            stream.getDuration(file)
        )
    }
}

refatore essa classe para que a parte gráfica possa ser passada para outra classe que recebe os parâmetros (pela função da classe) e retorna o necessário para a execução na classe AudioAdjustmentSelector

modifique 
package ui.interfaces

import java.io.File

interface UserNotifier {
    fun showError(message: String)
    fun showWarning(message: String)
    fun showInfo(message: String)
    fun again(): Boolean
    fun option(): Int
    fun selectAudioStreams(
        audioStreams1: List<Map<String, String>>,
        audioStreams2: List<Map<String, String>>,
        file1: File,
        file2: File,
    ): List<Pair<File, Map<String, String>>>

    fun smallFile(): Int
    fun noFreeSpace()
    fun codecSelection(availableCodecs: Array<String>): String
}