//! Utility functions for the admin UI.

/// Gets the API base path based on the current URL.
///
/// Returns `/api/admin` if the current path starts with `/admin`,
/// otherwise returns `/api`.
///
/// # Example
/// ```rust
/// let api_base = get_api_base();
/// let url = format!("{}/realms/{}", api_base, slug);
/// ```
#[cfg(feature = "hydrate")]
pub fn get_api_base() -> String {
    web_sys::window()
        .and_then(|w| w.location().pathname().ok())
        .map(|path| {
            if path.starts_with("/admin") {
                "/api/admin".to_string()
            } else {
                "/api".to_string()
            }
        })
        .unwrap_or_else(|| "/api".to_string())
}

/// Gets the API base path (SSR fallback - always returns /api).
#[cfg(not(feature = "hydrate"))]
pub fn get_api_base() -> String {
    "/api".to_string()
}

/// Reloads the current page.
#[cfg(feature = "hydrate")]
pub fn reload_page() {
    if let Some(window) = web_sys::window() {
        let _ = window.location().reload();
    }
}

/// Reloads the current page (SSR no-op).
#[cfg(not(feature = "hydrate"))]
pub fn reload_page() {}

/// Navigates to a new URL.
#[cfg(feature = "hydrate")]
pub fn navigate_to(url: &str) {
    if let Some(window) = web_sys::window() {
        let _ = window.location().set_href(url);
    }
}

/// Navigates to a new URL (SSR no-op).
#[cfg(not(feature = "hydrate"))]
pub fn navigate_to(_url: &str) {}

/// Shows a browser confirm dialog and returns the result.
#[cfg(feature = "hydrate")]
pub fn confirm(message: &str) -> bool {
    web_sys::window()
        .and_then(|w| w.confirm_with_message(message).ok())
        .unwrap_or(false)
}

/// Shows a browser confirm dialog (SSR fallback - always returns false).
#[cfg(not(feature = "hydrate"))]
pub fn confirm(_message: &str) -> bool {
    false
}

/// Builds a paginated URL with optional search query.
pub fn build_paginated_url(base: &str, page: i64, query: &str, limit: i64) -> String {
    if query.is_empty() {
        format!("{}?page={}&limit={}", base, page, limit)
    } else {
        format!("{}?q={}&page={}&limit={}", base, query, page, limit)
    }
}

/// Parse width and height from WKT bounds string.
///
/// Example: "POLYGON((0 0, 800 0, 800 600, 0 600, 0 0))" -> (800, 600)
/// Handles both "0 0, 800 0" (with space) and "0 0,800 0" (without space) formats.
pub fn parse_bounds_wkt(wkt: &str) -> (i32, i32) {
    // Extract coordinates from POLYGON((x1 y1, x2 y2, x3 y3, x4 y4, x5 y5))
    // The second point has (width, 0) and third point has (width, height)
    if let Some(start) = wkt.find("((") {
        if let Some(end) = wkt.find("))") {
            let coords_str = &wkt[start + 2..end];
            let points: Vec<&str> = coords_str.split(',').map(|s| s.trim()).collect();
            if points.len() >= 3 {
                // Second point: "width 0"
                let second: Vec<&str> = points[1].split_whitespace().collect();
                // Third point: "width height"
                let third: Vec<&str> = points[2].split_whitespace().collect();
                if !second.is_empty() && third.len() >= 2 {
                    let width = second[0].parse().unwrap_or(800);
                    let height = third[1].parse().unwrap_or(600);
                    return (width, height);
                }
            }
        }
    }
    (800, 600)
}

/// Builds a WKT polygon string from width and height.
pub fn build_bounds_wkt(width: i32, height: i32) -> String {
    format!(
        "POLYGON((0 0, {} 0, {} {}, 0 {}, 0 0))",
        width, width, height, height
    )
}

/// Fetch image dimensions client-side using JavaScript Image API.
///
/// This works regardless of CORS since we're only reading dimensions, not pixel data.
/// The key is NOT setting the `crossorigin` attribute on the image element.
///
/// # Arguments
/// * `url` - The image URL to fetch dimensions from
/// * `on_success` - Callback receiving (width, height) on success
/// * `on_error` - Callback receiving error message on failure
/// * `set_loading` - Signal to set loading state
#[cfg(feature = "hydrate")]
pub fn fetch_image_dimensions_client<F, E>(
    url: String,
    on_success: F,
    on_error: E,
    set_loading: leptos::prelude::WriteSignal<bool>,
)
where
    F: Fn(u32, u32) + 'static,
    E: Fn(String) + Clone + 'static,
{
    use leptos::prelude::Set;
    use wasm_bindgen::prelude::*;
    use wasm_bindgen::JsCast;

    let on_error_for_onerror = on_error.clone();

    let window = match web_sys::window() {
        Some(w) => w,
        None => {
            on_error("No window object available".to_string());
            set_loading.set(false);
            return;
        }
    };

    let document = match window.document() {
        Some(d) => d,
        None => {
            on_error("No document object available".to_string());
            set_loading.set(false);
            return;
        }
    };

    let img: web_sys::HtmlImageElement = match document
        .create_element("img")
        .ok()
        .and_then(|el| el.dyn_into().ok())
    {
        Some(img) => img,
        None => {
            on_error("Failed to create image element".to_string());
            set_loading.set(false);
            return;
        }
    };

    // Note: We intentionally do NOT set crossorigin attribute.
    // Without it, we can load images from any URL and read their dimensions.
    // The crossorigin attribute would cause CORS errors for external images.

    let img_clone = img.clone();

    let onload = Closure::wrap(Box::new(move || {
        let width = img_clone.natural_width();
        let height = img_clone.natural_height();
        set_loading.set(false);
        if width > 0 && height > 0 {
            on_success(width, height);
        } else {
            on_error("Could not determine image dimensions".to_string());
        }
    }) as Box<dyn Fn()>);

    let onerror = Closure::wrap(Box::new(move || {
        set_loading.set(false);
        on_error_for_onerror("Failed to load image".to_string());
    }) as Box<dyn Fn()>);

    img.set_onload(Some(onload.as_ref().unchecked_ref()));
    img.set_onerror(Some(onerror.as_ref().unchecked_ref()));

    // Trigger the load
    img.set_src(&url);

    // Prevent closures from being dropped
    onload.forget();
    onerror.forget();
}
