import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/cupertino.dart';
import 'package:pointycastle/api.dart'
    show KeyParameter, PaddedBlockCipher, PaddedBlockCipherParameters;
import 'package:pointycastle/block/aes_fast.dart';
import 'package:pointycastle/block/modes/ecb.dart';
import 'package:pointycastle/padded_block_cipher/padded_block_cipher_impl.dart';
import 'package:pointycastle/paddings/pkcs7.dart';

/// Giống Swift:
/// - `cipherHex`: chuỗi hex của dữ liệu đã mã hoá AES
/// - `secretKey`: chuỗi key (UTF-8), yêu cầu 16 bytes (AES-128)
class Crypto {
  final String cipherHex;
  final String secretKey;

  const Crypto({required this.cipherHex, required this.secretKey});

  /// Decrypt AES-128/ECB/PKCS7 từ hex -> String (UTF-8). Lỗi -> null.
  String? decryption() {
    try {
      final keyBytes = _normalizeKeyUtf8(secretKey, 16); // AES-128 = 16 bytes
      final dataBytes = _hexToBytes(cipherHex);

      final cipher = _createCipher(keyBytes);
      final decryptedBytes = cipher.process(dataBytes);
      final decrypted = utf8.decode(decryptedBytes);
      // ignore: avoid_print
      debugPrint('Decrypted Text: $decrypted');
      return decrypted;
    } catch (e) {
      // ignore: avoid_print
      debugPrint('Decryption failed: $e');
      return null;
    }
  }

  /// Chuyển hex -> bytes
  Uint8List _hexToBytes(String hex) {
    final s = hex.replaceAll(RegExp(r'\s+'), '');
    if (s.length % 2 != 0) {
      throw const FormatException('Invalid hex length');
    }
    final result = Uint8List(s.length ~/ 2);
    for (var i = 0; i < s.length; i += 2) {
      result[i ~/ 2] = int.parse(s.substring(i, i + 2), radix: 16);
    }
    return result;
  }

  /// Key từ UTF-8, đảm bảo đúng `len` bytes: nếu thiếu thì pad 0x00, nếu dư thì cắt.
  Uint8List _normalizeKeyUtf8(String key, int len) {
    final raw = Uint8List.fromList(key.codeUnits); // UTF-8 code units (ASCII-safe)
    if (raw.length == len) return raw;
    if (raw.length > len) return Uint8List.fromList(raw.sublist(0, len));
    // pad 0x00 đến đủ độ dài
    final out = Uint8List(len);
    out.setRange(0, raw.length, raw);
    return out;
  }

  PaddedBlockCipher _createCipher(Uint8List key) {
    final engine = ECBBlockCipher(AESFastEngine());
    final cipher = PaddedBlockCipherImpl(PKCS7Padding(), engine);
    cipher.init(
      false,
      PaddedBlockCipherParameters<KeyParameter, Null>(
        KeyParameter(key),
        null,
      ),
    );
    return cipher;
  }
}
