use gloo_storage::{LocalStorage, Storage};
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
pub enum AuthState {
    #[default]
    Unauthenticated,
    Authenticating,
    Authenticated {
        user: User,
        token: String,
    },
    Error(String),
}

impl AuthState {
    pub fn is_authenticated(&self) -> bool {
        matches!(self, AuthState::Authenticated { .. })
    }

    pub fn is_loading(&self) -> bool {
        matches!(self, AuthState::Authenticating)
    }

    pub fn get_user(&self) -> Option<&User> {
        match self {
            AuthState::Authenticated { user, .. } => Some(user),
            _ => None,
        }
    }

    pub fn get_token(&self) -> Option<&str> {
        match self {
            AuthState::Authenticated { token, .. } => Some(token),
            _ => None,
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct User {
    pub id: String,
    pub username: String,
    pub email: String,
    pub roles: Vec<String>,
    pub avatar_url: Option<String>,
    pub created_at: String,
    pub last_login: Option<String>,
}

// Token storage utilities
const TOKEN_KEY: &str = "auth_token";
const USER_KEY: &str = "user_info";

pub fn save_auth_token(token: &str) {
    let _ = LocalStorage::set(TOKEN_KEY, token);
}

pub fn get_auth_token() -> Option<String> {
    LocalStorage::get(TOKEN_KEY).ok()
}

pub fn remove_auth_token() {
    LocalStorage::delete(TOKEN_KEY);
}

pub fn save_user_info(user: &User) {
    let _ = LocalStorage::set(USER_KEY, user);
}

pub fn get_user_info() -> Option<User> {
    LocalStorage::get(USER_KEY).ok()
}

pub fn remove_user_info() {
    LocalStorage::delete(USER_KEY);
}

pub fn clear_auth_storage() {
    remove_auth_token();
    remove_user_info();
}
