// ==================== Confidential Transactions ====================

class ConfidentialTxInput {
  final String commitment;
  final String blindingFactor;
  final String value;
  final String? keyImage;

  ConfidentialTxInput({
    required this.commitment,
    required this.blindingFactor,
    required this.value,
    this.keyImage,
  });

  factory ConfidentialTxInput.fromJson(Map<String, dynamic> json) {
    return ConfidentialTxInput(
      commitment: json['commitment'] as String,
      blindingFactor: json['blinding_factor'] as String,
      value: json['value'] as String,
      keyImage: json['key_image'] as String?,
    );
  }

  Map<String, dynamic> toJson() => {
        'commitment': commitment,
        'blinding_factor': blindingFactor,
        'value': value,
        if (keyImage != null) 'key_image': keyImage,
      };
}

class ConfidentialTxOutput {
  final String commitment;
  final String blindingFactor;
  final String value;
  final String recipientPublicKey;
  final String? rangeProof;

  ConfidentialTxOutput({
    required this.commitment,
    required this.blindingFactor,
    required this.value,
    required this.recipientPublicKey,
    this.rangeProof,
  });

  factory ConfidentialTxOutput.fromJson(Map<String, dynamic> json) {
    return ConfidentialTxOutput(
      commitment: json['commitment'] as String,
      blindingFactor: json['blinding_factor'] as String,
      value: json['value'] as String,
      recipientPublicKey: json['recipient_public_key'] as String,
      rangeProof: json['range_proof'] as String?,
    );
  }

  Map<String, dynamic> toJson() => {
        'commitment': commitment,
        'blinding_factor': blindingFactor,
        'value': value,
        'recipient_public_key': recipientPublicKey,
        if (rangeProof != null) 'range_proof': rangeProof,
      };
}

class ConfidentialTransaction {
  final String id;
  final List<ConfidentialTxInput> inputs;
  final List<ConfidentialTxOutput> outputs;
  final String fee;
  final String excess;
  final String excessSig;
  final String? kernelOffset;

  ConfidentialTransaction({
    required this.id,
    required this.inputs,
    required this.outputs,
    required this.fee,
    required this.excess,
    required this.excessSig,
    this.kernelOffset,
  });

  factory ConfidentialTransaction.fromJson(Map<String, dynamic> json) {
    return ConfidentialTransaction(
      id: json['id'] as String,
      inputs: (json['inputs'] as List)
          .map((e) => ConfidentialTxInput.fromJson(e))
          .toList(),
      outputs: (json['outputs'] as List)
          .map((e) => ConfidentialTxOutput.fromJson(e))
          .toList(),
      fee: json['fee'] as String,
      excess: json['excess'] as String,
      excessSig: json['excess_sig'] as String,
      kernelOffset: json['kernel_offset'] as String?,
    );
  }

  Map<String, dynamic> toJson() => {
        'id': id,
        'inputs': inputs.map((i) => i.toJson()).toList(),
        'outputs': outputs.map((o) => o.toJson()).toList(),
        'fee': fee,
        'excess': excess,
        'excess_sig': excessSig,
        if (kernelOffset != null) 'kernel_offset': kernelOffset,
      };
}

// ==================== Commitments ====================

class Commitment {
  final String commitment;
  final String blindingFactor;

  Commitment({required this.commitment, required this.blindingFactor});

  factory Commitment.fromJson(Map<String, dynamic> json) {
    return Commitment(
      commitment: json['commitment'] as String,
      blindingFactor: json['blinding_factor'] as String,
    );
  }

  Map<String, dynamic> toJson() => {
        'commitment': commitment,
        'blinding_factor': blindingFactor,
      };
}

class RangeProof {
  final String proof;
  final String commitment;
  final int minValue;
  final int maxValue;

  RangeProof({
    required this.proof,
    required this.commitment,
    required this.minValue,
    required this.maxValue,
  });

  factory RangeProof.fromJson(Map<String, dynamic> json) {
    return RangeProof(
      proof: json['proof'] as String,
      commitment: json['commitment'] as String,
      minValue: json['min_value'] as int,
      maxValue: json['max_value'] as int,
    );
  }

  Map<String, dynamic> toJson() => {
        'proof': proof,
        'commitment': commitment,
        'min_value': minValue,
        'max_value': maxValue,
      };
}

// ==================== Ring Signatures ====================

class RingSignature {
  final String c0;
  final List<String> s;
  final String keyImage;
  final List<String> ring;

  RingSignature({
    required this.c0,
    required this.s,
    required this.keyImage,
    required this.ring,
  });

  factory RingSignature.fromJson(Map<String, dynamic> json) {
    return RingSignature(
      c0: json['c0'] as String,
      s: (json['s'] as List).map((e) => e as String).toList(),
      keyImage: json['key_image'] as String,
      ring: (json['ring'] as List).map((e) => e as String).toList(),
    );
  }

  Map<String, dynamic> toJson() => {
        'c0': c0,
        's': s,
        'key_image': keyImage,
        'ring': ring,
      };
}

// ==================== Stealth Addresses ====================

class StealthKeyPair {
  final String spendPublicKey;
  final String spendPrivateKey;
  final String viewPublicKey;
  final String viewPrivateKey;

  StealthKeyPair({
    required this.spendPublicKey,
    required this.spendPrivateKey,
    required this.viewPublicKey,
    required this.viewPrivateKey,
  });

  factory StealthKeyPair.fromJson(Map<String, dynamic> json) {
    return StealthKeyPair(
      spendPublicKey: json['spend_public_key'] as String,
      spendPrivateKey: json['spend_private_key'] as String,
      viewPublicKey: json['view_public_key'] as String,
      viewPrivateKey: json['view_private_key'] as String,
    );
  }
}

class StealthAddress {
  final String address;
  final String ephemeralPublicKey;
  final String? txPublicKey;

  StealthAddress({
    required this.address,
    required this.ephemeralPublicKey,
    this.txPublicKey,
  });

  factory StealthAddress.fromJson(Map<String, dynamic> json) {
    return StealthAddress(
      address: json['address'] as String,
      ephemeralPublicKey: json['ephemeral_public_key'] as String,
      txPublicKey: json['tx_public_key'] as String?,
    );
  }
}

class StealthOutput {
  final String txHash;
  final int outputIndex;
  final String stealthAddress;
  final String amount;
  final int blockHeight;

  StealthOutput({
    required this.txHash,
    required this.outputIndex,
    required this.stealthAddress,
    required this.amount,
    required this.blockHeight,
  });

  factory StealthOutput.fromJson(Map<String, dynamic> json) {
    return StealthOutput(
      txHash: json['tx_hash'] as String,
      outputIndex: json['output_index'] as int,
      stealthAddress: json['stealth_address'] as String,
      amount: json['amount'] as String,
      blockHeight: json['block_height'] as int,
    );
  }
}
