import 'dart:convert';

class AuditLogEntry {
  final String eventId;
  final DateTime timestamp;
  final String userId;
  final String eventType;
  final String status;
  final String authMethod;
  final String ipAddress;
  final String userAgent;
  final String sessionId;
  final String details;
  final String source;
  final String clientId;
  final String appName;
  final String parentSessionId;

  AuditLogEntry({
    required this.eventId,
    required this.timestamp,
    required this.userId,
    required this.eventType,
    required this.status,
    required this.authMethod,
    required this.ipAddress,
    required this.userAgent,
    required this.sessionId,
    required this.details,
    required this.source,
    required this.clientId,
    required this.appName,
    required this.parentSessionId,
  });

  factory AuditLogEntry.fromJson(Map<String, dynamic> json) {
    final timestampRaw = json['timestamp']?.toString() ?? '';
    DateTime parsedTimestamp;
    try {
      parsedTimestamp = DateTime.parse(timestampRaw).toLocal();
    } catch (_) {
      parsedTimestamp = DateTime.now();
    }

    return AuditLogEntry(
      eventId: json['event_id'] ?? '',
      timestamp: parsedTimestamp,
      userId: json['user_id'] ?? '',
      eventType: json['event_type'] ?? '',
      status: json['status'] ?? '',
      authMethod: json['auth_method'] ?? '',
      ipAddress: json['ip_address'] ?? '',
      userAgent: json['user_agent'] ?? '',
      sessionId: json['session_id'] ?? '',
      details: json['details'] ?? '',
      source: json['source'] ?? '',
      clientId: json['client_id'] ?? '',
      appName: json['app_name'] ?? '',
      parentSessionId: json['parent_session_id'] ?? '',
    );
  }

  Map<String, dynamic> get detailMap {
    if (details.isEmpty) {
      return {};
    }
    try {
      return jsonDecode(details) as Map<String, dynamic>;
    } catch (_) {
      return {};
    }
  }

  String get path {
    final detailPath = detailMap['path']?.toString();
    if (detailPath != null && detailPath.isNotEmpty) {
      return detailPath;
    }
    final parts = eventType.split(' ');
    if (parts.length >= 2) {
      return parts.sublist(1).join(' ');
    }
    return '-';
  }
}

class AuditPage {
  final List<AuditLogEntry> items;
  final String? nextCursor;

  const AuditPage({required this.items, this.nextCursor});
}

class LinkedRp {
  final String id;
  final String name;
  final String logo;
  final String url;
  final String initUrl;
  final bool autoLoginSupported;
  final String autoLoginUrl;
  final String status;
  final List<String> scopes;
  final DateTime? lastAuthenticatedAt;

  LinkedRp({
    required this.id,
    required this.name,
    required this.logo,
    required this.url,
    required this.initUrl,
    required this.autoLoginSupported,
    required this.autoLoginUrl,
    required this.status,
    required this.scopes,
    this.lastAuthenticatedAt,
  });

  factory LinkedRp.fromJson(Map<String, dynamic> json) {
    DateTime? parsedLastAuth;
    final rawLastAuth = json['lastAuthenticatedAt']?.toString();
    if (rawLastAuth != null && rawLastAuth.isNotEmpty) {
      try {
        parsedLastAuth = DateTime.parse(rawLastAuth).toLocal();
      } catch (_) {
        parsedLastAuth = null;
      }
    }

    return LinkedRp(
      id: json['id']?.toString() ?? '',
      name: json['name']?.toString() ?? '',
      logo: json['logo']?.toString() ?? '',
      url: json['url']?.toString() ?? '',
      initUrl: json['init_url']?.toString() ?? '',
      autoLoginSupported: json['auto_login_supported'] == true,
      autoLoginUrl: json['auto_login_url']?.toString() ?? '',
      status: json['status']?.toString() ?? '',
      scopes: (json['scopes'] as List?)?.whereType<String>().toList() ?? [],
      lastAuthenticatedAt: parsedLastAuth,
    );
  }
}

class RpHistoryItem {
  final String clientId;
  final String clientName;
  final List<String> scopes;
  final DateTime? lastApprovedAt;
  final DateTime? lastRevokedAt;
  final String status;

  RpHistoryItem({
    required this.clientId,
    required this.clientName,
    required this.scopes,
    this.lastApprovedAt,
    this.lastRevokedAt,
    required this.status,
  });

  factory RpHistoryItem.fromJson(Map<String, dynamic> json) {
    DateTime? parseDate(String? raw) {
      if (raw == null || raw.isEmpty) return null;
      try {
        return DateTime.parse(raw).toLocal();
      } catch (_) {
        return null;
      }
    }

    return RpHistoryItem(
      clientId: json['client_id']?.toString() ?? '',
      clientName: json['client_name']?.toString() ?? '',
      scopes: (json['scopes'] as List?)?.whereType<String>().toList() ?? [],
      lastApprovedAt: parseDate(json['last_approved_at']?.toString()),
      lastRevokedAt: parseDate(json['last_revoked_at']?.toString()),
      status: json['status']?.toString() ?? 'unknown',
    );
  }
}

class UserSessionSummary {
  final String sessionId;
  final DateTime? authenticatedAt;
  final DateTime? expiresAt;
  final DateTime? issuedAt;
  final DateTime? lastSeenAt;
  final String ipAddress;
  final String userAgent;
  final String clientId;
  final String appName;
  final bool isCurrent;
  final bool isActive;

  UserSessionSummary({
    required this.sessionId,
    this.authenticatedAt,
    this.expiresAt,
    this.issuedAt,
    this.lastSeenAt,
    required this.ipAddress,
    required this.userAgent,
    required this.clientId,
    required this.appName,
    required this.isCurrent,
    required this.isActive,
  });

  factory UserSessionSummary.fromJson(Map<String, dynamic> json) {
    DateTime? parseDate(dynamic raw) {
      final value = raw?.toString();
      if (value == null || value.isEmpty) {
        return null;
      }
      try {
        return DateTime.parse(value).toLocal();
      } catch (_) {
        return null;
      }
    }

    return UserSessionSummary(
      sessionId: json['session_id']?.toString() ?? '',
      authenticatedAt: parseDate(json['authenticated_at']),
      expiresAt: parseDate(json['expires_at']),
      issuedAt: parseDate(json['issued_at']),
      lastSeenAt: parseDate(json['last_seen_at']),
      ipAddress: json['ip_address']?.toString() ?? '',
      userAgent: json['user_agent']?.toString() ?? '',
      clientId: json['client_id']?.toString() ?? '',
      appName: json['app_name']?.toString() ?? '',
      isCurrent: json['is_current'] == true,
      isActive: json['is_active'] != false,
    );
  }
}
