/// Authentication Session Model
///
/// Models for API authentication response structure.
/// Matches the ERPNext login API response format.
library;

import 'package:freezed_annotation/freezed_annotation.dart';

part 'auth_session_model.freezed.dart';
part 'auth_session_model.g.dart';

/// App Information
///
/// Represents an available app in the system.
@freezed
sealed class AppInfo with _$AppInfo {
  const factory AppInfo({
    @JsonKey(name: 'app_title') required String appTitle,
    @JsonKey(name: 'app_endpoint') required String appEndpoint,
    @JsonKey(name: 'app_logo') required String appLogo,
  }) = _AppInfo;

  factory AppInfo.fromJson(Map<String, dynamic> json) =>
      _$AppInfoFromJson(json);
}

/// Login Response Message
///
/// Contains the core authentication data from login response.
@freezed
sealed class LoginMessage with _$LoginMessage {
  const factory LoginMessage({
    required bool success,
    required String message,
    required String sid,
    @JsonKey(name: 'csrf_token') required String csrfToken,
    @Default([]) List<AppInfo> apps,
  }) = _LoginMessage;

  factory LoginMessage.fromJson(Map<String, dynamic> json) =>
      _$LoginMessageFromJson(json);
}

/// Authentication Session Response
///
/// Complete authentication response from ERPNext login API.
@freezed
sealed class AuthSessionResponse with _$AuthSessionResponse {
  const factory AuthSessionResponse({
    @JsonKey(name: 'session_expired') required int sessionExpired,
    required LoginMessage message,
    @JsonKey(name: 'home_page') required String homePage,
    @JsonKey(name: 'full_name') required String fullName,
  }) = _AuthSessionResponse;

  factory AuthSessionResponse.fromJson(Map<String, dynamic> json) =>
      _$AuthSessionResponseFromJson(json);
}

/// Session Data (for GET SESSION API)
///
/// Represents the session data structure from get_session API.
@freezed
sealed class GetSessionData with _$GetSessionData {
  const factory GetSessionData({
    required String sid,
    @JsonKey(name: 'csrf_token') required String csrfToken,
  }) = _GetSessionData;

  factory GetSessionData.fromJson(Map<String, dynamic> json) =>
      _$GetSessionDataFromJson(json);
}

/// Get Session Message
///
/// Wrapper for session data in get_session API response.
@freezed
sealed class GetSessionMessage with _$GetSessionMessage {
  const factory GetSessionMessage({
    required GetSessionData data,
  }) = _GetSessionMessage;

  factory GetSessionMessage.fromJson(Map<String, dynamic> json) =>
      _$GetSessionMessageFromJson(json);
}

/// Get Session Response
///
/// Complete response from get_session API.
@freezed
sealed class GetSessionResponse with _$GetSessionResponse {
  const factory GetSessionResponse({
    required GetSessionMessage message,
    @JsonKey(name: 'home_page') required String homePage,
    @JsonKey(name: 'full_name') required String fullName,
  }) = _GetSessionResponse;

  factory GetSessionResponse.fromJson(Map<String, dynamic> json) =>
      _$GetSessionResponseFromJson(json);
}

/// Session Storage Model
///
/// Simplified model for storing session data in Hive.
@freezed
sealed class SessionData with _$SessionData {
  const factory SessionData({
    required String sid,
    required String csrfToken,
    required String fullName,
    required DateTime createdAt,
    List<AppInfo>? apps,
  }) = _SessionData;

  factory SessionData.fromJson(Map<String, dynamic> json) =>
      _$SessionDataFromJson(json);

  /// Create from get_session API response
  factory SessionData.fromGetSessionResponse(GetSessionResponse response) {
    return SessionData(
      sid: response.message.data.sid,
      csrfToken: response.message.data.csrfToken,
      fullName: response.fullName,
      createdAt: DateTime.now(),
    );
  }

  /// Create from auth login API response
  factory SessionData.fromAuthResponse(AuthSessionResponse response) {
    return SessionData(
      sid: response.message.sid,
      csrfToken: response.message.csrfToken,
      fullName: response.fullName,
      createdAt: DateTime.now(),
      apps: response.message.apps,
    );
  }
}
