//! Plain Rust request/response types for server domain logic.
//!
//! No proto, no capnp — just Rust structs.

use crate::storage::StorageError;

// ── Domain Error ────────────────────────────────────────────────────────────

/// Errors returned by domain service methods.
#[derive(thiserror::Error, Debug)]
pub enum DomainError {
    #[error("identity key must be exactly 32 bytes, got {0}")]
    InvalidIdentityKey(usize),

    #[error("key package must not be empty")]
    EmptyPackage,

    #[error("key package exceeds max size ({0} bytes)")]
    PackageTooLarge(usize),

    #[error("hybrid public key must not be empty")]
    EmptyHybridKey,

    #[error("username must not be empty")]
    EmptyUsername,

    #[error("blob hash must be exactly 32 bytes, got {0}")]
    BlobHashLength(usize),

    #[error("blob exceeds max size ({0} bytes)")]
    BlobTooLarge(u64),

    #[error("SHA-256 of uploaded data does not match blob hash")]
    BlobHashMismatch,

    #[error("blob not found")]
    BlobNotFound,

    #[error("maximum {0} devices per identity")]
    DeviceLimit(usize),

    #[error("device not found")]
    DeviceNotFound,

    #[error("group not found")]
    GroupNotFound,

    #[error("bad parameters: {0}")]
    BadParams(String),

    #[error("I/O error: {0}")]
    Io(String),

    #[error("storage error: {0}")]
    Storage(#[from] StorageError),
}

// ── Auth ─────────────────────────────────────────────────────────────────────

/// Caller authentication context (resolved from session token).
#[derive(Debug, Clone)]
pub struct CallerAuth {
    /// Ed25519 identity key of the authenticated caller (32 bytes).
    pub identity_key: Vec<u8>,
    /// Session token bytes.
    pub token: Vec<u8>,
    /// Device ID (optional, for auditing).
    pub device_id: Option<Vec<u8>>,
}

/// OPAQUE registration start.
pub struct RegisterStartReq {
    pub username: String,
    pub request_bytes: Vec<u8>,
}

pub struct RegisterStartResp {
    pub response_bytes: Vec<u8>,
}

/// OPAQUE registration finish.
pub struct RegisterFinishReq {
    pub username: String,
    pub upload_bytes: Vec<u8>,
    pub identity_key: Vec<u8>,
}

pub struct RegisterFinishResp {
    pub success: bool,
}

/// OPAQUE login start.
pub struct LoginStartReq {
    pub username: String,
    pub request_bytes: Vec<u8>,
}

pub struct LoginStartResp {
    pub response_bytes: Vec<u8>,
}

/// OPAQUE login finish.
pub struct LoginFinishReq {
    pub username: String,
    pub finalization_bytes: Vec<u8>,
    pub identity_key: Vec<u8>,
}

pub struct LoginFinishResp {
    pub session_token: Vec<u8>,
}

// ── Delivery ─────────────────────────────────────────────────────────────────

/// An envelope pairing a sequence number with an opaque payload.
#[derive(Debug, Clone)]
pub struct Envelope {
    pub seq: u64,
    pub data: Vec<u8>,
}

pub struct EnqueueReq {
    pub recipient_key: Vec<u8>,
    pub payload: Vec<u8>,
    pub channel_id: Vec<u8>,
    pub ttl_secs: u32,
}

pub struct EnqueueResp {
    pub seq: u64,
    pub delivery_proof: Vec<u8>,
}

pub struct FetchReq {
    pub recipient_key: Vec<u8>,
    pub channel_id: Vec<u8>,
    pub limit: u32,
}

pub struct FetchResp {
    pub payloads: Vec<Envelope>,
}

pub struct PeekReq {
    pub recipient_key: Vec<u8>,
    pub channel_id: Vec<u8>,
    pub limit: u32,
}

pub struct PeekResp {
    pub payloads: Vec<Envelope>,
}

pub struct AckReq {
    pub recipient_key: Vec<u8>,
    pub channel_id: Vec<u8>,
    pub seq_up_to: u64,
}

pub struct BatchEnqueueReq {
    pub recipient_keys: Vec<Vec<u8>>,
    pub payload: Vec<u8>,
    pub channel_id: Vec<u8>,
    pub ttl_secs: u32,
}

pub struct BatchEnqueueResp {
    pub seqs: Vec<u64>,
}

// ── Keys ─────────────────────────────────────────────────────────────────────

pub struct UploadKeyPackageReq {
    pub identity_key: Vec<u8>,
    pub package: Vec<u8>,
}

pub struct UploadKeyPackageResp {
    pub fingerprint: Vec<u8>,
}

pub struct FetchKeyPackageReq {
    pub identity_key: Vec<u8>,
}

pub struct FetchKeyPackageResp {
    pub package: Vec<u8>,
}

pub struct UploadHybridKeyReq {
    pub identity_key: Vec<u8>,
    pub hybrid_public_key: Vec<u8>,
}

pub struct FetchHybridKeyReq {
    pub identity_key: Vec<u8>,
}

pub struct FetchHybridKeyResp {
    pub hybrid_public_key: Vec<u8>,
}

pub struct FetchHybridKeysReq {
    pub identity_keys: Vec<Vec<u8>>,
}

pub struct FetchHybridKeysResp {
    pub keys: Vec<Vec<u8>>,
}

// ── Key Transparency / Revocation ────────────────────────────────────

pub struct RevokeKeyReq {
    pub identity_key: Vec<u8>,
    pub reason: String,
}

pub struct RevokeKeyResp {
    pub success: bool,
    pub leaf_index: u64,
}

pub struct CheckRevocationReq {
    pub identity_key: Vec<u8>,
}

pub struct CheckRevocationResp {
    pub revoked: bool,
    pub reason: String,
    pub timestamp_ms: u64,
}

pub struct AuditKeyTransparencyReq {
    pub start: u64,
    pub end: u64,
}

pub struct AuditLogEntry {
    pub index: u64,
    pub leaf_hash: Vec<u8>,
}

pub struct AuditKeyTransparencyResp {
    pub entries: Vec<AuditLogEntry>,
    pub tree_size: u64,
    pub root: Vec<u8>,
}

// ── Channel ──────────────────────────────────────────────────────────────────

pub struct CreateChannelReq {
    pub peer_key: Vec<u8>,
}

pub struct CreateChannelResp {
    pub channel_id: Vec<u8>,
    pub was_new: bool,
}

// ── User ─────────────────────────────────────────────────────────────────────

pub struct ResolveUserReq {
    pub username: String,
}

pub struct ResolveUserResp {
    pub identity_key: Vec<u8>,
    pub inclusion_proof: Vec<u8>,
}

pub struct ResolveIdentityReq {
    pub identity_key: Vec<u8>,
}

pub struct ResolveIdentityResp {
    pub username: String,
}

// ── Blob ─────────────────────────────────────────────────────────────────────

pub struct UploadBlobReq {
    pub blob_hash: Vec<u8>,
    pub chunk: Vec<u8>,
    pub offset: u64,
    pub total_size: u64,
    pub mime_type: String,
}

pub struct UploadBlobResp {
    pub blob_id: Vec<u8>,
}

pub struct DownloadBlobReq {
    pub blob_id: Vec<u8>,
    pub offset: u64,
    pub length: u32,
}

pub struct DownloadBlobResp {
    pub chunk: Vec<u8>,
    pub total_size: u64,
    pub mime_type: String,
}

// ── Device ───────────────────────────────────────────────────────────────────

pub struct RegisterDeviceReq {
    pub device_id: Vec<u8>,
    pub device_name: String,
}

pub struct RegisterDeviceResp {
    pub success: bool,
}

pub struct DeviceInfo {
    pub device_id: Vec<u8>,
    pub device_name: String,
    pub registered_at: u64,
}

pub struct ListDevicesResp {
    pub devices: Vec<DeviceInfo>,
}

pub struct RevokeDeviceReq {
    pub device_id: Vec<u8>,
}

pub struct RevokeDeviceResp {
    pub success: bool,
}

// ── Group metadata ───────────────────────────────────────────────────

pub struct GroupMetadata {
    pub group_id: Vec<u8>,
    pub name: String,
    pub description: String,
    pub avatar_hash: Vec<u8>,
    pub creator_key: Vec<u8>,
    pub created_at: u64,
}

pub struct UpdateGroupMetadataReq {
    pub group_id: Vec<u8>,
    pub name: String,
    pub description: String,
    pub avatar_hash: Vec<u8>,
}

pub struct ListGroupMembersReq {
    pub group_id: Vec<u8>,
}

pub struct GroupMemberInfo {
    pub identity_key: Vec<u8>,
    pub username: String,
    pub joined_at: u64,
}

pub struct ListGroupMembersResp {
    pub members: Vec<GroupMemberInfo>,
}

// ── Moderation ───────────────────────────────────────────────────────────────

pub struct ReportMessageReq {
    pub encrypted_report: Vec<u8>,
    pub conversation_id: Vec<u8>,
    pub reporter_identity: Vec<u8>,
}

pub struct ReportMessageResp {
    pub accepted: bool,
}

pub struct BanUserReq {
    pub identity_key: Vec<u8>,
    pub reason: String,
    pub duration_secs: u64,
}

pub struct BanUserResp {
    pub success: bool,
}

pub struct UnbanUserReq {
    pub identity_key: Vec<u8>,
}

pub struct UnbanUserResp {
    pub success: bool,
}

pub struct ListReportsReq {
    pub limit: u32,
    pub offset: u32,
}

pub struct ReportEntry {
    pub id: u64,
    pub encrypted_report: Vec<u8>,
    pub conversation_id: Vec<u8>,
    pub reporter_identity: Vec<u8>,
    pub timestamp: u64,
}

pub struct ListReportsResp {
    pub reports: Vec<ReportEntry>,
}

pub struct BannedUserEntry {
    pub identity_key: Vec<u8>,
    pub reason: String,
    pub banned_at: u64,
    pub expires_at: u64,
}

pub struct ListBannedResp {
    pub users: Vec<BannedUserEntry>,
}

// ── P2P ──────────────────────────────────────────────────────────────────────

pub struct PublishEndpointReq {
    pub identity_key: Vec<u8>,
    pub node_addr: Vec<u8>,
}

pub struct ResolveEndpointReq {
    pub identity_key: Vec<u8>,
}

pub struct ResolveEndpointResp {
    pub node_addr: Vec<u8>,
}

pub struct HealthResp {
    pub status: String,
}
