/// Model representing a site request with all necessary information
/// Supports three request types: Add Site, Change Site, and Remove Site
class SiteRequestModel {
  final String? id;
  final String requestType;
  final String? requestNumber;
  final String employeeId;
  final String fullName;
  final String emailAddress;
  final String mobileNumber;
  final String? extensionNumber;
  final String? returnReason;
  final List<String> siteIds;
  final List<String> siteNames;
  final List<String>? oldSiteIds; // For Change Site request
  final List<String>? oldSiteNames; // For Change Site request
  final List<String>? departmentIds;
  final List<String>? departmentNames;
  final List<String>? oldDepartmentIds; // For Change Site request - old departments
  final List<String>? oldDepartmentNames; // For Change Site request - old departments
  final String role;
  final String ?status; // Pending, Approved, Rejected
  final DateTime? requestDate;

  SiteRequestModel({
    this.id,
    required this.requestType,
     this.requestNumber,
    required this.employeeId,
    required this.fullName,
    required this.emailAddress,
    required this.mobileNumber,
    this.extensionNumber,
    required this.siteIds,
    required this.siteNames,
    this.oldSiteIds,
    this.oldSiteNames,
    this.departmentIds,
    this.departmentNames,
    this.oldDepartmentIds,
    this.oldDepartmentNames,
    required this.role,
     this.status,
     this.returnReason,
    this.requestDate,
  });

  /// Converts model to JSON for API submission
  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'requestType': requestType,
      'requestNumber': requestNumber,
      'employeeId': employeeId,
      'fullName': fullName,
      'emailAddress': emailAddress,
      'mobileNumber': mobileNumber,
      'extensionNumber': extensionNumber,
      'siteIds': siteIds,
      'siteNames': siteNames,
      'oldSiteIds': oldSiteIds,
      'oldSiteNames': oldSiteNames,
      'departmentIds': departmentIds,
      'departmentNames': departmentNames,
      'role': role,
      // 'status': status,
      // 'requestDate': requestDate?.toIso8601String(),
    };
  }

  /// Creates model from API response JSON
  factory SiteRequestModel.fromJson(Map<String, dynamic> json) {
    final sitesData = _parseSitesFromJson(json);
    final departmentsData = _parseDepartmentsFromJson(json);

    return SiteRequestModel(
      id: json['id']?.toString() ?? json['requestNumber']?.toString() ?? '',
      requestType: _parseRequestType(json),
      employeeId: json['employeeId'] ?? '',
      requestNumber: json['requestNumber'] ?? '',
      fullName: json['userName'] ?? json['fullName'] ?? '',
      emailAddress: json['email'] ?? json['emailAddress'] ?? '',
      mobileNumber: json['mobileNumber'] ?? '',
      extensionNumber: json['extensionNo'] ?? json['extensionNumber'],
      siteIds: sitesData['siteIds'],
      returnReason: json['returnReason'],
      siteNames: sitesData['siteNames'],
      oldSiteIds: sitesData['oldSiteIds'],
      oldSiteNames: sitesData['oldSiteNames'],
      departmentIds: departmentsData['departmentIds'],
      departmentNames: departmentsData['departmentNames'],
      oldDepartmentIds: departmentsData['oldDepartmentIds'],
      oldDepartmentNames: departmentsData['oldDepartmentNames'],
      role: json['role'] ?? '',
      status: _parseStatus(json),
      requestDate: _parseDate(json),
    );
  }

  /// Creates a copy with optional field updates
  SiteRequestModel copyWith({
    String? id,
    String? requestType,
    String? employeeId,
    String? fullName,
    String? emailAddress,
    String? mobileNumber,
    String? extensionNumber,
    String? returnReason,
    List<String>? siteIds,
    List<String>? siteNames,
    List<String>? oldSiteIds,
    List<String>? oldSiteNames,
    List<String>? departmentIds,
    List<String>? departmentNames,
    String? role,
    String? status,
    DateTime? requestDate,
  }) {
    return SiteRequestModel(
      id: id ?? this.id,
      requestType: requestType ?? this.requestType,
      requestNumber: requestNumber ?? this.requestNumber,
      employeeId: employeeId ?? this.employeeId,
      fullName: fullName ?? this.fullName,
      emailAddress: emailAddress ?? this.emailAddress,
      mobileNumber: mobileNumber ?? this.mobileNumber,
      extensionNumber: extensionNumber ?? this.extensionNumber,
      siteIds: siteIds ?? this.siteIds,
      siteNames: siteNames ?? this.siteNames,
      oldSiteIds: oldSiteIds ?? this.oldSiteIds,
      oldSiteNames: oldSiteNames ?? this.oldSiteNames,
      departmentIds: departmentIds ?? this.departmentIds,
      departmentNames: departmentNames ?? this.departmentNames,
      role: role ?? this.role,
      status: status ?? this.status,
      returnReason: returnReason ?? this.returnReason,
      requestDate: requestDate ?? this.requestDate,
    );
  }

  // Private helper methods for parsing

  static Map<String, dynamic> _parseSitesFromJson(Map<String, dynamic> json) {
    List<String> siteIds = [];
    List<String> siteNames = [];
    List<String>? oldSiteIds;
    List<String>? oldSiteNames;

    if (json['sites'] != null && json['sites'] is List) {
      for (var site in json['sites']) {
        siteIds.add(site['siteId']?.toString() ?? '');
        siteNames.add(site['siteName'] ?? '');

        if (site['oldSiteId'] != null && site['oldSiteId'] != 0) {
          oldSiteIds ??= [];
          oldSiteNames ??= [];
          oldSiteIds.add(site['oldSiteId']?.toString() ?? '');
          oldSiteNames.add(site['oldSitName'] ?? '');
        }
      }
    }

    return {
      'siteIds': siteIds,
      'siteNames': siteNames,
      'oldSiteIds': oldSiteIds,
      'oldSiteNames': oldSiteNames,
    };
  }

  static Map<String, List<String>?> _parseDepartmentsFromJson(Map<String, dynamic> json) {
    List<String>? departmentIds;
    List<String>? departmentNames;
    List<String>? oldDepartmentIds;
    List<String>? oldDepartmentNames;

    // Check if departments are nested within sites array
    if (json['sites'] != null && json['sites'] is List) {
      for (var site in json['sites']) {
        if (site['departments'] != null && site['departments'] is List) {
          for (var dept in site['departments']) {
            departmentIds ??= [];
            departmentNames ??= [];
            departmentIds.add(dept['departmentId']?.toString() ?? '');
            departmentNames.add(dept['departmentName'] ?? '');

            // Check for old department data in Change Site requests
            if (dept['oldDepartmentId'] != null && dept['oldDepartmentId'] != 0) {
              oldDepartmentIds ??= [];
              oldDepartmentNames ??= [];
              oldDepartmentIds.add(dept['oldDepartmentId']?.toString() ?? '');
              oldDepartmentNames.add(dept['oldDepartmentName'] ?? '');
            }
          }
        }
      }
    }
    // Fallback: check if departments are at root level (for backward compatibility)
    else if (json['departments'] != null &&
        json['departments'] is List &&
        (json['departments'] as List).isNotEmpty) {
      departmentIds = [];
      departmentNames = [];
      for (var dept in json['departments']) {
        departmentIds.add(dept['departmentId']?.toString() ?? '');
        departmentNames.add(dept['departmentName'] ?? '');

        // Check for old department data in Change Site requests
        if (dept['oldDepartmentId'] != null && dept['oldDepartmentId'] != 0) {
          oldDepartmentIds ??= [];
          oldDepartmentNames ??= [];
          oldDepartmentIds.add(dept['oldDepartmentId']?.toString() ?? '');
          oldDepartmentNames.add(dept['oldDepartmentName'] ?? '');
        }
      }
    }

    return {
      'departmentIds': departmentIds,
      'departmentNames': departmentNames,
      'oldDepartmentIds': oldDepartmentIds,
      'oldDepartmentNames': oldDepartmentNames,
    };
  }

  static String _parseRequestType(Map<String, dynamic> json) {
    return json['requestType'] is Map
        ? (json['requestType']['name'] ?? '')
        : (json['requestType'] ?? '');
  }

  static String _parseStatus(Map<String, dynamic> json) {
    return json['status'] is Map
        ? (json['status']['name'] ?? 'Pending')
        : (json['status'] ?? 'Pending');
  }

  static DateTime _parseDate(Map<String, dynamic> json) {
    if (json['createdDate'] != null) {
      return DateTime.parse(json['createdDate']);
    } else if (json['requestDate'] != null) {
      return DateTime.parse(json['requestDate']);
    }
    return DateTime.now();
  }
}
