use std::{future::Future, path::PathBuf};
use tokio::runtime::Handle;
use tokio_util::sync::CancellationToken;
use url::Url;

use super::GuiError;
use crate::Info;

pub struct RuntimeConfig {
    pub url: Url,
    pub output_path: PathBuf,
    /// Checkpoint file to resume from, if any.
    pub resume_from: Option<PathBuf>,
    pub page_delay_ms: u64,
}

/// Abstract crawl-and-extract pipeline.
///
/// Implement this to plug your own runtime into [`super::App`]. The GUI calls
/// [`Runtime::run`] on start and [`Runtime::on_exit`] when the window closes
/// while running (e.g. to flush a checkpoint).
pub trait Runtime<I: Info + Clone + Send + Sync + 'static>: Send + Sync + 'static {
    fn run(
        &self,
        config: RuntimeConfig,
        cancel: CancellationToken,
    ) -> impl Future<Output = Result<(), GuiError>> + Send;

    /// Called when the application exits while this runtime is still active.
    /// Default no-op — override to flush state (e.g. save a checkpoint).
    fn on_exit(&self) {}

    /// Whether the shared URL input should be displayed.
    fn show_url_input(&self) -> bool {
        true
    }

    /// Runtime-provided start URL used when the shared URL input is empty.
    fn fallback_start_url(&self) -> Option<Url> {
        None
    }

    /// Render runtime-specific configuration controls in the GUI.
    ///
    /// `enabled` is false while a crawl is running.
    fn render_config_extension(&self, _ui: &mut egui::Ui, _enabled: bool) {}

    /// Runtime-owned tabs to show next to the default crawler tab.
    fn extension_tabs(&self) -> &'static [&'static str] {
        &[]
    }

    /// Render a runtime-owned tab.
    ///
    /// `crawler_enabled` is false while the default crawler tab is running.
    fn render_extension_tab(
        &self,
        _tab: &str,
        _ui: &mut egui::Ui,
        _crawler_enabled: bool,
        _handle: &Handle,
    ) {
    }
}
