2025-05-29 15:44:23 +02:00

194 lines
6.2 KiB
Dart

import 'package:flutter/cupertino.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:insparkspokalen_ui/models/userModel.dart';
import 'package:insparkspokalen_ui/api_endpoints.dart';
// import 'package:shared_preferences/shared_preferences.dart';
import '../googleAuthService.dart';
import '../image_service.dart';
/// Api docs UserMS
/// https://group-10-15.pvt.dsv.su.se/user/swagger-ui/index.html
class UserService {
late UserModel user;
Future<List<UserModel>> showUsers() async {
try {
final response = await http.get(ApiEndPoints.userAll);
if (response.statusCode == 200) {
final List<dynamic> data = jsonDecode(response.body);
return data.map((json) => UserModel.fromJson(json)).toList();
} else {
return [];
}
} catch (e) {
print("Error fetching users: $e");
return [];
}
}
Future<void> createOrFetchUser(GoogleSignInAccount account) async {
String googleEmail = account.email;
try {
if (await fetchExistingUser(googleEmail)) { // user exists in backend -> set user, check profile picture and return
print("User fetched: ${user.toJson()}");
if (await isDefaultGoogleAvatar(user.profilePicture)) { // if default google profile set random dicebear avatar and update in backend
await updateProfilePicture(user.email, await ImageService().diceStyleToStorageUrl('avataaars-neutral'));
}
GoogleAuthService.setCurrentUser(user); // update locally
print('UserService DEBUG: googleauthuser = ${GoogleAuthService.getCurrentUser()?.teamId}');
return;
}
// User doesn't exist -> create userModel
String? profilePicture =
await (await isDefaultGoogleAvatar(account.photoUrl)
? await ImageService().diceStyleToStorageUrl('avataaars-neutral')
: Future.value(account.photoUrl));
user = UserModel(
googleEmail,
account.displayName ?? 'Unknown',
profilePicture,
0,
);
if (await createUserBackend(user)) {
print("User created: ${user.toJson()}");
GoogleAuthService.setCurrentUser(user);
} else {
throw Exception("Failed to create user in backend");
}
} catch (e) {
print("UserService error: $e");
}
}
/// If user exists in backend the method will,
/// Set this.user to the user from the backend
/// return true
Future<bool> fetchExistingUser(String email) async {
final getUserResponse = await http.get(ApiEndPoints.userGetUserByEmail(email));
if (getUserResponse.statusCode == 200 && getUserResponse.body.isNotEmpty) {
user = UserModel.fromJson(jsonDecode(getUserResponse.body));
print('UserService DEBUG: Fetched user from backend: ${user.toJson()}');
return true;
}
return false;
}
Future<bool> createUserBackend(UserModel user) async {
final getUserResponse = await http.post(
ApiEndPoints.userCreate,
headers: {'Content-Type': 'application/json'},
body: jsonEncode(user.toJson()),
);
user = UserModel.fromJson(jsonDecode(getUserResponse.body));
return getUserResponse.statusCode == 200 || getUserResponse.statusCode == 201;
}
static Future<String> getUserRole(String email) async {
final response = await http.get(ApiEndPoints.userGetRoleByEmail(email));
if (response.statusCode == 200) {
return response.body.replaceAll('"', '').toUpperCase();
} else {
throw Exception("Failed to retrieve role for $email");
}
}
Future<UserModel> getUserByEmail(String email) async {
final response = await http.get(ApiEndPoints.userGetUserByEmail(email));
if (response.statusCode == 200) {
return UserModel.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to load user');
}
}
Future<bool> addTeamToUser(int teamId) async {
user = GoogleAuthService.getCurrentUser()!;
final response = await http.post(
ApiEndPoints.userJoinTeam,
headers: {'Content-Type': 'application/json'},
body: jsonEncode({'email': user?.email, 'teamId': teamId}),
);
bool success = response.statusCode == 200 || response.statusCode == 201;
if (success) {
user.teamId = teamId;
GoogleAuthService.setCurrentUser(user);
}
return success;
}
Future<bool> userResetTeamByEmail(String email) async {
final response = await http.put(ApiEndPoints.userResetTeamByEmail(email));
return response.statusCode == 200 || response.statusCode == 201;
}
Future<String?> fetchProfilePicture(String email) async {
final response = await http.get(ApiEndPoints.userGetProfilePictureByEmail(email));
if (response.statusCode == 200) {
return response.body.replaceAll('"', '');
} else {
return null;
}
}
Future<int?> getUserTeamByEmail(String email) async {
final response = await http.get(ApiEndPoints.userGetTeamByEmail(email));
user = UserModel.fromJson(jsonDecode(response.body));
if (response.statusCode == 200) {
return user?.teamId;
} else {
print('Kunde inte hämta teamId för användare: ${response.statusCode}');
return 0;
}
}
Future<bool> userInTeam(String email) async {
final userTeamId = await getUserTeamByEmail(email);
print('UserService DEBUG: userInTeam: userTeamId = $userTeamId'); // todo remove debug
final bool userInTeam = userTeamId != 0 && userTeamId != null;
return userInTeam;
}
Future<bool> updateProfilePicture(String email, String imageUrl) async {
final response = await http.put(
ApiEndPoints.userChangePictureByEmail(email),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
'imageUrl': imageUrl
}),
);
return response.statusCode == 200;
}
static Future<bool> isDefaultGoogleAvatar(String? photoUrl) async {
if (photoUrl == null || photoUrl.isEmpty) return true;
try {
final response = await http.head(Uri.parse(photoUrl));
final contentType = response.headers['content-type'];
print('Content type: ${contentType == 'image/png'}');
return contentType == 'image/png'; // Defaults are PNG
} catch (e) {
// Fail safe: assume default if request fails
return true;
}
}
}