package api1

import (
	"context"
	"time"

	"api-soap-facturacion/internal/config"
	"api-soap-facturacion/internal/logger"
	"api-soap-facturacion/pkg/errors"
	"api-soap-facturacion/pkg/soap"
	"github.com/google/uuid"
)

// Client es la interfaz para el cliente de API1
type Client interface {
	GetData(ctx context.Context, request GetDataRequest) (*GetDataResponse, error)
	// Agregar más métodos según sea necesario
}

// client implementa la interfaz Client
type client struct {
	soapClient soap.Client
	logger     logger.Logger
}

// NewClient crea un nuevo cliente para API1
func NewClient(config config.APIConfig, log logger.Logger) Client {
	// Configurar cliente SOAP
	options := soap.ClientOptions{
		Endpoint: config.Endpoint,
		Username: config.Username,
		Password: config.Password,
		Timeout:  config.Timeout * time.Second,
		Headers: map[string]string{
			"User-Agent": "soap-api-client/1.0",
		},
	}

	return &client{
		soapClient: soap.NewClient(options),
		logger:     log,
	}
}

// GetData realiza una solicitud GetData a API1
func (c *client) GetData(ctx context.Context, request GetDataRequest) (*GetDataResponse, error) {
	// Generar ID de solicitud si no existe
	var requestID string
	if id, ok := ctx.Value(soap.RequestIDKey{}).(string); ok {
		requestID = id
	} else {
		requestID = uuid.New().String()
		ctx = context.WithValue(ctx, soap.RequestIDKey{}, requestID)
	}

	// Crear request
	soapRequest := GetDataSoapRequest{
		Request: request,
	}

	// Registrar solicitud
	c.logger.Debug("Enviando solicitud GetData a API1",
		logger.NewField("request_id", requestID),
		logger.NewField("parameters", request),
	)

	// Respuesta
	response := &GetDataSoapResponse{}

	// Realizar llamada SOAP
	startTime := time.Now()
	err := c.soapClient.Call(ctx, "GetData", soapRequest, response)
	duration := time.Since(startTime)

	// Manejar error
	if err != nil {
		c.logger.Error("Error al realizar solicitud GetData a API1",
			logger.NewField("request_id", requestID),
			logger.NewField("error", err),
			logger.NewField("duration_ms", duration.Milliseconds()),
		)
		return nil, errors.Wrap(err, "error en solicitud GetData a API1")
	}

	// Registrar respuesta exitosa
	c.logger.Debug("Respuesta recibida de API1 para GetData",
		logger.NewField("request_id", requestID),
		logger.NewField("duration_ms", duration.Milliseconds()),
		logger.NewField("status", response.Response.Status),
	)

	return &response.Response, nil
}
