use anyhow::Result;
use futures::future::BoxFuture;
use tokio::sync::broadcast;

use super::models::config::SshConfig;
use super::models::session::SessionEvent;
use super::models::session::SessionId;
use super::models::types::{
    ExecRequest, ExecResult, FileEntry, PtyOpenRequest, ReadFileRequest, SystemProfile,
    WriteFileRequest,
};
use super::shell::SystemType;

/// Command execution service.
///
/// A unified command execution interface supporting connection validation, command execution,
/// system detection, and a simple shell. Suitable for automation scripts and operations tools.
pub trait ExecService {
    /// Validate that an SSH connection can be established and authenticated.
    fn validate(&self, cfg: SshConfig) -> BoxFuture<'static, Result<()>>;

    /// Execute a structured command request and return a structured result.
    fn exec(&self, cfg: SshConfig, req: ExecRequest) -> BoxFuture<'static, Result<ExecResult>>;

    /// Detect the remote system type.
    fn detect_system_type(&self, cfg: SshConfig) -> BoxFuture<'static, Result<SystemType>>;

    /// Detect full system information (OS, architecture, package manager, etc.).
    fn detect_system(&self, cfg: SshConfig) -> BoxFuture<'static, Result<SystemProfile>>;

    /// Open a simple interactive shell (non-PTY).
    fn open_shell(&self, cfg: SshConfig) -> BoxFuture<'static, Result<()>>;
}

/// PTY terminal service.
///
/// Provides full PTY terminal session management, suitable for Tauri terminal components,
/// vim/top, and other interactive scenarios.
pub trait PtyService {
    /// Open a remote PTY session and return a `SessionId`.
    fn open(&self, cfg: SshConfig, req: PtyOpenRequest) -> BoxFuture<'static, Result<SessionId>>;

    /// Write input data to an open PTY session.
    fn write_input(&self, session_id: SessionId, data: Vec<u8>) -> BoxFuture<'static, Result<()>>;

    /// Resize the PTY window.
    fn resize(
        &self,
        session_id: SessionId,
        cols: u32,
        rows: u32,
        pix_width: u32,
        pix_height: u32,
    ) -> BoxFuture<'static, Result<()>>;

    /// Close the PTY session.
    fn close(&self, session_id: SessionId) -> BoxFuture<'static, Result<()>>;

    /// Subscribe to PTY session output events.
    fn subscribe(
        &self,
        session_id: SessionId,
    ) -> BoxFuture<'static, Result<broadcast::Receiver<SessionEvent>>>;
}

/// File service.
///
/// Implemented via the SFTP subsystem, does not depend on remote shell commands,
/// consistent across platforms. Suitable for file managers, automated file transfer, etc.
pub trait FileService {
    /// List top-level entries in the specified directory.
    fn list_dir(&self, cfg: SshConfig, path: String) -> BoxFuture<'static, Result<Vec<FileEntry>>>;

    /// Read remote file content.
    fn read_file(
        &self,
        cfg: SshConfig,
        req: ReadFileRequest,
    ) -> BoxFuture<'static, Result<Vec<u8>>>;

    /// Write remote file content.
    fn write_file(&self, cfg: SshConfig, req: WriteFileRequest) -> BoxFuture<'static, Result<()>>;

    /// Download a remote file to a local path.
    fn download_file(
        &self,
        cfg: SshConfig,
        remote_path: &str,
        local_path: &str,
    ) -> BoxFuture<'static, Result<()>>;

    /// Upload a local file to a remote path.
    fn upload_file(
        &self,
        cfg: SshConfig,
        local_path: &str,
        remote_path: &str,
    ) -> BoxFuture<'static, Result<()>>;
}
