import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:inventory_system/services/api_service.dart';
import 'package:inventory_system/services/session_manager.dart'; // Import SessionManager
import 'package:inventory_system/services/user_service.dart';

class ProductRequestService {
  Future<List<Map<String, dynamic>>> fetchProductRequests() async {
    final currentUser = SessionManager.instance.currentUser;

    if (currentUser == null) {
      throw Exception('User session not found.');
    }

    final userId = currentUser['id'];
    final currentUserRoles = currentUser['role'] as List<dynamic>? ?? [];
    List<Map<String, dynamic>> requests = [];

    try {
      if (currentUserRoles.contains("Super Admin") || currentUserRoles.contains("System Admin")) {
        // Admins see all requests
        final url = Uri.parse('${ApiService.baseUrl}/InvMainAPI/ItemRequestList');
        final response = await http.get(url);

        if (response.statusCode == 200) {
          requests = json.decode(response.body).cast<Map<String, dynamic>>();
        } else {
          throw Exception('Failed to load product requests for Admin: ${response.statusCode}');
        }
      } else if (currentUserRoles.contains("Inventory Master")) {
        // Inventory Masters: get their stores, then filter all requests
        final storesUrl = Uri.parse('${ApiService.baseUrl}/InvMainAPI/StoreSpecificMasterList/$userId');
        final storesResponse = await http.post(storesUrl); // StoreSpecificMasterList is a POST method

        if (storesResponse.statusCode != 200) {
          throw Exception('Failed to load managed stores for Inventory Master: ${storesResponse.statusCode}');
        }
        
        // Parse the response to get a list of store IDs.
        // Assuming the response is a list of store objects, and each has an 'id' field
        final List<dynamic> storeJson = json.decode(storesResponse.body);
        final List<int> managedStoreIds = storeJson.map((store) => store['id'] as int).toList();

        // Prepare Department Mapping
        final userService = UserService();
        final allUsers = await userService.fetchUsers();
        final userDeptMap = {
          for (var u in allUsers)
            if (u['id'] != null && u['department'] != null)
              u['id']: u['department']['departmentId']
        };
        final currentUserDepartmentId = currentUser['department']?['departmentId'];

        final allRequestsUrl = Uri.parse('${ApiService.baseUrl}/InvMainAPI/ItemRequestList');
        final allRequestsResponse = await http.get(allRequestsUrl);

        if (allRequestsResponse.statusCode == 200) {
          final List<dynamic> allJsonRequests = json.decode(allRequestsResponse.body);
          // Filter requests where assignStoreItem or fromStoreItem matches managedStoreIds, OR if it is a technician request (assignStoreItem is null)
          requests = allJsonRequests
              .cast<Map<String, dynamic>>()
              .where((r) {
                final assignStoreItem = r['assignStoreItem'] as int?;
                final fromStoreItem = r['fromStoreItem'] as int?;
                
                final storeMatch = (assignStoreItem != null && managedStoreIds.contains(assignStoreItem)) ||
                       (fromStoreItem != null && managedStoreIds.contains(fromStoreItem)) ||
                       (assignStoreItem == null || assignStoreItem == 0);
                
                final requestUserId = r['userId'];
                final requestUserDept = userDeptMap[requestUserId];
                final deptMatch = (currentUserDepartmentId != null && requestUserDept == currentUserDepartmentId);

                return storeMatch && deptMatch;
              })
              .toList();
        } else {
          throw Exception('Failed to load all product requests for Inventory Master: ${allRequestsResponse.statusCode}');
        }
      } else {
        // Standard users: fetch only their requests
        final url = Uri.parse('${ApiService.baseUrl}/InvMainAPI/ItemRequestListEachUser/$userId');
        final response = await http.get(url);

        if (response.statusCode == 200) {
          requests = json.decode(response.body).cast<Map<String, dynamic>>();
        } else {
          throw Exception('Failed to load product requests for user $userId: ${response.statusCode}');
        }
      }
      return requests;
    } catch (e) {
      throw Exception('Failed to connect to the server or process requests: $e');
    }
  }

  Future<bool> approveRequest(int requestId, String remarkMasterInv) async {
    final url = Uri.parse('${ApiService.baseUrl}/InvMainAPI/ApproveRequest/$requestId');
    try {
      final response = await http.post(
        url,
        headers: {'Content-Type': 'application/json'},
        body: json.encode({'remarkMasterInv': remarkMasterInv}),
      );

      if (response.statusCode == 200) {
        return true;
      } else {
        throw Exception('Failed to approve request: ${response.statusCode}');
      }
    } catch (e) {
      throw Exception('Failed to connect to the server: $e');
    }
  }

  Future<bool> rejectRequest(int requestId, String remarkMasterInv) async {
    final url = Uri.parse(
        '${ApiService.baseUrl}/InvMainAPI/RejectRequest/$requestId');
    try {
      final response = await http.post(
        url,
        headers: {'Content-Type': 'application/json'},
        body: json.encode({'remarkMasterInv': remarkMasterInv}),
      );

      if (response.statusCode == 200) {
        return true;
      } else {
        throw Exception('Failed to reject request: ${response.statusCode}');
      }
    } catch (e) {
      throw Exception('Failed to connect to the server: $e');
    }
  }

  Future<bool> addRequestMaster(Map<String, dynamic> requestData) async {
    final url = Uri.parse('${ApiService.baseUrl}/InvMainAPI/AddRequestMaster');
    final cookie = SessionManager.instance.getCookie();

    try {
      final response = await http.post(
        url,
        headers: {
          'Content-Type': 'application/json',
          if (cookie != null) 'Cookie': cookie,
        },
        body: json.encode(requestData),
      );

      if (response.statusCode == 200) {
        return true;
      } else {
        throw Exception(
            'Failed to submit request: ${response.statusCode} - ${response
                .body}');
      }
    } catch (e) {
      throw Exception('Failed to connect to the server: $e');
    }
  }

  Future<bool> addRequest(Map<String, dynamic> requestData) async {
    final url = Uri.parse('${ApiService.baseUrl}/InvMainAPI/AddRequest');
    final cookie = SessionManager.instance.getCookie();

    try {
      final response = await http.post(
        url,
        headers: {
          'Content-Type': 'application/json',
          if (cookie != null) 'Cookie': cookie,
        },
        body: json.encode(requestData),
      );

      if (response.statusCode == 200) {
        return true;
      } else {
        throw Exception('Failed to submit request: ${response.statusCode} - ${response.body}');
      }
    } catch (e) {
      throw Exception('Failed to connect to the server: $e');
    }
  }
  
  Future<bool> deleteRequest(int requestId) async {
    final url = Uri.parse('${ApiService.baseUrl}/InvMainAPI/DeleteRequest/$requestId');
    try {
      final response = await http.delete(url);

      if (response.statusCode == 200) {
        return true;
      } else {
        throw Exception('Failed to delete request: ${response.statusCode} - ${response.body}');
      }
    } catch (e) {
      throw Exception('Failed to connect to the server: $e');
    }
  }
}
