use std::sync::Arc;

use crate::client::TetrixClient;
use crate::errors::TetrixError;
use crate::types::*;

impl TetrixClient {
    /// Index (upsert) an entity with optional content and embedding.
    pub async fn index(self: &Arc<Self>, req: &IndexRequest) -> Result<IndexResponse, TetrixError> {
        self.request("INDEX", req).await
    }

    /// Index a batch of entities.
    pub async fn index_batch(
        self: &Arc<Self>,
        req: &IndexBatchRequest,
    ) -> Result<IndexBatchResponse, TetrixError> {
        self.request("INDEX_BATCH", req).await
    }

    /// Get an entity by ID with optional content and relations.
    pub async fn get(self: &Arc<Self>, req: &GetRequest) -> Result<GetResponse, TetrixError> {
        self.request("GET", req).await
    }

    /// Update an entity's metadata, name, relations, or content.
    pub async fn update(
        self: &Arc<Self>,
        req: &UpdateRequest,
    ) -> Result<UpdateResponse, TetrixError> {
        self.request("UPDATE", req).await
    }

    /// Delete an entity (soft or hard).
    pub async fn delete(
        self: &Arc<Self>,
        req: &DeleteRequest,
    ) -> Result<DeleteResponse, TetrixError> {
        self.request("DELETE", req).await
    }

    /// Delete a batch of entities.
    pub async fn delete_batch(
        self: &Arc<Self>,
        req: &DeleteBatchRequest,
    ) -> Result<DeleteBatchResponse, TetrixError> {
        self.request("DELETE_BATCH", req).await
    }

    /// List entities with optional filters and pagination.
    pub async fn list_entities(
        self: &Arc<Self>,
        req: Option<&ListEntitiesRequest>,
    ) -> Result<ListEntitiesResponse, TetrixError> {
        let default = ListEntitiesRequest::default();
        let req = req.unwrap_or(&default);
        self.request("LIST_ENTITIES", req).await
    }

    /// List mutation events for an entity.
    pub async fn list_entity_events(
        self: &Arc<Self>,
        req: &ListEntityEventsRequest,
    ) -> Result<ListEntityEventsResponse, TetrixError> {
        self.request("LIST_ENTITY_EVENTS", req).await
    }

    /// Semantic search across entities.
    pub async fn semantic_search(
        self: &Arc<Self>,
        req: &SemanticSearchRequest,
    ) -> Result<SemanticSearchResponse, TetrixError> {
        self.request("SEMANTIC_SEARCH", req).await
    }

    /// Generate embedding vectors for multiple texts.
    pub async fn embed_batch(
        self: &Arc<Self>,
        req: &EmbedBatchRequest,
    ) -> Result<EmbedBatchResponse, TetrixError> {
        self.request("EMBED_BATCH", req).await
    }

    /// Health check.
    pub async fn health(self: &Arc<Self>) -> Result<HealthResponse, TetrixError> {
        self.request("HEALTH", &serde_json::json!({})).await
    }

    /// Get daemon metrics.
    pub async fn metrics(
        self: &Arc<Self>,
        req: &MetricsRequest,
    ) -> Result<MetricsResponse, TetrixError> {
        self.request("METRICS", req).await
    }
}
