/// Shared renderer settings and capability metadata.
library;

/// Engine-visible renderer modes used by host adapters and menu flow.
enum WolfRendererMode {
  ascii('ASCII'),
  sixel('SIXEL'),
  software('SOFTWARE'),
  hardware('HARDWARE')
  ;

  const WolfRendererMode(this.label);

  final String label;
}

/// Renderer-specific toggles shown by the Change View customization submenu.
enum WolfRendererOptionId {
  asciiTheme,
  hardwareEffects,
  fpsCounter,
}

/// Host-reported renderer capability set used to filter visible menu options.
class WolfRendererCapabilities {
  const WolfRendererCapabilities({
    required this.supportedModes,
    this.supportsAsciiThemes = false,
    this.supportsHardwareEffects = false,
    this.supportsFpsCounter = false,
  });

  final Set<WolfRendererMode> supportedModes;
  final bool supportsAsciiThemes;
  final bool supportsHardwareEffects;
  final bool supportsFpsCounter;

  bool supportsMode(WolfRendererMode mode) => supportedModes.contains(mode);
}

/// Engine-owned renderer settings that both menu flow and host shortcuts mutate.
class WolfRendererSettings {
  const WolfRendererSettings({
    this.mode = WolfRendererMode.software,
    this.asciiThemeId = asciiThemeBlocks,
    this.hardwareEffectsEnabled = false,
    this.fpsCounterEnabled = false,
  });

  static const String asciiThemeBlocks = 'blocks';
  static const String asciiThemeQuadrant = 'quadrant';

  static const List<String> asciiThemeIds = <String>[
    asciiThemeBlocks,
    asciiThemeQuadrant,
  ];

  final WolfRendererMode mode;
  final String asciiThemeId;
  final bool hardwareEffectsEnabled;
  final bool fpsCounterEnabled;

  WolfRendererSettings copyWith({
    WolfRendererMode? mode,
    String? asciiThemeId,
    bool? hardwareEffectsEnabled,
    bool? fpsCounterEnabled,
  }) {
    return WolfRendererSettings(
      mode: mode ?? this.mode,
      asciiThemeId: asciiThemeId ?? this.asciiThemeId,
      hardwareEffectsEnabled:
          hardwareEffectsEnabled ?? this.hardwareEffectsEnabled,
      fpsCounterEnabled: fpsCounterEnabled ?? this.fpsCounterEnabled,
    );
  }

  WolfRendererSettings cycleAsciiTheme() {
    final int current = asciiThemeIds.indexOf(asciiThemeId);
    final int next = current == -1 ? 0 : (current + 1) % asciiThemeIds.length;
    return copyWith(asciiThemeId: asciiThemeIds[next]);
  }

  static String asciiThemeLabel(String id) {
    switch (id) {
      case asciiThemeQuadrant:
        return 'CHARSET: QUADRANT';
      case asciiThemeBlocks:
      default:
        return 'CHARSET: BLOCKS';
    }
  }

  Map<String, Object> toJson() {
    return <String, Object>{
      'mode': mode.name,
      'asciiThemeId': asciiThemeId,
      'hardwareEffectsEnabled': hardwareEffectsEnabled,
      'fpsCounterEnabled': fpsCounterEnabled,
    };
  }

  static WolfRendererSettings fromJson(Map<String, Object?> json) {
    final Object? modeRaw = json['mode'];
    final WolfRendererMode mode = WolfRendererMode.values.firstWhere(
      (candidate) => candidate.name == modeRaw,
      orElse: () => WolfRendererMode.software,
    );

    final Object? themeRaw = json['asciiThemeId'];
    final String asciiThemeId =
        themeRaw is String && asciiThemeIds.contains(themeRaw)
        ? themeRaw
        : asciiThemeBlocks;

    return WolfRendererSettings(
      mode: mode,
      asciiThemeId: asciiThemeId,
      hardwareEffectsEnabled: json['hardwareEffectsEnabled'] == true,
      fpsCounterEnabled: json['fpsCounterEnabled'] == true,
    );
  }
}
