from textual.screen import ModalScreen
from textual.widgets import Label, Select, TabbedContent, TabPane, Switch, Input, Rule, Static
from textual.containers import Vertical, HorizontalGroup, VerticalGroup, VerticalScroll
from textual.binding import Binding

from textual_slider import Slider

import sounddevice as sd


class SettingsScreen(ModalScreen):
    border_title = "Settings"
    DEFAULT_CSS = """
    SettingsScreen {
        align: center middle;

        #window {
            border: panel $primary;
            background: $background;
            width: 65%;
            height: 65%;
            padding: 1;
        }

        TabPane {
            padding: 1;
        }

        Rule {
            color: $boost;
        }

        .thingy {
            margin-top: 2;
            text-style: bold;
        }
        
        #block-size-text {
            width: 5;
            height: 3;
            content-align: left middle;
        }

        .setting {
            padding: 0 2;
            content-align: center middle;
            margin-bottom: 1;

            .setting-name {
                text-style: bold;
            }

            .setting-desc {
                text-style: dim;
                width: 100%;
                min-width: 30;
            }

            VerticalGroup {
                width: 50%;
                min-width: 20;
                margin-right: 1;
            }

            Select, Input, Slider {
                max-width: 35;
            }
        }
    }
    """

    BINDINGS = [
        Binding("escape", "close", "Close")
    ]

    def __init__(self):
        super().__init__()

    def action_close(self):
        self.dismiss()

    def on_select_changed(self, event: Select.Changed):
        if event.select.id == "colour-theme":
            self.app.theme = event.value
            self.app.config_handler.set("appearance", "colour_theme", event.value)
        elif event.select.id == "output-device":
            self.app.config_handler.set("audio", "output_device", event.value)
        elif event.select.id == "input-device":
            self.app.config_handler.set("audio", "input_device", event.value)
            
    def on_slider_changed(self, event: Slider.Changed):
        if event.slider.id == "block-size":
            self.query_one("#block-size-text").update(str(event.value))
            self.app.config_handler.set("audio", "block_size", str(event.value))
            
    def compose(self):
        with Vertical(id="window") as window:
            window.border_title = "Settings"
            with TabbedContent():
                with TabPane("Appearance"):
                    with VerticalScroll():
                        with HorizontalGroup(classes="setting"):
                            with VerticalGroup():
                                yield Label("Colour Theme", classes="setting-name")
                                yield Label("Colour theme used for the entire Berry app. You can get more themes with plugins!", classes="setting-desc")

                            yield Select.from_values(
                                (theme_name for theme_name in self.app._registered_themes.keys() if theme_name != "textual-ansi"),
                                allow_blank=False,
                                id="colour-theme",
                                value=self.app.theme
                            )
                with TabPane("Audio"):
                    with VerticalScroll():
                        with HorizontalGroup(classes="setting"):
                            with VerticalGroup():
                                yield Label("Output Device", classes="setting-name")
                                yield Label("The device that audio will be outputted to. If a device is not shown, then [i]sounddevice[/i] thinks it has 0 output channels.", classes="setting-desc")
                                
                            devices: list[str] = [device["name"] for device in sd.query_devices() if device["max_output_channels"] > 0]
                            output_device_name = self.app.config_handler.get("audio", "output_device")
                            
                            yield Select.from_values(
                                devices,
                                allow_blank=False,
                                id="output-device",
                                value=output_device_name if output_device_name in devices else devices[0]
                            )
                        with HorizontalGroup(classes="setting"):
                            with VerticalGroup():
                                yield Label("Input Device", classes="setting-name")
                                yield Label("The device that will be used for recording audio. If a device is not shown, then [i]sounddevice[/i] thinks it has 0 input channels. (this setting is unused for now)", classes="setting-desc")
                                
                            devices: list[str] = [device["name"] for device in sd.query_devices() if device["max_input_channels"] > 0]
                            input_device_name = self.app.config_handler.get("audio", "input_device")
                            
                            yield Select.from_values(
                                devices,
                                allow_blank=False,
                                id="input-device",
                                value=input_device_name if input_device_name in devices else devices[0]
                            )
                        with HorizontalGroup(classes="setting"):
                            with VerticalGroup():
                                yield Label("Block Size", classes="setting-name")
                                yield Label("Block size of audio playback. Higher block size will reduce stutters or cut outs, but will also lead to higher CPU strain.", classes="setting-desc")
                            
                            yield Static("N/A", id="block-size-text")
                            yield Slider(
                                16,
                                2048,
                                step=16,
                                value=int(self.app.config_handler.get("audio", "block_size")),
                                id="block-size"
                            )