use serde::{Deserialize, Serialize};

use crate::agent::SubmitTaskRequest;
use crate::pipe::ConversationMessage;

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ClientMessage {
    Connect,
    Start,
    Stop,
    SubmitTask {
        instruction: String,
        #[serde(default)]
        conversation_id: String,
        #[serde(default)]
        messages: Vec<ConversationMessage>,
        #[serde(default)]
        page_url: String,
        #[serde(default)]
        page_title: String,
    },
    Ping,
}

impl ClientMessage {
    pub fn into_submit_task_request(self) -> Option<SubmitTaskRequest> {
        match self {
            ClientMessage::SubmitTask {
                instruction,
                conversation_id,
                messages,
                page_url,
                page_title,
            } => Some(SubmitTaskRequest {
                instruction,
                conversation_id: normalize_optional_field(conversation_id),
                messages,
                page_url: normalize_optional_field(page_url),
                page_title: normalize_optional_field(page_title),
            }),
            ClientMessage::Connect | ClientMessage::Start | ClientMessage::Stop | ClientMessage::Ping => None,
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ServiceMessage {
    StatusChanged { state: String },
    LogEntry { level: String, message: String },
    TaskComplete { success: bool, summary: String },
    Busy { message: String },
    Pong,
}

fn normalize_optional_field(value: String) -> Option<String> {
    let trimmed = value.trim();
    (!trimmed.is_empty()).then(|| trimmed.to_string())
}
