/// A backend-independent emergency notice loaded from a foreign server URL —
/// frontmatter (control fields) plus a free Markdown body, so it stays
/// hand-writable in an outage. See [parse] for the format.
class EmergencyNotice {
  /// `false` renders full-screen and blocks back/barrier taps.
  final bool dismissible;
  final String? title;
  final String body;

  const EmergencyNotice({
    required this.dismissible,
    required this.title,
    required this.body,
  });

  /// Parses the raw file, or returns `null` when there is nothing to show.
  /// Never throws — malformed input yields `null` so a broken file can't break
  /// the app.
  ///
  /// ```
  /// ---
  /// active: true          # required truthy, else null; # lines are comments
  /// dismissible: true     # default true
  /// title: Störung        # optional
  /// ---
  /// Free **markdown** body (everything after the closing ---).
  /// ```
  static EmergencyNotice? parse(String raw) {
    final lines = raw
        .replaceAll('\r\n', '\n')
        .replaceAll('\r', '\n')
        .split('\n');

    var i = 0;
    while (i < lines.length && lines[i].trim().isEmpty) {
      i++;
    }
    if (i >= lines.length || lines[i].trim() != '---') return null;
    final openIndex = i;

    var closeIndex = -1;
    for (var j = openIndex + 1; j < lines.length; j++) {
      if (lines[j].trim() == '---') {
        closeIndex = j;
        break;
      }
    }
    if (closeIndex == -1) return null;

    final meta = <String, String>{};
    for (var j = openIndex + 1; j < closeIndex; j++) {
      final line = lines[j].trim();
      if (line.isEmpty || line.startsWith('#')) continue;
      final sep = line.indexOf(':');
      if (sep <= 0) continue;
      final key = line.substring(0, sep).trim().toLowerCase();
      final value = line.substring(sep + 1).trim();
      meta[key] = value;
    }

    if (_parseBool(meta['active']) != true) return null;

    final body = lines.sublist(closeIndex + 1).join('\n').trim();
    if (body.isEmpty) return null;

    final title = meta['title'];
    return EmergencyNotice(
      dismissible: _parseBool(meta['dismissible']) ?? true,
      title: (title == null || title.isEmpty) ? null : title,
      body: body,
    );
  }

  static bool? _parseBool(String? value) {
    switch (value?.trim().toLowerCase()) {
      case 'true':
      case 'yes':
      case '1':
      case 'on':
        return true;
      case 'false':
      case 'no':
      case '0':
      case 'off':
        return false;
      default:
        return null;
    }
  }
}
