#pragma once

// DragonX Wallet - HushChat outgoing memo construction (the inverse of the receive parser).
//
// Given the sender's identity and the peer, produce the header memo JSON + payload memo that,
// sent as two 0-value memo outputs to the peer's z-address (header at the LOWER memo position),
// another HushChat client parses and decrypts. The byte format matches SilentDragonXLite: the
// header keys serialize alphabetically (nlohmann default) to cid,e,h,p,t,v,z. Pure — no I/O, no
// network; broadcasting the memos is the caller's job (the transport lands in a later phase).

#include "chat_crypto.h"  // ChatKeyPair

#include <array>
#include <string>

namespace dragonx::chat {

struct OutgoingChatMemos {
    std::string recipientZaddr;  // the peer's z-address (recipient of both memo outputs)
    std::string headerMemo;      // JSON header — MUST occupy the lower memo position on the wire
    std::string payloadMemo;     // ciphertext hex (Message) or plaintext (ContactRequest)
};

// One of the two 0-value memo outputs a HushChat send produces (amount is always 0).
struct ChatSendOutput {
    std::string address;  // the peer's z-address
    std::string memo;     // memo encoded for the target transport (utf8:-prefixed or raw)
};

// The two outputs for a HushChat send, HEADER FIRST (it must occupy the lower memo position).
// `utf8Prefix` prepends the daemon's "utf8:" marker required by full-node z_sendmany (which then
// UTF-8-encodes the bytes on-chain, byte-identical to SDXLite's Memo::from_str); lite backends take
// raw UTF-8, so pass false there.
std::array<ChatSendOutput, 2> chatSendOutputs(const OutgoingChatMemos& memos, bool utf8Prefix);

enum class ChatComposeStatus {
    Ok,
    EmptyBody,
    MissingField,
    BadPeerKey,
    BadRequestText,  // a contact request text must not start with '{' (parser would read it as a header)
    EncryptFailed,
    TooLong          // a resulting memo exceeds the HushChat 512-byte memo limit
};

// Build an ENCRYPTED message to a peer whose public key you already learned from a memo they sent
// you. `mine` is the sender's identity keypair; `myPublicKeyHex` its public half (goes in header p).
ChatComposeStatus buildOutgoingMessage(const ChatKeyPair& mine,
                                       const std::string& myPublicKeyHex,
                                       const std::string& myReplyZaddr,
                                       const std::string& peerPublicKeyHex,
                                       const std::string& peerZaddr,
                                       const std::string& conversationId,
                                       const std::string& plaintext,
                                       OutgoingChatMemos& out);

// Build a plaintext contact request — no peer public key needed yet; this is how the peer first
// learns your public key + reply address. The payload is the (plaintext) request text.
ChatComposeStatus buildOutgoingContactRequest(const std::string& myPublicKeyHex,
                                              const std::string& myReplyZaddr,
                                              const std::string& peerZaddr,
                                              const std::string& conversationId,
                                              const std::string& requestText,
                                              OutgoingChatMemos& out);

} // namespace dragonx::chat
