"""
TUI Dialog components for Infra Services Management
"""

import os
from textual.app import ComposeResult
from textual.widgets import Button, Label, Markdown, Input, TextArea
from textual.containers import Horizontal, Vertical
from textual.screen import ModalScreen
from ..core.config import Config
from ..core.users import UserManager


class ConfirmDialog(ModalScreen):
    """Confirmation dialog for actions"""

    def __init__(self, message: str, on_confirm=None):
        super().__init__()
        self.message = message
        self.on_confirm_callback = on_confirm

    def compose(self) -> ComposeResult:
        yield Vertical(
            Markdown(self.message, id="dialog-message"),
            Horizontal(
                Button("Yes", id="yes", variant="error"),
                Button("No", id="no", variant="default"),
                id="dialog-buttons"
            ),
            id="dialog"
        )

    def on_button_pressed(self, event: Button.Pressed) -> None:
        if event.button.id == "yes":
            self.dismiss(True)
            if self.on_confirm_callback:
                self.on_confirm_callback()
        else:
            self.dismiss(False)

    CSS = """
    #dialog {
        align: center middle;
        border: thick green;
        padding: 2;
        background: $surface;
    }

    #dialog-message {
        margin-bottom: 2;
    }

    #dialog-buttons {
        align: center middle;
    }

    Button {
        min-width: 15;
        margin: 0 2;
    }
    """


class SelectUserTypeDialog(ModalScreen):
    """Dialog for adding a new user - step 1: select user type"""

    def __init__(self, app_instance):
        super().__init__()
        self.app_instance = app_instance

    def compose(self) -> ComposeResult:
        from .dialogs import EnterUsernameDialog
        yield Vertical(
            Label("Create New User", id="user-type-title"),
            Label("Select user type:", id="user-type-label"),
            Button("Regular User (with home directory)", id="user-type-regular", variant="primary"),
            Button("System User (no home directory)", id="user-type-system", variant="default"),
            Horizontal(
                Button("Cancel", id="add-user-cancel", variant="default"),
                id="user-type-buttons"
            ),
            id="user-type-dialog"
        )

    def on_button_pressed(self, event: Button.Pressed) -> None:
        if event.button.id == "user-type-regular":
            self.dismiss(False)
            self.app_instance.push_screen(EnterUsernameDialog(self.app_instance, create_home=True))
        elif event.button.id == "user-type-system":
            self.dismiss(False)
            self.app_instance.push_screen(EnterUsernameDialog(self.app_instance, create_home=False))
        else:
            self.dismiss(False)

    CSS = """
    #user-type-dialog {
        align: center middle;
        padding: 1 2;
        border: thick green;
        background: $surface;
        width: 60;
    }

    #user-type-title {
        text-align: center;
        text-style: bold;
        margin-bottom: 1;
    }

    #user-type-buttons {
        align: center middle;
        margin-top: 1;
    }

    Button {
        min-width: 15;
        margin: 0 2;
    }

    #user-type-regular, #user-type-system {
        width: 50;
        margin: 1 0;
    }
    """


class EnterUsernameDialog(ModalScreen):
    """Dialog for adding a new user - step 2: enter username"""

    def __init__(self, app_instance, create_home: bool):
        super().__init__()
        self.app_instance = app_instance
        self.create_home = create_home
        self.user_type = "Regular User" if create_home else "System User"

    def compose(self) -> ComposeResult:
        yield Vertical(
            Label(f"Create {self.user_type}", id="user-dialog-title"),
            Label("Username:", id="username-label"),
            Input(placeholder="Enter username", id="username-input"),
            Horizontal(
                Button("Create", id="add-user-create", variant="primary"),
                Button("Cancel", id="add-user-cancel", variant="default"),
                id="user-dialog-buttons"
            ),
            id="user-dialog"
        )

    def on_button_pressed(self, event: Button.Pressed) -> None:
        if event.button.id == "add-user-create":
            username = self.query_one("#username-input", Input).value.strip()

            if not username:
                self.notify("Username is required", severity="error")
                return

            # Validate username (alphanumeric, underscore, hyphen)
            import re
            if not re.match(r'^[a-zA-Z_][a-zA-Z0-9_-]*$', username):
                self.notify("Invalid username. Use letters, numbers, _, -, starting with letter or _", severity="error")
                return

            # Check if user already exists
            if UserManager.user_exists(username):
                self.notify(f"User '{username}' already exists", severity="error")
                return

            shell = "/bin/bash" if self.create_home else "/usr/sbin/nologin"

            def do_add_user():
                result = UserManager.create_user(username, self.create_home)
                if result["success"]:
                    self.app_instance.notify(result["message"], severity="information")
                    self.app_instance.run_worker(self.app_instance.refresh_users_table)
                    # Offer to set password for regular users (with home/login capability)
                    if self.create_home:
                        self.app_instance.push_screen(SetPasswordDialog(
                            self.app_instance, username, is_new_user=True
                        ))
                else:
                    self.app_instance.notify(result["message"], severity="error")

            self.dismiss(False)
            self.app_instance.push_screen(ConfirmDialog(
                f"Create {self.user_type.lower()} **{username}**?\n\n"
                f"Home directory: {'Yes' if self.create_home else 'No'}\n"
                f"Shell: {shell}",
                on_confirm=do_add_user
            ))
        else:
            self.dismiss(False)

    CSS = """
    #user-dialog, #user-type-dialog {
        align: center middle;
        border: thick cyan;
        padding: 2;
        background: $surface;
        width: 60;
    }

    #user-dialog-title, #user-type-title {
        text-align: center;
        text-style: bold;
        margin-bottom: 1;
    }

    Label {
        margin-top: 1;
    }

    #user-dialog-buttons, #user-type-buttons {
        align: center middle;
        margin-top: 1;
    }

    Button {
        min-width: 15;
        margin: 0 2;
    }

    #user-type-regular, #user-type-system {
        width: 50;
        margin: 1 0;
    }
    """


class SetPasswordDialog(ModalScreen):
    """Dialog for setting a user's password"""

    def __init__(self, app_instance, username: str, is_new_user: bool = False):
        super().__init__()
        self.app_instance = app_instance
        self.username = username
        self.is_new_user = is_new_user

    def compose(self) -> ComposeResult:
        title = f"Set Password for {self.username}"
        yield Vertical(
            Label(title, id="password-dialog-title"),
            Label("Password:", id="password-label"),
            Input(placeholder="Enter password", id="password-input", password=True),
            Label("Confirm Password:", id="confirm-label"),
            Input(placeholder="Confirm password", id="confirm-input", password=True),
            Horizontal(
                Button("Set Password", id="set-password-btn", variant="primary"),
                Button("Skip" if self.is_new_user else "Cancel", id="skip-password-btn", variant="default"),
                id="password-dialog-buttons"
            ),
            id="password-dialog"
        )

    def on_button_pressed(self, event: Button.Pressed) -> None:
        if event.button.id == "set-password-btn":
            password = self.query_one("#password-input", Input).value
            confirm = self.query_one("#confirm-input", Input).value

            if not password:
                self.app_instance.notify("Password is required", severity="error")
                return

            if password != confirm:
                self.app_instance.notify("Passwords do not match", severity="error")
                return

            if len(password) < 4:
                self.app_instance.notify("Password must be at least 4 characters", severity="error")
                return

            result = UserManager.set_password(self.username, password)
            if result["success"]:
                self.app_instance.notify(result["message"], severity="information")
            else:
                self.app_instance.notify(result["message"], severity="error")

            self.dismiss(True)
            self._ask_sudo_if_new_user()
        else:
            self.dismiss(False)
            self._ask_sudo_if_new_user()

    def _ask_sudo_if_new_user(self):
        """Ask about adding to sudoers for new regular users"""
        if self.is_new_user:
            username = self.username

            def do_add_sudo():
                result = UserManager.add_to_sudoers(username)
                if result["success"]:
                    self.app_instance.notify(result["message"], severity="information")
                    self.app_instance.run_worker(self.app_instance.refresh_users_table)
                else:
                    self.app_instance.notify(result["message"], severity="error")

            self.app_instance.push_screen(ConfirmDialog(
                f"Add **{username}** to sudoers group?\n\nThis will allow the user to run commands as root.",
                on_confirm=do_add_sudo
            ))

    CSS = """
    #password-dialog {
        align: center middle;
        border: thick cyan;
        padding: 2;
        background: $surface;
        width: 50;
    }

    #password-dialog-title {
        text-align: center;
        text-style: bold;
        margin-bottom: 1;
    }

    #password-dialog-buttons {
        align: center middle;
        margin-top: 1;
    }

    Button {
        min-width: 15;
        margin: 0 2;
    }
    """


class SudoPasswordDialog(ModalScreen):
    """Dialog for collecting sudo password"""

    def __init__(self, app_instance):
        super().__init__()
        self.app_instance = app_instance
        self.password = ""

    def compose(self) -> ComposeResult:
        yield Vertical(
            Label("Sudo Password Required", id="sudo-title"),
            Label("Enter your sudo password to continue:", id="sudo-label"),
            Input(placeholder="Password", id="sudo-password-input", password=True),
            Horizontal(
                Button("Submit", id="sudo-submit", variant="primary"),
                Button("Cancel", id="sudo-cancel", variant="default"),
                id="sudo-buttons"
            ),
            id="sudo-dialog"
        )

    def on_button_pressed(self, event: Button.Pressed) -> None:
        if event.button.id == "sudo-submit":
            self.password = self.query_one("#sudo-password-input", Input).value
            if self.password:
                self.dismiss(self.password)
            else:
                self.notify("Password is required", severity="error")
        else:
            self.dismiss(None)

    def on_input_submitted(self, event: Input.Submitted) -> None:
        """Handle Enter key in password input"""
        if event.input.id == "sudo-password-input":
            self.password = event.input.value
            if self.password:
                self.dismiss(self.password)
            else:
                self.notify("Password is required", severity="error")

    CSS = """
    #sudo-dialog {
        align: center middle;
        padding: 3;
    }

    #sudo-title {
        text-align: center;
        text-style: bold;
        margin-bottom: 1;
    }

    #sudo-label {
        margin-bottom: 1;
    }

    #sudo-buttons {
        align: center middle;
        margin-top: 1;
    }

    Button {
        min-width: 15;
        margin: 0 2;
    }
    """


class SSHTestDialog(ModalScreen):
    """Dialog for testing SSH with private key and optional passphrase/password"""

    def __init__(self, app_instance, user: str, has_key: bool, has_password: bool):
        super().__init__()
        self.app_instance = app_instance
        self.user = user
        self.has_key = has_key
        self.has_password = has_password

    def compose(self) -> ComposeResult:
        yield Vertical(
            Label(f"SSH Test for {self.user}", id="ssh-test-title"),
            Label("Provide SSH credentials:", id="ssh-test-label"),
            Label("", id="ssh-spacer1"),
            Label("Private Key (paste content or path):", id="ssh-key-label"),
            TextArea(id="ssh-key-input"),
            Label("Passphrase (if key is encrypted):", id="ssh-passphrase-label"),
            Input(placeholder="Leave empty if no passphrase", id="ssh-passphrase-input", password=True),
            Label("", id="ssh-spacer2"),
            Label("— OR —", id="ssh-or-label"),
            Label("Password:", id="ssh-password-label"),
            Input(placeholder="SSH password", id="ssh-password-input", password=True),
            Horizontal(
                Button("Test", id="ssh-test-submit", variant="primary"),
                Button("Cancel", id="ssh-auth-cancel", variant="default"),
                id="ssh-auth-buttons"
            ),
            id="ssh-test-dialog"
        )

    def on_mount(self) -> None:
        # Set some reasonable defaults for the TextArea
        key_input = self.query_one("#ssh-key-input", TextArea)
        key_input.styles.height = 8
        key_input.styles.width = "100%"

    def on_button_pressed(self, event: Button.Pressed) -> None:
        button_id = event.button.id

        if button_id == "ssh-auth-cancel":
            self.dismiss(None)
            return

        if button_id == "ssh-test-submit":
            key_content = self.query_one("#ssh-key-input", TextArea).text.strip()
            passphrase = self.query_one("#ssh-passphrase-input", Input).value
            password = self.query_one("#ssh-password-input", Input).value

            # Auto-detect which method to use based on what's provided
            if key_content:
                self.dismiss({
                    "method": "key",
                    "key_content": key_content,
                    "passphrase": passphrase if passphrase else None,
                    "user": self.user
                })
            elif password:
                self.dismiss({
                    "method": "password",
                    "credential": password,
                    "user": self.user
                })
            else:
                self.app_instance.notify("Please provide private key or password", severity="error")

    CSS = """
    #ssh-test-dialog {
        align: center middle;
        padding: 2;
        width: 80;
    }

    #ssh-test-title {
        text-align: center;
        text-style: bold;
        margin-bottom: 1;
    }

    #ssh-test-label {
        margin-bottom: 1;
    }

    #ssh-key-label, #ssh-passphrase-label, #ssh-password-label {
        margin-top: 1;
    }

    #ssh-or-label {
        text-align: center;
        color: $text-muted;
        margin: 1 0;
    }

    #ssh-key-input {
        height: 8;
        margin: 0 0 1 0;
    }

    #ssh-auth-buttons {
        align: center middle;
        margin-top: 1;
    }

    #ssh-spacer1, #ssh-spacer2 {
        height: 1;
    }

    Button {
        min-width: 15;
        margin: 0 1;
    }
    """


class SSHKeySetupDialog(ModalScreen):
    """Dialog for adding SSH public key to a user"""

    def __init__(self, app_instance, user: str):
        super().__init__()
        self.app_instance = app_instance
        self.user = user

    def compose(self) -> ComposeResult:
        if self.user == "root":
            path = "/root/.ssh/authorized_keys"
        else:
            path = f"/home/{self.user}/.ssh/authorized_keys"

        yield Vertical(
            Label(f"Add SSH Key for {self.user}", id="sshkey-title"),
            Label(f"Paste your public key (ssh-rsa, ssh-ed25519, etc.):", id="sshkey-label"),
            Label(f"Will be added to: {path}", id="sshkey-path"),
            Input(placeholder="ssh-ed25519 AAAA... user@host", id="sshkey-input"),
            Horizontal(
                Button("Add Key", id="sshkey-add", variant="success"),
                Button("Cancel", id="sshkey-cancel", variant="error"),
                id="sshkey-buttons"
            ),
            id="sshkey-dialog"
        )

    def on_button_pressed(self, event: Button.Pressed) -> None:
        if event.button.id == "sshkey-cancel":
            self.dismiss(None)
            return

        if event.button.id == "sshkey-add":
            key = self.query_one("#sshkey-input", Input).value.strip()
            if not key:
                self.app_instance.notify("Please paste your public key", severity="error")
                return

            # Basic validation
            if not any(key.startswith(t) for t in ["ssh-rsa", "ssh-ed25519", "ssh-dss", "ecdsa-sha2"]):
                self.app_instance.notify("Invalid key format. Should start with ssh-rsa, ssh-ed25519, etc.", severity="error")
                return

            self.dismiss({"user": self.user, "key": key})

    def on_input_submitted(self, event: Input.Submitted) -> None:
        if event.input.id == "sshkey-input":
            key = event.input.value.strip()
            if key and any(key.startswith(t) for t in ["ssh-rsa", "ssh-ed25519", "ssh-dss", "ecdsa-sha2"]):
                self.dismiss({"user": self.user, "key": key})

    CSS = """
    #sshkey-dialog {
        align: center middle;
        padding: 2;
    }

    #sshkey-title {
        text-align: center;
        text-style: bold;
        margin-bottom: 1;
    }

    #sshkey-label {
        margin-bottom: 1;
    }

    #sshkey-path {
        color: $text-muted;
        margin-bottom: 1;
    }

    #sshkey-input {
        width: 100%;
        margin-bottom: 1;
    }

    #sshkey-buttons {
        align: center middle;
        margin-top: 1;
    }

    Button {
        min-width: 12;
        margin: 0 1;
    }
    """


class InitialSetupDialog(ModalScreen):
    """Initial setup dialog for first-time users"""

    def __init__(self, app_instance):
        super().__init__()
        self.app_instance = app_instance
        self.setup_needed = []
        self.setup_completed = False

    def compose(self) -> ComposeResult:
        issues = []

        # Check what needs to be set up
        if not Config.SERVICES_DIR.exists():
            issues.append(f"* Create services directory: {Config.SERVICES_DIR}")
            self.setup_needed.append("services_dir")
        if not UserManager.group_exists():
            issues.append(f"* Create group: {UserManager.GROUP_NAME}")
            self.setup_needed.append("group")
        if not Config.CONFIG_DIR.exists():
            issues.append(f"* Create config directory: {Config.CONFIG_DIR}")
            self.setup_needed.append("config_dir")

        if not issues:
            issues.append("All set up!")
            self.setup_completed = True

        yield Vertical(
            Label("Initial Setup Required", id="setup-title"),
            Label("Infra needs to set up the following:", id="setup-subtitle"),
            Label("\n".join(issues), id="setup-list"),
            Label("This will require sudo privileges.", id="setup-warning"),
            Horizontal(
                Button("Setup", id="setup-btn", variant="primary"),
                Button("Skip", id="skip-btn", variant="default"),
                id="setup-buttons"
            ),
            id="setup-dialog"
        )

    def on_button_pressed(self, event: Button.Pressed) -> None:
        if event.button.id == "setup-btn":
            self.run_setup()
        else:
            self.dismiss(False)

    def run_setup(self):
        """Run the setup process"""
        import subprocess

        for item in self.setup_needed:
            if item == "services_dir":
                self.notify(f"Creating {Config.SERVICES_DIR}...", severity="information")
                result = subprocess.run(
                    f"sudo mkdir -p {Config.SERVICES_DIR}",
                    shell=True,
                    capture_output=True,
                    text=True
                )
                if result.returncode == 0:
                    # Set up permissions for group management
                    subprocess.run(
                        f"sudo chgrp -R {UserManager.GROUP_NAME} {Config.INSTALL_DIR} 2>/dev/null || true",
                        shell=True
                    )
                    subprocess.run(
                        f"sudo chmod -R g+rwx {Config.SERVICES_DIR} 2>/dev/null || true",
                        shell=True
                    )

            elif item == "group":
                self.notify(f"Creating {UserManager.GROUP_NAME} group...", severity="information")
                UserManager.create_group()

            elif item == "config_dir":
                self.notify(f"Creating {Config.CONFIG_DIR}...", severity="information")
                result = subprocess.run(
                    f"sudo mkdir -p {Config.CONFIG_DIR}",
                    shell=True,
                    capture_output=True,
                    text=True
                )

        # Add current user to group
        if UserManager.group_exists():
            current_user = os.environ.get("USER", "")
            if current_user and not UserManager.is_user_in_group(current_user):
                self.notify(f"Adding user '{current_user}' to group...", severity="information")
                UserManager.add_user_to_group(current_user)

        self.notify("Setup complete! Please log out and back in for group changes to take effect.", severity="information")
        self.dismiss(True)
        self.app_instance.ensure_group_membership()
        # Initialize all tables after setup completes
        self.app_instance.initialize_all_tables()

    CSS = """
    #setup-dialog {
        align: center middle;
        border: thick cyan;
        padding: 3;
        background: $surface;
        min-width: 60;
    }

    #setup-title {
        text-align: center;
        text-style: bold;
        margin-bottom: 1;
    }

    #setup-subtitle {
        text-align: center;
        margin-bottom: 1;
    }

    #setup-list {
        margin: 1 0;
        text-style: bold;
    }

    #setup-warning {
        margin: 1 0;
        color: $warning;
        text-style: italic;
    }

    #setup-buttons {
        align: center middle;
        margin-top: 1;
    }

    Button {
        min-width: 15;
        margin: 0 2;
    }
    """
