import 'dart:typed_data';

import '../connector/meshcore_protocol.dart';

class Channel {
  final int index;
  final String name;
  final Uint8List psk; // 16 bytes

  Channel({
    required this.index,
    required this.name,
    required this.psk,
  });

  String get pskHex => _bytesToHex(psk);

  bool get isEmpty => name.isEmpty && psk.every((b) => b == 0);

  bool get isPublicChannel => pskHex == publicChannelPsk;

  static Channel? fromFrame(Uint8List data) {
    // CHANNEL_INFO format:
    // [0] = RESP_CODE_CHANNEL_INFO (18)
    // [1] = channel_idx
    // [2-33] = name (32 bytes, null-terminated)
    // [34-49] = psk (16 bytes)
    if (data.length < 50) return null;
    if (data[0] != respCodeChannelInfo) return null;

    final index = data[1];
    final name = readCString(data, 2, 32);
    final psk = Uint8List.fromList(data.sublist(34, 50));

    return Channel(index: index, name: name, psk: psk);
  }

  static Channel empty(int index) {
    return Channel(
      index: index,
      name: '',
      psk: Uint8List(16),
    );
  }

  static Channel fromHex(int index, String name, String pskHex) {
    final psk = parsePskHex(pskHex);
    return Channel(index: index, name: name, psk: psk);
  }

  static Uint8List parsePskHex(String hex) {
    final cleaned = hex.replaceAll(RegExp(r'[^0-9a-fA-F]'), '');
    if (cleaned.length != 32) {
      throw const FormatException('PSK must be 32 hex characters');
    }
    final bytes = Uint8List(16);
    for (int i = 0; i < 16; i++) {
      final start = i * 2;
      bytes[i] = int.parse(cleaned.substring(start, start + 2), radix: 16);
    }
    return bytes;
  }

  static String formatPskHex(Uint8List psk) {
    return _bytesToHex(psk);
  }

  static String _bytesToHex(Uint8List bytes) {
    return bytes.map((b) => b.toRadixString(16).padLeft(2, '0')).join();
  }

  static const String publicChannelPsk = '8b3387e9c5cdea6ac9e5edbaa115cd72';
}
