use leptos::prelude::*;
use leptos::task::spawn_local;
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct User {
    pub id: String,
    pub email: String,
    pub name: String,
    pub status: UserStatus,
    pub roles: Vec<String>,
    pub groups: Vec<String>,
    pub created_at: String,
    pub last_login: Option<String>,
    pub mfa_enabled: bool,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum UserStatus {
    Active,
    Inactive,
    Suspended,
    PendingVerification,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Role {
    pub id: String,
    pub name: String,
    pub description: String,
    pub permissions: Vec<String>,
    pub parent_role: Option<String>,
    pub children: Vec<String>,
    pub level: u32,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Group {
    pub id: String,
    pub name: String,
    pub description: String,
    pub members: Vec<String>,
    pub parent_group: Option<String>,
    pub children: Vec<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Permission {
    pub id: String,
    pub name: String,
    pub description: String,
    pub resource: String,
    pub action: String,
    pub category: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AccessReviewCampaign {
    pub id: String,
    pub name: String,
    pub description: String,
    pub schedule: String,
    pub reviewers: Vec<String>,
    pub status: String,
    pub due_date: String,
}

#[component]
pub fn UsersPage() -> impl IntoView {
    let (active_tab, set_active_tab) = signal("users".to_string());
    let (users, set_users) = signal(Vec::<User>::new());
    let (roles, set_roles) = signal(Vec::<Role>::new());
    let (groups, set_groups) = signal(Vec::<Group>::new());
    let (permissions, set_permissions) = signal(Vec::<Permission>::new());
    let (selected_user, set_selected_user) = signal(None::<User>);
    let (show_user_modal, set_show_user_modal) = signal(false);
    let (show_role_hierarchy, set_show_role_hierarchy) = signal(false);
    let (show_bulk_operations, set_show_bulk_operations) = signal(false);

    // Load initial data
    Effect::new(move |_| {
        spawn_local(async move {
            // Mock data - in real app, fetch from API
            let mock_users = vec![
                User {
                    id: "u1".to_string(),
                    email: "admin@example.com".to_string(),
                    name: "System Admin".to_string(),
                    status: UserStatus::Active,
                    roles: vec!["admin".to_string()],
                    groups: vec!["admins".to_string()],
                    created_at: "2024-01-01".to_string(),
                    last_login: Some("2024-01-15".to_string()),
                    mfa_enabled: true,
                },
                User {
                    id: "u2".to_string(),
                    email: "user@example.com".to_string(),
                    name: "Regular User".to_string(),
                    status: UserStatus::Active,
                    roles: vec!["user".to_string()],
                    groups: vec!["users".to_string()],
                    created_at: "2024-01-10".to_string(),
                    last_login: Some("2024-01-14".to_string()),
                    mfa_enabled: false,
                },
            ];

            let mock_roles = vec![
                Role {
                    id: "admin".to_string(),
                    name: "Administrator".to_string(),
                    description: "Full system access".to_string(),
                    permissions: vec!["*".to_string()],
                    parent_role: None,
                    children: vec!["operator".to_string()],
                    level: 0,
                },
                Role {
                    id: "operator".to_string(),
                    name: "Operator".to_string(),
                    description: "Infrastructure management".to_string(),
                    permissions: vec!["infra:*".to_string()],
                    parent_role: Some("admin".to_string()),
                    children: vec!["user".to_string()],
                    level: 1,
                },
                Role {
                    id: "user".to_string(),
                    name: "User".to_string(),
                    description: "Basic access".to_string(),
                    permissions: vec!["read:*".to_string()],
                    parent_role: Some("operator".to_string()),
                    children: vec![],
                    level: 2,
                },
            ];

            set_users.set(mock_users);
            set_roles.set(mock_roles);
        });
    });

    view! {
        <div class="users-page h-full flex flex-col">
            // Header
            <div class="flex-none border-b border-base-300 p-4">
                <div class="flex items-center justify-between">
                    <h1 class="text-3xl font-bold">"User Management"</h1>
                    <div class="flex gap-2">
                        <button
                            class="btn btn-outline btn-sm"
                            on:click=move |_| set_show_bulk_operations.set(true)
                        >
                            "Bulk Operations"
                        </button>
                        <button
                            class="btn btn-outline btn-sm"
                            on:click=move |_| set_show_role_hierarchy.set(true)
                        >
                            "Role Hierarchy"
                        </button>
                        <button
                            class="btn btn-primary btn-sm"
                            on:click=move |_| {
                                set_selected_user.set(None);
                                set_show_user_modal.set(true);
                            }
                        >
                            "Add User"
                        </button>
                    </div>
                </div>

                // Tab Navigation
                <div class="tabs tabs-boxed mt-4">
                    <a
                        class={move || if active_tab.get() == "users" { "tab tab-active" } else { "tab" }}
                        on:click=move |_| set_active_tab.set("users".to_string())
                    >
                        "Users"
                    </a>
                    <a
                        class={move || if active_tab.get() == "roles" { "tab tab-active" } else { "tab" }}
                        on:click=move |_| set_active_tab.set("roles".to_string())
                    >
                        "Roles"
                    </a>
                    <a
                        class={move || if active_tab.get() == "groups" { "tab tab-active" } else { "tab" }}
                        on:click=move |_| set_active_tab.set("groups".to_string())
                    >
                        "Groups"
                    </a>
                    <a
                        class={move || if active_tab.get() == "permissions" { "tab tab-active" } else { "tab" }}
                        on:click=move |_| set_active_tab.set("permissions".to_string())
                    >
                        "Permissions"
                    </a>
                    <a
                        class={move || if active_tab.get() == "reviews" { "tab tab-active" } else { "tab" }}
                        on:click=move |_| set_active_tab.set("reviews".to_string())
                    >
                        "Access Reviews"
                    </a>
                </div>
            </div>

            // Content Area
            <div class="flex-1 overflow-hidden">
                {move || match active_tab.get().as_str() {
                    "users" => view! { <UsersTab users=users set_selected_user=set_selected_user set_show_user_modal=set_show_user_modal /> }.into(),
                    "roles" => view! { <RolesTab roles=roles /> }.into(),
                    "groups" => view! { <GroupsTab groups=groups /> }.into(),
                    "permissions" => view! { <PermissionsTab permissions=permissions /> }.into(),
                    "reviews" => view! { <AccessReviewsTab /> }.into(),
                    _ => view! { <div>"Unknown tab"</div> }.into(),
                }}
            </div>

            // User Modal
            {move || if show_user_modal.get() {
                view! {
                    <UserModal
                        user=selected_user
                        show=show_user_modal
                        set_show=set_show_user_modal
                        roles=roles.get()
                        groups=groups.get()
                    />
                }.into()
            } else {
                view! { <div></div> }.into()
            }}

            // Role Hierarchy Modal
            {move || if show_role_hierarchy.get() {
                view! {
                    <RoleHierarchyModal
                        roles=roles.get()
                        show=show_role_hierarchy
                        set_show=set_show_role_hierarchy
                    />
                }.into()
            } else {
                view! { <div></div> }.into()
            }}

            // Bulk Operations Modal
            {move || if show_bulk_operations.get() {
                view! {
                    <BulkOperationsModal
                        show=show_bulk_operations
                        set_show=set_show_bulk_operations
                    />
                }.into()
            } else {
                view! { <div></div> }.into()
            }}
        </div>
    }
}

#[component]
fn UsersTab(
    users: ReadSignal<Vec<User>>,
    set_selected_user: WriteSignal<Option<User>>,
    set_show_user_modal: WriteSignal<bool>,
) -> impl IntoView {
    let (search_term, set_search_term) = signal(String::new());
    let (status_filter, set_status_filter) = signal("all".to_string());

    let filtered_users = Memo::new(move |_| {
        let search = search_term.get().to_lowercase();
        let status = status_filter.get();

        users.get().into_iter().filter(|user| {
            let matches_search = search.is_empty() ||
                user.name.to_lowercase().contains(&search) ||
                user.email.to_lowercase().contains(&search);

            let matches_status = status == "all" ||
                format!("{:?}", user.status).to_lowercase() == status;

            matches_search && matches_status
        }).collect::<Vec<_>>()
    });

    view! {
        <div class="p-4 h-full flex flex-col">
            // Search and Filters
            <div class="flex-none mb-4 flex gap-4 items-center">
                <div class="flex-1">
                    <input
                        type="text"
                        placeholder="Search users..."
                        class="input input-bordered w-full"
                        prop:value=move || search_term.get()
                        on:input=move |ev| set_search_term.set(event_target_value(&ev))
                    />
                </div>
                <select
                    class="select select-bordered"
                    on:change=move |ev| set_status_filter.set(event_target_value(&ev))
                >
                    <option value="all">"All Status"</option>
                    <option value="active">"Active"</option>
                    <option value="inactive">"Inactive"</option>
                    <option value="suspended">"Suspended"</option>
                    <option value="pendingverification">"Pending"</option>
                </select>
            </div>

            // Users Table
            <div class="flex-1 overflow-auto">
                <table class="table table-zebra w-full">
                    <thead>
                        <tr>
                            <th>"Name"</th>
                            <th>"Email"</th>
                            <th>"Status"</th>
                            <th>"Roles"</th>
                            <th>"MFA"</th>
                            <th>"Last Login"</th>
                            <th>"Actions"</th>
                        </tr>
                    </thead>
                    <tbody>
                        {move || {
                            filtered_users.get().into_iter().map(|user| {
                                let user_clone = user.clone();
                                let user_clone2 = user.clone();
                                view! {
                                    <tr>
                                        <td class="font-medium">{&user.name}</td>
                                        <td>{&user.email}</td>
                                        <td>
                                            <div class={format!("badge {}",
                                                match user.status {
                                                    UserStatus::Active => "badge-success",
                                                    UserStatus::Inactive => "badge-warning",
                                                    UserStatus::Suspended => "badge-error",
                                                    UserStatus::PendingVerification => "badge-info",
                                                }
                                            )}>
                                                {format!("{:?}", user.status)}
                                            </div>
                                        </td>
                                        <td>
                                            <div class="flex gap-1 flex-wrap">
                                                {user.roles.into_iter().map(|role| {
                                                    view! {
                                                        <div class="badge badge-outline badge-sm">{role}</div>
                                                    }
                                                }).collect::<Vec<_>>()}
                                            </div>
                                        </td>
                                        <td>
                                            {if user.mfa_enabled {
                                                view! { <div class="badge badge-success">"Enabled"</div> }
                                            } else {
                                                view! { <div class="badge badge-warning">"Disabled"</div> }
                                            }}
                                        </td>
                                        <td class="text-sm text-base-content/70">
                                            {user.last_login.unwrap_or_else(|| "Never".to_string())}
                                        </td>
                                        <td>
                                            <div class="flex gap-2">
                                                <button
                                                    class="btn btn-ghost btn-xs"
                                                    on:click=move |_| {
                                                        set_selected_user.set(Some(user_clone.clone()));
                                                        set_show_user_modal.set(true);
                                                    }
                                                >
                                                    "Edit"
                                                </button>
                                                <button class="btn btn-ghost btn-xs text-error">
                                                    "Delete"
                                                </button>
                                            </div>
                                        </td>
                                    </tr>
                                }
                            }).collect::<Vec<_>>()
                        }}
                    </tbody>
                </table>
            </div>
        </div>
    }
}

#[component]
fn RolesTab(roles: ReadSignal<Vec<Role>>) -> impl IntoView {
    view! {
        <div class="p-4 h-full">
            <div class="mb-4">
                <button class="btn btn-primary btn-sm">"Add Role"</button>
            </div>

            <div class="grid gap-4">
                {move || {
                    roles.get().into_iter().map(|role| {
                        view! {
                            <div class="card bg-base-200 p-4">
                                <div class="flex items-start justify-between">
                                    <div>
                                        <h3 class="font-semibold">{&role.name}</h3>
                                        <p class="text-sm text-base-content/70 mt-1">{&role.description}</p>
                                        <div class="mt-2">
                                            <span class="text-xs font-medium">"Permissions: "</span>
                                            <div class="flex gap-1 flex-wrap mt-1">
                                                {role.permissions.into_iter().map(|perm| {
                                                    view! {
                                                        <div class="badge badge-outline badge-xs">{perm}</div>
                                                    }
                                                }).collect::<Vec<_>>()}
                                            </div>
                                        </div>
                                        {role.parent_role.as_ref().map(|parent| {
                                            view! {
                                                <div class="mt-2 text-xs">
                                                    "Inherits from: "
                                                    <span class="badge badge-ghost badge-xs">{parent}</span>
                                                </div>
                                            }
                                        })}
                                    </div>
                                    <div class="flex gap-2">
                                        <button class="btn btn-ghost btn-xs">"Edit"</button>
                                        <button class="btn btn-ghost btn-xs text-error">"Delete"</button>
                                    </div>
                                </div>
                            </div>
                        }
                    }).collect::<Vec<_>>()
                }}
            </div>
        </div>
    }
}

#[component]
fn GroupsTab(groups: ReadSignal<Vec<Group>>) -> impl IntoView {
    view! {
        <div class="p-4">
            <div class="text-center text-base-content/50 mt-8">
                "Group management coming soon..."
            </div>
        </div>
    }
}

#[component]
fn PermissionsTab(permissions: ReadSignal<Vec<Permission>>) -> impl IntoView {
    view! {
        <div class="p-4">
            <PermissionMatrix />
        </div>
    }
}

#[component]
fn AccessReviewsTab() -> impl IntoView {
    view! {
        <div class="p-4">
            <div class="mb-4">
                <button class="btn btn-primary btn-sm">"Create Campaign"</button>
            </div>
            <div class="text-center text-base-content/50 mt-8">
                "Access review campaigns coming soon..."
            </div>
        </div>
    }
}

#[component]
fn UserModal(
    user: ReadSignal<Option<User>>,
    show: ReadSignal<bool>,
    set_show: WriteSignal<bool>,
    roles: Vec<Role>,
    groups: Vec<Group>,
) -> impl IntoView {
    let (name, set_name) = signal(String::new());
    let (email, set_email) = signal(String::new());
    let (selected_roles, set_selected_roles) = signal(Vec::<String>::new());

    Effect::new(move |_| {
        if let Some(u) = user.get() {
            set_name.set(u.name);
            set_email.set(u.email);
            set_selected_roles.set(u.roles);
        } else {
            set_name.set(String::new());
            set_email.set(String::new());
            set_selected_roles.set(Vec::new());
        }
    });

    view! {
        <div class={move || if show.get() { "modal modal-open" } else { "modal" }}>
            <div class="modal-box w-11/12 max-w-2xl">
                <h3 class="font-bold text-lg">
                    {move || if user.get().is_some() { "Edit User" } else { "Add User" }}
                </h3>

                <div class="py-4 space-y-4">
                    <div>
                        <label class="label">"Name"</label>
                        <input
                            type="text"
                            class="input input-bordered w-full"
                            prop:value=move || name.get()
                            on:input=move |ev| set_name.set(event_target_value(&ev))
                        />
                    </div>

                    <div>
                        <label class="label">"Email"</label>
                        <input
                            type="email"
                            class="input input-bordered w-full"
                            prop:value=move || email.get()
                            on:input=move |ev| set_email.set(event_target_value(&ev))
                        />
                    </div>

                    <div>
                        <label class="label">"Roles"</label>
                        <div class="space-y-2">
                            {roles.into_iter().map(|role| {
                                let role_id = role.id.clone();
                                view! {
                                    <label class="label cursor-pointer justify-start gap-2">
                                        <input
                                            type="checkbox"
                                            class="checkbox"
                                            prop:checked=move || selected_roles.get().contains(&role_id)
                                            on:change=move |_| {
                                                let mut current = selected_roles.get();
                                                if current.contains(&role_id) {
                                                    current.retain(|r| r != &role_id);
                                                } else {
                                                    current.push(role_id.clone());
                                                }
                                                set_selected_roles.set(current);
                                            }
                                        />
                                        <span class="label-text">{&role.name}</span>
                                        <span class="text-xs text-base-content/50">{"("}{&role.description}{")"}</span>
                                    </label>
                                }
                            }).collect::<Vec<_>>()}
                        </div>
                    </div>
                </div>

                <div class="modal-action">
                    <button
                        class="btn"
                        on:click=move |_| set_show.set(false)
                    >
                        "Cancel"
                    </button>
                    <button class="btn btn-primary">"Save"</button>
                </div>
            </div>
        </div>
    }
}

#[component]
fn RoleHierarchyModal(
    roles: Vec<Role>,
    show: ReadSignal<bool>,
    set_show: WriteSignal<bool>,
) -> impl IntoView {
    view! {
        <div class={move || if show.get() { "modal modal-open" } else { "modal" }}>
            <div class="modal-box w-11/12 max-w-4xl">
                <div class="flex justify-between items-center mb-4">
                    <h3 class="font-bold text-lg">"Role Hierarchy"</h3>
                    <button
                        class="btn btn-ghost btn-sm"
                        on:click=move |_| set_show.set(false)
                    >
                        "✕"
                    </button>
                </div>

                <div class="py-4">
                    <RoleHierarchyViewer roles=roles />
                </div>
            </div>
        </div>
    }
}

#[component]
fn RoleHierarchyViewer(roles: Vec<Role>) -> impl IntoView {
    // Sort roles by level for hierarchy display
    let mut sorted_roles = roles;
    sorted_roles.sort_by_key(|r| r.level);

    view! {
        <div class="space-y-4">
            {sorted_roles.into_iter().map(|role| {
                let indent = role.level * 24; // 24px per level
                view! {
                    <div class="flex items-center" style={format!("margin-left: {}px", indent)}>
                        <div class="w-4 h-4 border-2 border-primary rounded mr-3"></div>
                        <div class="flex-1">
                            <div class="font-medium">{&role.name}</div>
                            <div class="text-sm text-base-content/70">{&role.description}</div>
                            <div class="flex gap-1 mt-1">
                                {role.permissions.into_iter().take(3).map(|perm| {
                                    view! {
                                        <div class="badge badge-outline badge-xs">{perm}</div>
                                    }
                                }).collect::<Vec<_>>()}
                                {if role.permissions.len() > 3 {
                                    view! {
                                        <div class="badge badge-ghost badge-xs">
                                            {"+"}{role.permissions.len() - 3}{" more"}
                                        </div>
                                    }.into()
                                } else {
                                    view! { <div></div> }.into()
                                }}
                            </div>
                        </div>
                        <div class="flex gap-2">
                            <button class="btn btn-ghost btn-xs">"Edit"</button>
                        </div>
                    </div>
                }
            }).collect::<Vec<_>>()}
        </div>
    }
}

#[component]
fn PermissionMatrix() -> impl IntoView {
    let resources = vec!["Users", "Roles", "Infrastructure", "Workflows", "Policies"];
    let actions = vec!["Read", "Write", "Delete", "Execute", "Admin"];
    let roles = vec!["Admin", "Operator", "User"];

    view! {
        <div class="overflow-auto">
            <table class="table table-zebra table-compact w-full">
                <thead>
                    <tr>
                        <th>"Resource"</th>
                        <th>"Action"</th>
                        {roles.iter().map(|role| {
                            let role = role.clone();
                            view! { <th>{role}</th> }
                        }).collect::<Vec<_>>()}
                    </tr>
                </thead>
                <tbody>
                    {resources.into_iter().flat_map(|resource| {
                        actions.iter().map({
                            let resource = resource.clone();
                            move |action| {
                                view! {
                                    <tr>
                                        <td>{&resource}</td>
                                        <td>{action}</td>
                                        {roles.iter().map(|role| {
                                            let role = role.clone();
                                            view! {
                                                <td>
                                                    <input type="checkbox" class="checkbox checkbox-xs" />
                                                </td>
                                            }
                                        }).collect::<Vec<_>>()}
                                    </tr>
                                }
                            }
                        }).collect::<Vec<_>>()
                    }).collect::<Vec<_>>()}
                </tbody>
            </table>
        </div>
    }
}

#[component]
fn BulkOperationsModal(
    show: ReadSignal<bool>,
    set_show: WriteSignal<bool>,
) -> impl IntoView {
    let (operation_type, set_operation_type) = signal("import".to_string());

    view! {
        <div class={move || if show.get() { "modal modal-open" } else { "modal" }}>
            <div class="modal-box">
                <div class="flex justify-between items-center mb-4">
                    <h3 class="font-bold text-lg">"Bulk Operations"</h3>
                    <button
                        class="btn btn-ghost btn-sm"
                        on:click=move |_| set_show.set(false)
                    >
                        "✕"
                    </button>
                </div>

                <div class="py-4 space-y-4">
                    <div>
                        <label class="label">"Operation Type"</label>
                        <select
                            class="select select-bordered w-full"
                            on:change=move |ev| set_operation_type.set(event_target_value(&ev))
                        >
                            <option value="import">"Import Users"</option>
                            <option value="export">"Export Users"</option>
                            <option value="bulk_update">"Bulk Update"</option>
                            <option value="bulk_delete">"Bulk Delete"</option>
                        </select>
                    </div>

                    {move || match operation_type.get().as_str() {
                        "import" => view! {
                            <div>
                                <label class="label">"CSV File"</label>
                                <input type="file" class="file-input file-input-bordered w-full" accept=".csv" />
                                <div class="text-sm text-base-content/70 mt-2">
                                    "Expected format: name,email,roles (comma-separated)"
                                </div>
                            </div>
                        }.into(),
                        "export" => view! {
                            <div>
                                <label class="label cursor-pointer">
                                    <input type="checkbox" class="checkbox" />
                                    <span class="label-text">"Include sensitive data"</span>
                                </label>
                                <label class="label cursor-pointer">
                                    <input type="checkbox" class="checkbox" />
                                    <span class="label-text">"Include inactive users"</span>
                                </label>
                            </div>
                        }.into(),
                        _ => view! { <div>"Operation settings..."</div> }.into(),
                    }}
                </div>

                <div class="modal-action">
                    <button
                        class="btn"
                        on:click=move |_| set_show.set(false)
                    >
                        "Cancel"
                    </button>
                    <button class="btn btn-primary">"Execute"</button>
                </div>
            </div>
        </div>
    }
}
