import 'package:freezed_annotation/freezed_annotation.dart';

part 'server_config.freezed.dart';
part 'server_config.g.dart';

@freezed
class ServerConfig with _$ServerConfig {
  const factory ServerConfig({
    required SystemConfig system,
    required StoriesConfig stories,
    required ChatsModuleConfig chats,
    required MessagesConfig messages,
    required WebRtcConfig webRtc,
    required KlipyConfig klipy,
    required ImportConfig import,
    required FederationConfig federation,
  }) = _ServerConfig;

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

@freezed
class SystemConfig with _$SystemConfig {
  const factory SystemConfig({
    required String domainUrl,
    required bool enableRegistration,
    @Default('UTC') String serverTimezone,
    @Default('admin') String adminRoute,
  }) = _SystemConfig;

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

@Freezed(toJson: true)
class StoriesConfig with _$StoriesConfig {
  const factory StoriesConfig({
    required bool enabled,
    required int maxStoriesPerPeriod,
    required int storyLifetimeHours,
    required bool textStoriesEnabled,
    required int textStoryDurationSeconds,
    required int mediaStoryMaxDurationSeconds,
    required int maxMediaSizeBytes,
  }) = _StoriesConfig;

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

@Freezed(toJson: true)
class ChatsModuleConfig with _$ChatsModuleConfig {
  const factory ChatsModuleConfig({
    required bool supportGroups,
    required int maxGroupParticipants,
    required bool allowChatToGroupConversion,
    required bool enableFolders,
    @Default(false) bool enableAutoClean,
  }) = _ChatsModuleConfig;

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

@Freezed(toJson: true)
class MessagesConfig with _$MessagesConfig {
  const factory MessagesConfig({
    required int dailyMessageLimitPerUser,
    required int chatMessageLimit,
    required bool allowMedia,
    required int maxMediaSizeBytes,
    required List<String> allowedMediaTypes,
    required bool allowVoiceMessages,
    required bool allowForwarding,
    required bool allowReactions,
    required bool allowReplies,
    required bool allowQuoting,
    required bool allowMessageDeletion,
    required bool forbidCopying,
    required bool allowLinks,
    required bool allowPolls,
    required bool allowPinning,
    @Default(0) int maxFileSize,
  }) = _MessagesConfig;

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

@Freezed(toJson: true)
class WebRtcConfig with _$WebRtcConfig {
  const factory WebRtcConfig({
    required bool enabled,
    required bool enableVoiceCalls,
    required bool enableVideoCalls,
    required bool enableScreenSharing,
    required String turnHost,
    required int turnPort,
    @Default('') String turnUser,
    @Default('') String turnSecret,
  }) = _WebRtcConfig;

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

@Freezed(toJson: true)
class KlipyConfig with _$KlipyConfig {
  const factory KlipyConfig({
    required bool enabled,
    required String appName,
    @Default('') String apiKey,
  }) = _KlipyConfig;

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

@Freezed(toJson: true)
class ImportConfig with _$ImportConfig {
  const factory ImportConfig({
    @Default(false) bool enableTelegramImport,
  }) = _ImportConfig;

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

@Freezed(toJson: true)
class FederationConfig with _$FederationConfig {
  const factory FederationConfig({
    required bool enabled,
    required String serverDescription,
    required List<FederationDomainConfig> allowedDomains,
  }) = _FederationConfig;

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

@Freezed(toJson: true)
class FederationDomainConfig with _$FederationDomainConfig {
  const factory FederationDomainConfig({
    required String domain,
    required bool enabled,
  }) = _FederationDomainConfig;

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