use leptos::prelude::*;
use leptos::task::spawn_local;
use crate::services::auth_service::AuthService;

#[derive(Clone, Copy, Debug, PartialEq)]
enum SetupStep {
    Initial,
    ScanQr,
    Verify,
    BackupCodes,
}

#[component]
pub fn MfaSetupTotp(
    #[prop(into)] access_token: Signal<String>,
    #[prop(optional)] on_complete: Option<Box<dyn Fn() + Send + Sync>>,
) -> impl IntoView {
    let (step, set_step) = signal(SetupStep::Initial);
    let (qr_code, set_qr_code) = signal(String::new());
    let (secret, set_secret) = signal(String::new());
    let (manual_code, set_manual_code) = signal(String::new());
    let (verification_code, set_verification_code) = signal(String::new());
    let (backup_codes, set_backup_codes) = signal(Vec::<String>::new());
    let (error_message, set_error_message) = signal(None::<String>);
    let (loading, set_loading) = signal(false);
    let (codes_saved, set_codes_saved) = signal(false);

    let auth_service = AuthService::new();

    // Start TOTP enrollment
    let start_enrollment = move |_| {
        set_loading.set(true);
        set_error_message.set(None);

        let auth_service = auth_service.clone();
        let token = access_token.get();

        spawn_local(async move {
            match auth_service.enroll_totp(token).await {
                Ok(response) => {
                    set_qr_code.set(response.qr_code);
                    set_secret.set(response.secret);
                    set_manual_code.set(response.manual_entry_code);
                    set_step.set(SetupStep::ScanQr);
                }
                Err(e) => {
                    set_error_message.set(Some(format!("Failed to start enrollment: {}", e)));
                }
            }
            set_loading.set(false);
        });
    };

    // Verify TOTP code
    let verify_code = move |_| {
        set_loading.set(true);
        set_error_message.set(None);

        let auth_service = auth_service.clone();
        let token = access_token.get();
        let code = verification_code.get();

        spawn_local(async move {
            match auth_service.verify_totp(token, code).await {
                Ok(response) => {
                    if response.success {
                        set_backup_codes.set(response.backup_codes);
                        set_step.set(SetupStep::BackupCodes);
                    } else {
                        set_error_message.set(Some("Invalid verification code".to_string()));
                    }
                }
                Err(e) => {
                    set_error_message.set(Some(format!("Verification failed: {}", e)));
                }
            }
            set_loading.set(false);
        });
    };

    // Download backup codes
    let download_codes = move |_| {
        let codes = backup_codes.get();
        let text = codes.join("\n");
        let blob = web_sys::Blob::new_with_str_sequence(&js_sys::Array::of1(&text.into())).unwrap();
        let url = web_sys::Url::create_object_url_with_blob(&blob).unwrap();

        let document = web_sys::window().unwrap().document().unwrap();
        let link = document.create_element("a").unwrap();
        link.set_attribute("href", &url).unwrap();
        link.set_attribute("download", "backup-codes.txt").unwrap();
        link.dyn_ref::<web_sys::HtmlElement>().unwrap().click();

        web_sys::Url::revoke_object_url(&url).unwrap();
    };

    // Complete setup
    let complete_setup = move |_| {
        if codes_saved.get() {
            if let Some(callback) = &on_complete {
                callback();
            }
        }
    };

    view! {
        <div class="max-w-2xl mx-auto">
            // Error alert
            {move || error_message.get().map(|err| view! {
                <div class="alert alert-error shadow-lg mb-4">
                    <div>
                        <svg xmlns="http://www.w3.org/2000/svg" class="stroke-current flex-shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
                        </svg>
                        <span>{err}</span>
                    </div>
                </div>
            })}

            // Progress steps
            <ul class="steps steps-vertical lg:steps-horizontal w-full mb-8">
                <li class="step" class:step-primary=move || step.get() as u8 >= SetupStep::Initial as u8>"Setup"</li>
                <li class="step" class:step-primary=move || step.get() as u8 >= SetupStep::ScanQr as u8>"Scan QR"</li>
                <li class="step" class:step-primary=move || step.get() as u8 >= SetupStep::Verify as u8>"Verify"</li>
                <li class="step" class:step-primary=move || step.get() as u8 >= SetupStep::BackupCodes as u8>"Backup Codes"</li>
            </ul>

            // Step 1: Initial
            <Show
                when=move || step.get() == SetupStep::Initial
                fallback=|| view! { <div></div> }
            >
                <div class="card bg-base-100 shadow-xl">
                    <div class="card-body">
                        <h2 class="card-title text-2xl">"Setup Authenticator App"</h2>
                        <div class="space-y-4">
                            <div class="alert alert-info">
                                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="stroke-current shrink-0 w-6 h-6">
                                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
                                </svg>
                                <span>"You'll need an authenticator app like Google Authenticator, Authy, or 1Password."</span>
                            </div>

                            <div class="prose">
                                <h3>"How it works:"</h3>
                                <ol>
                                    <li>"Scan a QR code with your authenticator app"</li>
                                    <li>"Enter a verification code to confirm"</li>
                                    <li>"Save backup codes for account recovery"</li>
                                    <li>"Use codes from your app to log in"</li>
                                </ol>
                            </div>

                            <div class="divider"></div>

                            <div class="card-actions justify-end">
                                <button
                                    class="btn btn-primary"
                                    on:click=start_enrollment
                                    disabled=move || loading.get()
                                >
                                    {move || if loading.get() {
                                        view! {
                                            <span class="loading loading-spinner loading-sm"></span>
                                            " Loading..."
                                        }.into_view()
                                    } else {
                                        view! { "Get Started" }.into_view()
                                    }}
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
            </Show>

            // Step 2: Scan QR Code
            <Show
                when=move || step.get() == SetupStep::ScanQr
                fallback=|| view! { <div></div> }
            >
                <div class="card bg-base-100 shadow-xl">
                    <div class="card-body">
                        <h2 class="card-title text-2xl">"Scan QR Code"</h2>

                        <div class="flex flex-col items-center space-y-4">
                            <p class="text-center">"Scan this QR code with your authenticator app"</p>

                            // QR Code display
                            <div class="p-4 bg-white rounded-lg shadow-inner">
                                <img src=move || qr_code.get() alt="QR Code" class="w-64 h-64" />
                            </div>

                            <div class="divider">"OR"</div>

                            <div class="w-full">
                                <p class="text-sm text-base-content/70 mb-2">"Enter this code manually:"</p>
                                <div class="flex items-center gap-2">
                                    <input
                                        type="text"
                                        class="input input-bordered flex-1 font-mono"
                                        readonly
                                        prop:value=manual_code
                                    />
                                    <button
                                        class="btn btn-square btn-outline"
                                        on:click=move |_| {
                                            let window = web_sys::window().unwrap();
                                            let _ = window.navigator().clipboard()
                                                .write_text(&manual_code.get());
                                        }
                                    >
                                        <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
                                        </svg>
                                    </button>
                                </div>
                            </div>
                        </div>

                        <div class="card-actions justify-end mt-6">
                            <button
                                class="btn btn-primary"
                                on:click=move |_| set_step.set(SetupStep::Verify)
                            >
                                "Continue"
                            </button>
                        </div>
                    </div>
                </div>
            </Show>

            // Step 3: Verify Code
            <Show
                when=move || step.get() == SetupStep::Verify
                fallback=|| view! { <div></div> }
            >
                <div class="card bg-base-100 shadow-xl">
                    <div class="card-body">
                        <h2 class="card-title text-2xl">"Verify Setup"</h2>

                        <div class="space-y-4">
                            <p>"Enter the 6-digit code from your authenticator app to confirm the setup:"</p>

                            <div class="form-control">
                                <input
                                    type="text"
                                    class="input input-bordered input-lg text-center text-2xl tracking-widest"
                                    placeholder="000000"
                                    maxlength="6"
                                    pattern="[0-9]{6}"
                                    on:input=move |ev| {
                                        set_verification_code.set(event_target_value(&ev));
                                    }
                                    prop:value=verification_code
                                />
                            </div>
                        </div>

                        <div class="card-actions justify-between mt-6">
                            <button
                                class="btn btn-ghost"
                                on:click=move |_| set_step.set(SetupStep::ScanQr)
                            >
                                "Back"
                            </button>
                            <button
                                class="btn btn-primary"
                                on:click=verify_code
                                disabled=move || loading.get() || verification_code.get().len() != 6
                            >
                                {move || if loading.get() {
                                    view! {
                                        <span class="loading loading-spinner loading-sm"></span>
                                        " Verifying..."
                                    }.into_view()
                                } else {
                                    view! { "Verify & Continue" }.into_view()
                                }}
                            </button>
                        </div>
                    </div>
                </div>
            </Show>

            // Step 4: Backup Codes
            <Show
                when=move || step.get() == SetupStep::BackupCodes
                fallback=|| view! { <div></div> }
            >
                <div class="card bg-base-100 shadow-xl">
                    <div class="card-body">
                        <h2 class="card-title text-2xl">"Save Backup Codes"</h2>

                        <div class="space-y-4">
                            <div class="alert alert-warning">
                                <svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24">
                                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
                                </svg>
                                <span>"Save these codes in a secure location. You can use them to access your account if you lose your device."</span>
                            </div>

                            <div class="bg-base-200 p-4 rounded-lg">
                                <div class="grid grid-cols-2 gap-2 font-mono">
                                    {move || backup_codes.get().into_iter().map(|code| {
                                        view! {
                                            <div class="p-2 bg-base-100 rounded text-center">
                                                {code}
                                            </div>
                                        }
                                    }).collect_view()}
                                </div>
                            </div>

                            <div class="flex gap-2">
                                <button class="btn btn-outline flex-1" on:click=download_codes>
                                    <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
                                    </svg>
                                    "Download Codes"
                                </button>
                                <button
                                    class="btn btn-outline flex-1"
                                    on:click=move |_| {
                                        let codes = backup_codes.get().join("\n");
                                        let window = web_sys::window().unwrap();
                                        let _ = window.navigator().clipboard().write_text(&codes);
                                    }
                                >
                                    <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
                                    </svg>
                                    "Copy to Clipboard"
                                </button>
                            </div>

                            <div class="form-control">
                                <label class="label cursor-pointer justify-start">
                                    <input
                                        type="checkbox"
                                        class="checkbox checkbox-primary"
                                        on:change=move |ev| {
                                            set_codes_saved.set(event_target_checked(&ev));
                                        }
                                    />
                                    <span class="label-text ml-2">"I have saved these codes in a secure location"</span>
                                </label>
                            </div>
                        </div>

                        <div class="card-actions justify-end mt-6">
                            <button
                                class="btn btn-success"
                                on:click=complete_setup
                                disabled=move || !codes_saved.get()
                            >
                                "Complete Setup"
                            </button>
                        </div>
                    </div>
                </div>
            </Show>
        </div>
    }
}
