//! Config Service Proxy - Zero-copy gRPC forwarding for config.ConfigService
//!
//! Forwards to trading-service backend (config runs in the same process).

use futures::Stream;
use std::pin::Pin;
use tonic::{Request, Response, Status};
use tracing::{error, instrument};

use crate::config_backend::config_service_client::ConfigServiceClient;
use crate::config_backend::config_service_server::ConfigService;
use crate::config_backend::{
    ConfigChangeEvent, DeleteConfigurationRequest, DeleteConfigurationResponse,
    ExportConfigurationRequest, ExportConfigurationResponse, GetConfigSchemaRequest,
    GetConfigSchemaResponse, GetConfigurationHistoryRequest, GetConfigurationHistoryResponse,
    GetConfigurationRequest, GetConfigurationResponse, ImportConfigurationRequest,
    ImportConfigurationResponse, ListCategoriesRequest, ListCategoriesResponse,
    RollbackConfigurationRequest, RollbackConfigurationResponse, StreamConfigChangesRequest,
    UpdateConfigSchemaRequest, UpdateConfigSchemaResponse, UpdateConfigurationRequest,
    UpdateConfigurationResponse, ValidateConfigurationRequest, ValidateConfigurationResponse,
};

#[derive(Debug, Clone)]
pub struct ConfigServiceProxy {
    client: ConfigServiceClient<tonic::transport::Channel>,
}

impl ConfigServiceProxy {
    pub fn new(client: ConfigServiceClient<tonic::transport::Channel>) -> Self {
        Self { client }
    }
}

#[tonic::async_trait]
impl ConfigService for ConfigServiceProxy {
    type StreamConfigChangesStream =
        Pin<Box<dyn Stream<Item = Result<ConfigChangeEvent, Status>> + Send>>;

    #[instrument(skip(self, request), err)]
    async fn get_configuration(
        &self,
        request: Request<GetConfigurationRequest>,
    ) -> Result<Response<GetConfigurationResponse>, Status> {
        self.client
            .clone()
            .get_configuration(request)
            .await
            .map_err(|e| {
                error!("Backend GetConfiguration failed: {}", e);
                e
            })
    }

    #[instrument(skip(self, request), err)]
    async fn update_configuration(
        &self,
        request: Request<UpdateConfigurationRequest>,
    ) -> Result<Response<UpdateConfigurationResponse>, Status> {
        self.client
            .clone()
            .update_configuration(request)
            .await
            .map_err(|e| {
                error!("Backend UpdateConfiguration failed: {}", e);
                e
            })
    }

    #[instrument(skip(self, request), err)]
    async fn delete_configuration(
        &self,
        request: Request<DeleteConfigurationRequest>,
    ) -> Result<Response<DeleteConfigurationResponse>, Status> {
        self.client
            .clone()
            .delete_configuration(request)
            .await
            .map_err(|e| {
                error!("Backend DeleteConfiguration failed: {}", e);
                e
            })
    }

    #[instrument(skip(self, request), err)]
    async fn list_categories(
        &self,
        request: Request<ListCategoriesRequest>,
    ) -> Result<Response<ListCategoriesResponse>, Status> {
        self.client
            .clone()
            .list_categories(request)
            .await
            .map_err(|e| {
                error!("Backend ListCategories failed: {}", e);
                e
            })
    }

    #[instrument(skip(self, request), err)]
    async fn stream_config_changes(
        &self,
        request: Request<StreamConfigChangesRequest>,
    ) -> Result<Response<Self::StreamConfigChangesStream>, Status> {
        let stream = self
            .client
            .clone()
            .stream_config_changes(request)
            .await
            .map_err(|e| {
                error!("Backend StreamConfigChanges failed: {}", e);
                e
            })?;
        Ok(Response::new(Box::pin(stream.into_inner())))
    }

    #[instrument(skip(self, request), err)]
    async fn validate_configuration(
        &self,
        request: Request<ValidateConfigurationRequest>,
    ) -> Result<Response<ValidateConfigurationResponse>, Status> {
        self.client
            .clone()
            .validate_configuration(request)
            .await
            .map_err(|e| {
                error!("Backend ValidateConfiguration failed: {}", e);
                e
            })
    }

    #[instrument(skip(self, request), err)]
    async fn get_configuration_history(
        &self,
        request: Request<GetConfigurationHistoryRequest>,
    ) -> Result<Response<GetConfigurationHistoryResponse>, Status> {
        self.client
            .clone()
            .get_configuration_history(request)
            .await
            .map_err(|e| {
                error!("Backend GetConfigurationHistory failed: {}", e);
                e
            })
    }

    #[instrument(skip(self, request), err)]
    async fn rollback_configuration(
        &self,
        request: Request<RollbackConfigurationRequest>,
    ) -> Result<Response<RollbackConfigurationResponse>, Status> {
        self.client
            .clone()
            .rollback_configuration(request)
            .await
            .map_err(|e| {
                error!("Backend RollbackConfiguration failed: {}", e);
                e
            })
    }

    #[instrument(skip(self, request), err)]
    async fn export_configuration(
        &self,
        request: Request<ExportConfigurationRequest>,
    ) -> Result<Response<ExportConfigurationResponse>, Status> {
        self.client
            .clone()
            .export_configuration(request)
            .await
            .map_err(|e| {
                error!("Backend ExportConfiguration failed: {}", e);
                e
            })
    }

    #[instrument(skip(self, request), err)]
    async fn import_configuration(
        &self,
        request: Request<ImportConfigurationRequest>,
    ) -> Result<Response<ImportConfigurationResponse>, Status> {
        self.client
            .clone()
            .import_configuration(request)
            .await
            .map_err(|e| {
                error!("Backend ImportConfiguration failed: {}", e);
                e
            })
    }

    #[instrument(skip(self, request), err)]
    async fn get_config_schema(
        &self,
        request: Request<GetConfigSchemaRequest>,
    ) -> Result<Response<GetConfigSchemaResponse>, Status> {
        self.client
            .clone()
            .get_config_schema(request)
            .await
            .map_err(|e| {
                error!("Backend GetConfigSchema failed: {}", e);
                e
            })
    }

    #[instrument(skip(self, request), err)]
    async fn update_config_schema(
        &self,
        request: Request<UpdateConfigSchemaRequest>,
    ) -> Result<Response<UpdateConfigSchemaResponse>, Status> {
        self.client
            .clone()
            .update_config_schema(request)
            .await
            .map_err(|e| {
                error!("Backend UpdateConfigSchema failed: {}", e);
                e
            })
    }
}
