use crate::i18n::use_i18n;
use gloo_timers::callback::Timeout;
use leptos::prelude::*;

/// A component that displays authentication errors with proper internationalization
#[component]
pub fn AuthErrorDisplay(
    /// The error message to display (optional)
    #[prop(optional)]
    error: Option<String>,
    /// Whether to show the error in a dismissible alert
    #[prop(default = true)]
    dismissible: bool,
    /// Additional CSS classes to apply
    #[prop(optional)]
    class: Option<String>,
    /// Callback when error is dismissed
    #[prop(optional)]
    on_dismiss: Option<Callback<()>>,
) -> impl IntoView {
    let i18n = use_i18n();

    view! {
        <Show when=move || error.is_some()>
            <div class=move || format!(
                "bg-red-50 border border-red-200 rounded-md p-4 mb-4 {}",
                class.as_deref().unwrap_or("")
            )>
                <div class="flex items-start">
                    <div class="flex-shrink-0">
                        <svg class="h-5 w-5 text-red-400" viewBox="0 0 20 20" fill="currentColor">
                            <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/>
                        </svg>
                    </div>
                    <div class="ml-3 flex-1">
                        <p class="text-sm font-medium text-red-800">
                            {move || error.clone().unwrap_or_default()}
                        </p>
                    </div>
                    <Show when=move || dismissible && on_dismiss.is_some()>
                        <div class="ml-auto pl-3">
                            <div class="-mx-1.5 -my-1.5">
                                <button
                                    type="button"
                                    class="inline-flex bg-red-50 rounded-md p-1.5 text-red-500 hover:bg-red-100 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-red-50 focus:ring-red-600"
                                    on:click=move |_| {
                                        if let Some(callback) = on_dismiss {
                                            callback.call(());
                                        }
                                    }
                                >
                                    <span class="sr-only">{i18n.t("dismiss")}</span>
                                    <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
                                        <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"/>
                                    </svg>
                                </button>
                            </div>
                        </div>
                    </Show>
                </div>
            </div>
        </Show>
    }
}

/// A toast notification component for displaying errors
#[component]
pub fn AuthErrorToast(
    /// The error message to display
    error: String,
    /// Duration in milliseconds before auto-dismiss (0 = no auto-dismiss)
    #[prop(default = 5000)]
    duration: u32,
    /// Callback when toast is dismissed
    #[prop(optional)]
    on_dismiss: Option<Callback<()>>,
) -> impl IntoView {
    let i18n = use_i18n();
    let (visible, set_visible) = signal(true);

    // Auto-dismiss after duration
    if duration > 0 {
        let timeout = Timeout::new(duration, move || {
            set_visible.set(false);
            if let Some(callback) = on_dismiss {
                callback.call(());
            }
        });
        timeout.forget();
    }

    view! {
        <Show when=move || visible.get()>
            <div class="fixed top-4 right-4 z-50 max-w-sm w-full">
                <div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded-lg shadow-lg">
                    <div class="flex items-start">
                        <div class="flex-shrink-0">
                            <svg class="h-5 w-5 text-red-500" viewBox="0 0 20 20" fill="currentColor">
                                <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/>
                            </svg>
                        </div>
                        <div class="ml-3 flex-1">
                            <p class="text-sm font-medium">
                                {error}
                            </p>
                        </div>
                        <div class="ml-auto pl-3">
                            <div class="-mx-1.5 -my-1.5">
                                <button
                                    type="button"
                                    class="inline-flex bg-red-100 rounded-md p-1.5 text-red-500 hover:bg-red-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-red-100 focus:ring-red-600"
                                    on:click=move |_| {
                                        set_visible.set(false);
                                        if let Some(callback) = on_dismiss {
                                            callback.call(());
                                        }
                                    }
                                >
                                    <span class="sr-only">{i18n.t("dismiss")}</span>
                                    <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
                                        <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"/>
                                    </svg>
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </Show>
    }
}

/// A more compact inline error display
#[component]
pub fn InlineAuthError(
    /// The error message to display
    error: String,
    /// Additional CSS classes
    #[prop(optional)]
    class: Option<String>,
) -> impl IntoView {
    view! {
        <div class=move || format!(
            "text-sm text-red-600 mt-1 {}",
            class.as_deref().unwrap_or("")
        )>
            <div class="flex items-center">
                <svg class="h-4 w-4 mr-1 flex-shrink-0" viewBox="0 0 20 20" fill="currentColor">
                    <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"/>
                </svg>
                <span>{error}</span>
            </div>
        </div>
    }
}

/// Example usage component showing how to integrate with the auth context
#[component]
pub fn AuthErrorExample() -> impl IntoView {
    let auth = crate::auth::use_auth();
    let i18n = use_i18n();

    view! {
        <div class="space-y-4">
            <h3 class="text-lg font-medium text-gray-900">
                {i18n.t("authentication-errors")}
            </h3>

            // Display current auth error if any
            <AuthErrorDisplay
                error=move || auth.0.error()
                on_dismiss=Callback::new(move |_| {
                    (auth.0.actions.clear_error)();
                })
            />

            // Example of inline error display
            <Show when=move || auth.0.error().is_some()>
                <InlineAuthError
                    error=move || auth.0.error().unwrap_or_default()
                />
            </Show>

            // Example of toast notification
            <Show when=move || auth.0.error().is_some()>
                <AuthErrorToast
                    error=move || auth.0.error().unwrap_or_default()
                    duration=3000
                    on_dismiss=Callback::new(move |_| {
                        (auth.0.actions.clear_error)();
                    })
                />
            </Show>
        </div>
    }
}
