import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:http/http.dart' as http; import 'package:html/parser.dart' as html_parser; import 'package:inventory_system/services/api_service.dart'; import 'package:inventory_system/services/session_manager.dart'; class AuthService { Future> signIn({ required String usernameOrEmail, required String password, }) async { if (usernameOrEmail.toLowerCase() == 'admin@pstw.com.my') { return _performAdminWebLogin(usernameOrEmail, password); } else { return _performLdapApiLogin(usernameOrEmail, password); } } Future> _performLdapApiLogin( String username, String password) async { final Uri loginUri = Uri.parse('${ApiService.baseUrl}/IdentityAPI/LdapLogin'); final loginHeaders = {'Content-Type': 'application/json; charset=UTF-8'}; final loginBody = jsonEncode({'UserName': username, 'Password': password}); try { final response = await http.post(loginUri, headers: loginHeaders, body: loginBody); if (response.statusCode != 200) { return _handleLdapError(response); } final String? sessionCookie = response.headers['set-cookie']; if (sessionCookie == null) { return {'success': false, 'message': 'Login succeeded, but failed to start a session.'}; } SessionManager.instance.setCookie(sessionCookie); return await _fetchLdapUserDetails(sessionCookie, username); } on TimeoutException { return {'success': false, 'message': 'The connection timed out. Please try again.'}; } on SocketException { return {'success': false, 'message': 'Could not connect to the server. Please check your network.'}; } catch (e) { debugPrint('An unexpected error occurred during LDAP login: $e'); return {'success': false, 'message': 'An unexpected error occurred.'}; } } Future> _fetchLdapUserDetails(String sessionCookie, String username) async { final Uri userInfoUri = Uri.parse('${ApiService.baseUrl}/IdentityAPI/GetUserInformation'); final headers = {'Cookie': sessionCookie}; try { final response = await http.post(userInfoUri, headers: headers); if (response.statusCode == 200) { final userInfoResponse = jsonDecode(response.body); final Map? userData = userInfoResponse['userInfo']; if (userData == null) { return {'success': false, 'message': 'User profile data is missing from the API response.'}; } final List roles = userData['role'] ?? []; final bool isInventoryMaster = roles.contains('Inventory Master'); final bool isSuperAdmin = roles.contains('Super Admin'); final Map sessionData = Map.from(userData); sessionData['fullName'] = username; sessionData['isAdmin'] = isInventoryMaster || isSuperAdmin; sessionData['isInventoryMaster'] = isInventoryMaster; sessionData['isSuperAdmin'] = isSuperAdmin; sessionData['role'] = roles; return { 'success': true, 'data': sessionData }; } else { return {'success': false, 'message': 'Logged in, but failed to retrieve user profile.'}; } } catch (e) { return {'success': false, 'message': 'Error fetching user details after login.'}; } } Map _handleLdapError(http.Response response) { try { final errorData = jsonDecode(response.body); String errorMessage = errorData['message'] ?? 'An unknown error occurred'; if (errorMessage.toLowerCase().contains('was not found')) { return {'success': false, 'message': 'Wrong username or email.'}; } else if (errorMessage.toLowerCase().contains('incorrect password.')) { return {'success': false, 'message': 'Wrong password.'}; } else { return {'success': false, 'message': errorMessage}; } } catch (e) { return {'success': false, 'message': 'Login failed with status: ${response.statusCode}'}; } } Future> _performAdminWebLogin( String email, String password) async { final Uri loginUri = Uri.parse('${ApiService.baseUrl}/Identity/Account/Login'); try { final getResponse = await http.get(loginUri); final String? sessionCookie = getResponse.headers['set-cookie']; final document = html_parser.parse(getResponse.body); final token = document.querySelector('input[name="__RequestVerificationToken"]')?.attributes['value']; if (sessionCookie == null || token == null) { return {'success': false, 'message': 'Failed to prepare a secure login session.'}; } SessionManager.instance.setCookie(sessionCookie); final postResponse = await http.post( loginUri, headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Cookie': sessionCookie, }, body: { 'Email': email, 'Password': password, 'RememberMe': 'false', '__RequestVerificationToken': token, }, ); if (postResponse.statusCode == 302) { // After a successful login, the server issues a new, authenticated cookie. // We must capture and save this new cookie from the POST response. final String? newSessionCookie = postResponse.headers['set-cookie']; if (newSessionCookie != null) { SessionManager.instance.setCookie(newSessionCookie); } return { 'success': true, 'data': { 'fullName': 'Super Admin', 'isAdmin': true, 'isInventoryMaster': false, 'isSuperAdmin': true, 'role': ['Super Admin'], } }; } else { return {'success': false, 'message': 'Admin login failed. Please check credentials.'}; } } catch (e) { debugPrint('An unexpected error occurred during Admin login: $e'); return {'success': false, 'message': 'An unexpected error occurred.'}; } } }