1
use axum::{Extension, Json, extract::Query, http::StatusCode};
2
use serde::{Deserialize, Serialize};
3

            
4
use crate::jwt_auth::JWTAuthMiddleware;
5

            
6
#[derive(Serialize)]
7
pub struct TagSuggestion {
8
    name: String,
9
    value: Option<String>,
10
}
11

            
12
pub async fn transaction_tag_names(
13
    Extension(jwt_auth): Extension<JWTAuthMiddleware>,
14
) -> Result<Json<Vec<TagSuggestion>>, (StatusCode, Json<serde_json::Value>)> {
15
    let user = &jwt_auth.user;
16
    let server_user = server::user::User { id: user.id };
17

            
18
    match server_user.list_transaction_tag_names().await {
19
        Ok(names) => {
20
            let suggestions = names
21
                .into_iter()
22
                .map(|name| TagSuggestion { name, value: None })
23
                .collect();
24
            Ok(Json(suggestions))
25
        }
26
        Err(e) => {
27
            let error_response = serde_json::json!({
28
                "status": "fail",
29
                "message": "Failed to fetch transaction tag names",
30
            });
31
            log::error!("Failed to fetch transaction tag names: {e:?}");
32
            Err((StatusCode::INTERNAL_SERVER_ERROR, Json(error_response)))
33
        }
34
    }
35
}
36

            
37
#[derive(Deserialize)]
38
pub struct TagValuesQuery {
39
    name: String,
40
}
41

            
42
pub async fn transaction_tag_values(
43
    Query(query): Query<TagValuesQuery>,
44
    Extension(jwt_auth): Extension<JWTAuthMiddleware>,
45
) -> Result<Json<Vec<TagSuggestion>>, (StatusCode, Json<serde_json::Value>)> {
46
    let user = &jwt_auth.user;
47
    let server_user = server::user::User { id: user.id };
48

            
49
    match server_user.list_transaction_tag_values(&query.name).await {
50
        Ok(values) => {
51
            let suggestions = values
52
                .into_iter()
53
                .map(|value| TagSuggestion {
54
                    name: value.clone(),
55
                    value: Some(value),
56
                })
57
                .collect();
58
            Ok(Json(suggestions))
59
        }
60
        Err(e) => {
61
            let error_response = serde_json::json!({
62
                "status": "fail",
63
                "message": "Failed to fetch transaction tag values",
64
            });
65
            log::error!(
66
                "Failed to fetch transaction tag values for '{}': {e:?}",
67
                query.name
68
            );
69
            Err((StatusCode::INTERNAL_SERVER_ERROR, Json(error_response)))
70
        }
71
    }
72
}
73

            
74
pub async fn split_tag_names(
75
    Extension(jwt_auth): Extension<JWTAuthMiddleware>,
76
) -> Result<Json<Vec<TagSuggestion>>, (StatusCode, Json<serde_json::Value>)> {
77
    let user = &jwt_auth.user;
78
    let server_user = server::user::User { id: user.id };
79

            
80
    match server_user.list_split_tag_names().await {
81
        Ok(names) => {
82
            let suggestions = names
83
                .into_iter()
84
                .map(|name| TagSuggestion { name, value: None })
85
                .collect();
86
            Ok(Json(suggestions))
87
        }
88
        Err(e) => {
89
            let error_response = serde_json::json!({
90
                "status": "fail",
91
                "message": "Failed to fetch split tag names",
92
            });
93
            log::error!("Failed to fetch split tag names: {e:?}");
94
            Err((StatusCode::INTERNAL_SERVER_ERROR, Json(error_response)))
95
        }
96
    }
97
}
98

            
99
pub async fn split_tag_values(
100
    Query(query): Query<TagValuesQuery>,
101
    Extension(jwt_auth): Extension<JWTAuthMiddleware>,
102
) -> Result<Json<Vec<TagSuggestion>>, (StatusCode, Json<serde_json::Value>)> {
103
    let user = &jwt_auth.user;
104
    let server_user = server::user::User { id: user.id };
105

            
106
    match server_user.list_split_tag_values(&query.name).await {
107
        Ok(values) => {
108
            let suggestions = values
109
                .into_iter()
110
                .map(|value| TagSuggestion {
111
                    name: value.clone(),
112
                    value: Some(value),
113
                })
114
                .collect();
115
            Ok(Json(suggestions))
116
        }
117
        Err(e) => {
118
            let error_response = serde_json::json!({
119
                "status": "fail",
120
                "message": "Failed to fetch split tag values",
121
            });
122
            log::error!(
123
                "Failed to fetch split tag values for '{}': {e:?}",
124
                query.name
125
            );
126
            Err((StatusCode::INTERNAL_SERVER_ERROR, Json(error_response)))
127
        }
128
    }
129
}