package sale_order

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"net/http"
	"net/http/httptest"
	"testing"

	SOProto "github.com/AlchemyTelcoSolutions/proto/gen/go/callisto/so/v1"
	"github.com/AlchemyTelcoSolutions/xutils-go/xlogger"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/mock"

	"github.com/AlchemyTelcoSolutions/callisto-so-bff/api/v1"
	"github.com/AlchemyTelcoSolutions/callisto-so-bff/cmd/app/config"
	"github.com/AlchemyTelcoSolutions/callisto-so-bff/internal/domain/model"
	"github.com/AlchemyTelcoSolutions/callisto-so-bff/internal/proxy"
	proxyMock "github.com/AlchemyTelcoSolutions/callisto-so-bff/internal/proxy/mocks"
	orderMock "github.com/AlchemyTelcoSolutions/callisto-so-bff/internal/sale_order/mocks"
)

func TestUpdateSaleOrder(t *testing.T) {

	testSuite := []struct {
		name                   string
		assert                 func(*testing.T, *model.SaleOrderResponse)
		proxyService           func(*testing.T, *http.Request) proxy.ProxyService
		iscallistoSOGRPCClient bool
		callistoSOGRPCClient   func(t *testing.T, ctx context.Context) SOServiceClient
		funcToCall             func(*Service, *http.Request) *model.SaleOrderResponse
		configEndpoint         string
		request                *http.Request
	}{
		{
			name: "error calling callisto api",
			assert: func(t *testing.T, resp *model.SaleOrderResponse) {
				assert.Equal(t, false, resp.Response.Success)
				assert.Equal(t, http.StatusInternalServerError, resp.Code)
			},
			proxyService: func(t *testing.T, r *http.Request) proxy.ProxyService {
				//r = addLegacyIDToCtx(r, "12345")
				proxySvc := proxyMock.NewProxyService(t)
				proxySvc.On("SendRequestToClient", r, mock.Anything, map[string]string{}).Return(nil, fmt.Errorf("server fail"))
				return proxySvc
			},
			callistoSOGRPCClient: func(t *testing.T, _ context.Context) SOServiceClient {
				mockClient := orderMock.NewSOServiceClient(t)
				return mockClient
			},
			configEndpoint: "/v1/bff/sale-orders/123456",
			funcToCall: func(s *Service, r *http.Request) *model.SaleOrderResponse {
				return s.UpdateSaleOrder(r, &api.UpdateSaleOrderMultipartBody{}, "12345")
			},
			request: getTestRequestUpdate(),
		},
		{
			name: "success response from api and so service disabled",
			proxyService: func(t *testing.T, r *http.Request) proxy.ProxyService {
				response := &model.ProxyResponse{
					BodyBytes:  []byte(successBffUpdate(false, false, false)),
					StatusCode: 200,
				}
				proxySvc := proxyMock.NewProxyService(t)
				proxySvc.On("SendRequestToClient", r, mock.Anything, map[string]string{}).Return(response, nil)
				return proxySvc
			},
			callistoSOGRPCClient: func(t *testing.T, _ context.Context) SOServiceClient {
				mockClient := orderMock.NewSOServiceClient(t)
				return mockClient
			},
			configEndpoint: "/v1/bff/sale-orders/123456",
			funcToCall: func(s *Service, r *http.Request) *model.SaleOrderResponse {
				return s.UpdateSaleOrder(r, &api.UpdateSaleOrderMultipartBody{}, "12345")
			},
			request: getTestRequestUpdate(),
			assert: func(t *testing.T, resp *model.SaleOrderResponse) {
				assert.Equal(t, true, resp.Response.Success)
				assert.Equal(t, http.StatusOK, resp.Code)
			},
		},
		{
			name: "fail umarshal bff data",
			proxyService: func(t *testing.T, r *http.Request) proxy.ProxyService {
				response := &model.ProxyResponse{
					BodyBytes:  []byte(failBFFResponse()),
					StatusCode: 200,
				}
				proxySvc := proxyMock.NewProxyService(t)
				proxySvc.On("SendRequestToClient", r, mock.Anything, map[string]string{}).Return(response, nil)
				return proxySvc
			},
			configEndpoint: "/v1/bff/sale-orders/123456",
			funcToCall: func(s *Service, r *http.Request) *model.SaleOrderResponse {
				method := "PUT"
				return s.UpdateSaleOrder(r, &api.UpdateSaleOrderMultipartBody{Method: &method}, "12345")
			},
			request:                getTestRequestUpdate(),
			iscallistoSOGRPCClient: true,
			callistoSOGRPCClient: func(t *testing.T, _ context.Context) SOServiceClient {
				mockClient := orderMock.NewSOServiceClient(t)
				return mockClient
			},
			assert: func(t *testing.T, resp *model.SaleOrderResponse) {
				assert.Equal(t, true, resp.Response.Success)
				assert.Equal(t, http.StatusOK, resp.Code)
			},
		},
		{
			name: "fail adding note",
			proxyService: func(t *testing.T, r *http.Request) proxy.ProxyService {
				response := &model.ProxyResponse{
					BodyBytes:  []byte(successBffUpdate(true, false, false)),
					StatusCode: 200,
				}
				proxySvc := proxyMock.NewProxyService(t)
				proxySvc.On("SendRequestToClient", r, mock.Anything, map[string]string{}).Return(response, nil)
				return proxySvc
			},
			configEndpoint: "/v1/bff/sale-orders/123456",
			funcToCall: func(s *Service, r *http.Request) *model.SaleOrderResponse {
				method := "PUT"
				note := "this is a note"
				return s.UpdateSaleOrder(r, &api.UpdateSaleOrderMultipartBody{
					Method: &method,
					Note:   &note,
				}, "12345")
			},
			request:                getTestRequestUpdate(),
			iscallistoSOGRPCClient: true,
			callistoSOGRPCClient: func(t *testing.T, ctx context.Context) SOServiceClient {
				mockClient := orderMock.NewSOServiceClient(t)
				ctx = addLegacyIDToCtx(ctx, "12345")
				err := fmt.Errorf("Error in grpc call")
				mockClient.Mock.On("AddNote", ctx, mock.Anything).Return(nil, err)
				return mockClient
			},
			assert: func(t *testing.T, resp *model.SaleOrderResponse) {
				assert.Equal(t, true, resp.Response.Success)
				assert.Equal(t, http.StatusOK, resp.Code)
			},
		},
		{
			name: "fail adding shipment",
			proxyService: func(t *testing.T, r *http.Request) proxy.ProxyService {
				response := &model.ProxyResponse{
					BodyBytes:  []byte(successBffUpdate(true, true, false)),
					StatusCode: 200,
				}
				proxySvc := proxyMock.NewProxyService(t)
				proxySvc.On("SendRequestToClient", r, mock.Anything, map[string]string{}).Return(response, nil)
				return proxySvc
			},
			configEndpoint: "/v1/bff/sale-orders/123456",
			funcToCall: func(s *Service, r *http.Request) *model.SaleOrderResponse {
				return s.UpdateSaleOrder(r, getUpdateSaleOrderPut(), "12345")
			},
			request:                getTestRequestUpdate(),
			iscallistoSOGRPCClient: true,
			callistoSOGRPCClient: func(t *testing.T, ctx context.Context) SOServiceClient {
				mockClient := orderMock.NewSOServiceClient(t)
				ctx = addLegacyIDToCtx(ctx, "12345")
				err := fmt.Errorf("Error in grpc call")
				mockClient.Mock.On("AddNote", ctx, mock.Anything).Return(&SOProto.AddNoteResponse{Success: true}, nil)
				mockClient.Mock.On("AddShipment", ctx, mock.Anything).Return(nil, err)
				return mockClient
			},
			assert: func(t *testing.T, resp *model.SaleOrderResponse) {
				assert.Equal(t, true, resp.Response.Success)
				assert.Equal(t, http.StatusOK, resp.Code)
			},
		},
		{
			name: "fail adding document",
			proxyService: func(t *testing.T, r *http.Request) proxy.ProxyService {
				response := &model.ProxyResponse{
					BodyBytes:  []byte(successBffUpdate(true, true, true)),
					StatusCode: 200,
				}
				proxySvc := proxyMock.NewProxyService(t)
				proxySvc.On("SendRequestToClient", r, mock.Anything, map[string]string{}).Return(response, nil)
				return proxySvc
			},
			configEndpoint: "/v1/bff/sale-orders/123456",
			funcToCall: func(s *Service, r *http.Request) *model.SaleOrderResponse {
				return s.UpdateSaleOrder(r, getUpdateSaleOrderPut(), "12345")
			},
			request:                getTestRequestUpdate(),
			iscallistoSOGRPCClient: true,
			callistoSOGRPCClient: func(t *testing.T, ctx context.Context) SOServiceClient {
				mockClient := orderMock.NewSOServiceClient(t)
				ctx = addLegacyIDToCtx(ctx, "12345")
				err := fmt.Errorf("Error in grpc call")
				mockClient.Mock.On("AddNote", ctx, mock.Anything).Return(&SOProto.AddNoteResponse{Success: true}, nil)
				mockClient.Mock.On("AddShipment", ctx, mock.Anything).Return(&SOProto.AddShipmentResponse{ShipmentId: 12345}, nil)
				mockClient.Mock.On("AddDocument", ctx, mock.Anything).Return(nil, err)
				return mockClient
			},
			assert: func(t *testing.T, resp *model.SaleOrderResponse) {
				assert.Equal(t, true, resp.Response.Success)
				assert.Equal(t, http.StatusOK, resp.Code)
			},
		},
		{
			name: "success sale order service happy path",
			proxyService: func(t *testing.T, r *http.Request) proxy.ProxyService {
				response := &model.ProxyResponse{
					BodyBytes:  []byte(successBffUpdate(true, true, true)),
					StatusCode: 200,
				}
				proxySvc := proxyMock.NewProxyService(t)
				proxySvc.On("SendRequestToClient", r, mock.Anything, map[string]string{}).Return(response, nil)
				return proxySvc
			},
			configEndpoint: "/v1/bff/sale-orders/123456",
			funcToCall: func(s *Service, r *http.Request) *model.SaleOrderResponse {
				return s.UpdateSaleOrder(r, getUpdateSaleOrderPut(), "12345")
			},
			request:                getTestRequestUpdate(),
			iscallistoSOGRPCClient: true,
			callistoSOGRPCClient: func(t *testing.T, ctx context.Context) SOServiceClient {
				mockClient := orderMock.NewSOServiceClient(t)
				ctx = addLegacyIDToCtx(ctx, "12345")
				mockClient.Mock.On("AddNote", ctx, mock.Anything).Return(&SOProto.AddNoteResponse{Success: true}, nil)
				mockClient.Mock.On("AddShipment", ctx, mock.Anything).Return(&SOProto.AddShipmentResponse{ShipmentId: 12345}, nil)
				mockClient.Mock.On("AddDocument", ctx, mock.Anything).Return(&SOProto.AddDocumentResponse{Success: true}, nil)
				return mockClient
			},
			assert: func(t *testing.T, resp *model.SaleOrderResponse) {
				assert.Equal(t, true, resp.Response.Success)
				assert.Equal(t, http.StatusOK, resp.Code)
			},
		},
		{
			name: "error calling callisto api no bff",
			assert: func(t *testing.T, resp *model.SaleOrderResponse) {
				assert.Equal(t, false, resp.Response.Success)
				assert.Equal(t, http.StatusInternalServerError, resp.Code)
			},
			proxyService: func(t *testing.T, r *http.Request) proxy.ProxyService {
				proxySvc := proxyMock.NewProxyService(t)
				proxySvc.On("SendRequestToClient", r, mock.Anything, map[string]string{}).Return(nil, fmt.Errorf("server fail"))
				return proxySvc
			},
			callistoSOGRPCClient: func(t *testing.T, _ context.Context) SOServiceClient {
				mockClient := orderMock.NewSOServiceClient(t)
				return mockClient
			},
			configEndpoint: "/v1/sale-orders/123456",
			funcToCall: func(s *Service, r *http.Request) *model.SaleOrderResponse {
				return s.UpdateSaleOrder(r, &api.UpdateSaleOrderMultipartBody{}, "12345")
			},
			request: getTestRequestUpdate(),
		},
		{
			name: "success sale order service happy path no fbb api endpoint",
			proxyService: func(t *testing.T, r *http.Request) proxy.ProxyService {
				response := &model.ProxyResponse{
					BodyBytes:  []byte(successAPINoBFFUpdate()),
					StatusCode: 200,
				}
				proxySvc := proxyMock.NewProxyService(t)
				proxySvc.On("SendRequestToClient", r, mock.Anything, map[string]string{}).Return(response, nil)
				return proxySvc
			},
			configEndpoint: "/v1/sale-orders/123456",
			funcToCall: func(s *Service, r *http.Request) *model.SaleOrderResponse {
				return s.UpdateSaleOrder(r, getUpdateSaleOrderPut(), "12345")
			},
			request:                getTestRequestUpdate(),
			iscallistoSOGRPCClient: false,
			callistoSOGRPCClient: func(t *testing.T, ctx context.Context) SOServiceClient {
				mockClient := orderMock.NewSOServiceClient(t)
				return mockClient
			},
			assert: func(t *testing.T, resp *model.SaleOrderResponse) {
				assert.Equal(t, http.StatusOK, resp.Code)
			},
		},
	}

	for _, tt := range testSuite {
		t.Run(tt.name, func(t *testing.T) {
			t.Run(tt.name, func(t *testing.T) {
				config := &config.Config{}
				config.CallistoAPI.Host = "0.0.0.0"
				config.CallistoAPI.SaleOrder.Update = tt.configEndpoint
				config.CallistoSO.Enabled = tt.iscallistoSOGRPCClient
				proxyService := tt.proxyService(t, tt.request)
				s := NewSaleOrderService().
					SetProxyService(proxyService).
					SetLogger(xlogger.NoOpLogger{}).
					SetConfigs(config).
					SetCallistoSOGRPC(tt.callistoSOGRPCClient(t, context.Background()))
				resp := tt.funcToCall(s, tt.request)
				tt.assert(t, resp)
			})
		})
	}
}

func TestUpdateSaleOrderNetSuite(t *testing.T) {
	testSuite := []struct {
		name                   string
		assert                 func(*testing.T, *model.SaleOrderResponse)
		proxyService           func(*testing.T, *http.Request) proxy.ProxyService
		isCallistoSOGRPCClient bool
		callistoSOGRPCClient   func(t *testing.T, ctx context.Context) SOServiceClient
		funcToCall             func(*Service, *http.Request) *model.SaleOrderResponse
		configEndpoint         string
		request                *http.Request
	}{
		{
			name: "success sale order service happy path netsuite update",
			proxyService: func(t *testing.T, r *http.Request) proxy.ProxyService {
				response := &model.ProxyResponse{
					BodyBytes:  []byte(successBffUpdate(false, false, true)),
					StatusCode: 200,
				}
				proxySvc := proxyMock.NewProxyService(t)
				proxySvc.On("SendRequestToClient", r, mock.Anything, map[string]string{}).Return(response, nil)
				return proxySvc
			},
			configEndpoint: "/v1/bff/sale-orders/123456",
			funcToCall: func(s *Service, r *http.Request) *model.SaleOrderResponse {
				return s.UpdateSaleOrder(r, getUpdateSaleOrderPost(), "12345")
			},
			request:                getTestRequestUpdate(),
			isCallistoSOGRPCClient: true,
			callistoSOGRPCClient: func(t *testing.T, ctx context.Context) SOServiceClient {
				mockClient := orderMock.NewSOServiceClient(t)
				ctx = addLegacyIDToCtx(ctx, "12345")
				mockClient.Mock.On("GetInvoices", ctx, mock.Anything).Return(&SOProto.GetInvoicesResponse{Invoices: []*SOProto.Invoice{{Id: 123}}}, nil)
				mockClient.Mock.On("AddDocument", ctx, mock.Anything).Return(&SOProto.AddDocumentResponse{Success: true}, nil)
				mockClient.Mock.On("UpdateStatus", ctx, mock.Anything).Return(&SOProto.UpdateStatusResponse{StatusOld: 2, StatusNew: 3}, nil)
				return mockClient
			},
			assert: func(t *testing.T, resp *model.SaleOrderResponse) {
				assert.Equal(t, true, resp.Response.Success)
				assert.Equal(t, http.StatusOK, resp.Code)
			},
		},
		{
			name: "fail getting invoices",
			proxyService: func(t *testing.T, r *http.Request) proxy.ProxyService {
				response := &model.ProxyResponse{
					BodyBytes:  []byte(successBffUpdate(true, true, false)),
					StatusCode: 200,
				}
				proxySvc := proxyMock.NewProxyService(t)
				proxySvc.On("SendRequestToClient", r, mock.Anything, map[string]string{}).Return(response, nil)
				return proxySvc
			},
			configEndpoint: "/v1/bff/sale-orders/123456",
			funcToCall: func(s *Service, r *http.Request) *model.SaleOrderResponse {
				return s.UpdateSaleOrder(r, getUpdateSaleOrderPost(), "12345")
			},
			request:                getTestRequestUpdate(),
			isCallistoSOGRPCClient: true,
			callistoSOGRPCClient: func(t *testing.T, ctx context.Context) SOServiceClient {
				mockClient := orderMock.NewSOServiceClient(t)
				ctx = addLegacyIDToCtx(ctx, "12345")
				err := fmt.Errorf("error in grpc call")
				mockClient.Mock.On("GetInvoices", ctx, mock.Anything).Return(nil, err)
				return mockClient
			},
			assert: func(t *testing.T, resp *model.SaleOrderResponse) {
				assert.Equal(t, true, resp.Response.Success)
				assert.Equal(t, http.StatusOK, resp.Code)
			},
		},
		{
			name: "fail adding document",
			proxyService: func(t *testing.T, r *http.Request) proxy.ProxyService {
				response := &model.ProxyResponse{
					BodyBytes:  []byte(successBffUpdate(true, true, true)),
					StatusCode: 200,
				}
				proxySvc := proxyMock.NewProxyService(t)
				proxySvc.On("SendRequestToClient", r, mock.Anything, map[string]string{}).Return(response, nil)
				return proxySvc
			},
			configEndpoint: "/v1/bff/sale-orders/123456",
			funcToCall: func(s *Service, r *http.Request) *model.SaleOrderResponse {
				return s.UpdateSaleOrder(r, getUpdateSaleOrderPost(), "12345")
			},
			request:                getTestRequestUpdate(),
			isCallistoSOGRPCClient: true,
			callistoSOGRPCClient: func(t *testing.T, ctx context.Context) SOServiceClient {
				mockClient := orderMock.NewSOServiceClient(t)
				ctx = addLegacyIDToCtx(ctx, "12345")
				err := fmt.Errorf("error in grpc call")
				mockClient.Mock.On("GetInvoices", ctx, mock.Anything).Return(&SOProto.GetInvoicesResponse{Invoices: []*SOProto.Invoice{{Id: 123}}}, nil)
				mockClient.Mock.On("AddDocument", ctx, mock.Anything).Return(nil, err)
				return mockClient
			},
			assert: func(t *testing.T, resp *model.SaleOrderResponse) {
				assert.Equal(t, true, resp.Response.Success)
				assert.Equal(t, http.StatusOK, resp.Code)
			},
		},
		{
			name: "fail updating status",
			proxyService: func(t *testing.T, r *http.Request) proxy.ProxyService {
				response := &model.ProxyResponse{
					BodyBytes:  []byte(successBffUpdate(true, true, true)),
					StatusCode: 200,
				}
				proxySvc := proxyMock.NewProxyService(t)
				proxySvc.On("SendRequestToClient", r, mock.Anything, map[string]string{}).Return(response, nil)
				return proxySvc
			},
			configEndpoint: "/v1/bff/sale-orders/123456",
			funcToCall: func(s *Service, r *http.Request) *model.SaleOrderResponse {
				return s.UpdateSaleOrder(r, getUpdateSaleOrderPost(), "12345")
			},
			request:                getTestRequestUpdate(),
			isCallistoSOGRPCClient: true,
			callistoSOGRPCClient: func(t *testing.T, ctx context.Context) SOServiceClient {
				mockClient := orderMock.NewSOServiceClient(t)
				ctx = addLegacyIDToCtx(ctx, "12345")
				err := fmt.Errorf("error in grpc call")
				mockClient.Mock.On("GetInvoices", ctx, mock.Anything).Return(&SOProto.GetInvoicesResponse{Invoices: []*SOProto.Invoice{{Id: 123}}}, nil)
				mockClient.Mock.On("AddDocument", ctx, mock.Anything).Return(&SOProto.AddDocumentResponse{Success: true}, nil)
				mockClient.Mock.On("UpdateStatus", ctx, mock.Anything).Return(nil, err)
				return mockClient
			},
			assert: func(t *testing.T, resp *model.SaleOrderResponse) {
				assert.Equal(t, true, resp.Response.Success)
				assert.Equal(t, http.StatusOK, resp.Code)
			},
		},
	}

	for _, tt := range testSuite {
		t.Run(tt.name, func(t *testing.T) {
			t.Run(tt.name, func(t *testing.T) {
				config := &config.Config{}
				config.CallistoAPI.Host = "0.0.0.0"
				config.CallistoAPI.SaleOrder.Update = tt.configEndpoint
				config.CallistoSO.Enabled = tt.isCallistoSOGRPCClient
				proxyService := tt.proxyService(t, tt.request)
				s := NewSaleOrderService().
					SetProxyService(proxyService).
					SetLogger(xlogger.NoOpLogger{}).
					SetConfigs(config).
					SetCallistoSOGRPC(tt.callistoSOGRPCClient(t, context.Background()))
				resp := tt.funcToCall(s, tt.request)
				tt.assert(t, resp)
			})
		})
	}
}

func getUpdateSaleOrderPut() *api.UpdateSaleOrderMultipartBody {
	method := "PUT"
	note := "this is a note"
	docTypeId := uint32(1)
	shippedDate := "2022-12-05 00:00:00"
	collectDate := "2022-12-05 00:00:00"
	trackingCode := "this_is_tracking_code"
	shippingMethodID := uint64(1)
	trackingUrl := "http://tracking.com"
	noAirbill := int(1)
	courierName := "DHL"
	return &api.UpdateSaleOrderMultipartBody{
		Method:           &method,
		Note:             &note,
		DocTypeID:        &docTypeId,
		CollectDate:      &collectDate,
		CourierName:      &courierName,
		NoAirbill:        &noAirbill,
		ShippedDate:      &shippedDate,
		ShippingMethodID: &shippingMethodID,
		TrackingCode:     &trackingCode,
		TrackingURL:      &trackingUrl,
	}
}

func getUpdateSaleOrderPost() *api.UpdateSaleOrderMultipartBody {
	method := "POST"
	docType := "pi"
	status := uint32(SOProto.Status_STATUS_AWAITING_INVOICE)
	return &api.UpdateSaleOrderMultipartBody{
		Method: &method,
		Type:   &docType,
		Status: &status,
	}
}

func getTestRequestUpdate() *http.Request {
	jsonString := `{
		"doc_type_id": "1",
		"sale_order_doc": "/this_is_a_file.pdf",
 		"note": "this is a note"
	}`
	body := io.NopCloser(bytes.NewReader([]byte(jsonString)))
	httpRequest := httptest.NewRequest(http.MethodPut, "http://localhost.com/sale-order_12345", body)
	return httpRequest.WithContext(context.WithValue(httpRequest.Context(), proxy.LegacyOrderIDCtxValue{}, "12345"))
}

func successBffUpdate(withNote, withShipping, withDoc bool) string {
	var jsonNote, jsonShipment, jsonDoc string = "", "", ""
	if withNote {
		jsonNote = `,
        "note": {
            "details": "this is a note"
        }`
	}

	if withShipping {
		jsonShipment = `,
        "shipment": {
            "isCollection": true,
            "courierRef": "1",
            "trackingCode": "thi_is_tracking_code",
            "trackingUrl": "http://tracking.com",
            "dispatchedAt": "2022-12-05T00:00:00Z",
            "noWaybill": true
        }`
	}

	if withDoc {
		jsonDoc = `,
		"document": {
			"orderRef": "80013946",
			"documentType": "DOCTYPE_INVOICE_PROFORMA",
			"url": "sale_order/80013946/1701416426_this_is_a_file.pdf",
			"hash": "eb0a9fc064d0af4ff7dfb9a1f04140fddde6f440",
			"createdBy": "3"
		}`
	}
	jsonString := `{
		"_bff": {
			"order_ref": "80013946",
			"user_id": 3,
			"is_customer": false,
			"updated_at": "2023-12-01T07:40:26Z"%s%s%s
		},
		"success": true,
		"result": {
			"id": 80013946,
			"auction_id": null,
			"courier_id": null,
			"company_id": 2183,
			"currency_id": 3,
			"location_id": 14,
			"incoterm_id": 1,
			"shipping_address_id": 4143,
			"shipping_method_id": null,
			"promo_code_id": null,
			"jupiter_ref_no": "",
			"seller_po": null,
			"tax": "",
			"discount": null,
			"total": "96.97",
			"note": null,
			"status": 1,
			"shipped_date": null,
			"collect_date": null,
			"tracking_code": null,
			"tracking_url": null,
			"sku_release_time": null,
			"payment_overdue": null,
			"shipment_not_collected": null,
			"created_at": "2023-11-28T03:27:44.000000Z",
			"created_by": 3,
			"updated_at": "2023-11-28T03:27:44.000000Z",
			"updated_by": 3,
			"approval_admin1": 3,
			"approval_admin2": null,
			"no_airbill": 0,
			"require_approval": 0,
			"customer_po": "123123123",
			"backorder_id": 2697,
			"shipping_charge": "0.00"
		}
	}`
	return fmt.Sprintf(jsonString, jsonNote, jsonShipment, jsonDoc)
}

func successAPINoBFFUpdate() string {
	return `{
		"id": 80013946,
		"auction_id": null,
		"courier_id": null,
		"company_id": 2183,
		"currency_id": 3,
		"location_id": 14,
		"incoterm_id": 1,
		"shipping_address_id": 4143,
		"shipping_method_id": null,
		"promo_code_id": null,
		"jupiter_ref_no": "",
		"seller_po": null,
		"tax": "",
		"discount": null,
		"total": "96.97",
		"note": null,
		"status": 1,
		"shipped_date": null,
		"collect_date": null,
		"tracking_code": null,
		"tracking_url": null,
		"sku_release_time": null,
		"payment_overdue": null,
		"shipment_not_collected": null,
		"created_at": "2023-11-28T03:27:44.000000Z",
		"created_by": 3,
		"updated_at": "2023-11-28T03:27:44.000000Z",
		"updated_by": 3,
		"approval_admin1": 3,
		"approval_admin2": null,
		"no_airbill": 0,
		"require_approval": 0,
		"customer_po": "123123123",
		"backorder_id": 2697,
		"shipping_charge": "0.00"
	}`
}

func failBFFResponse() string {
	return `
	{
		"_bff": {
			"order_ref": "80013946",
			"user_id": "a poco si",
			"is_customer": "false",
			"updated_at": "2023-12-01T07:40:26Z"
		},
		"success": true,
		"result": {
			"id": 80013946,
			"auction_id": null,
			"courier_id": null,
			"company_id": 2183,
			"currency_id": 3,
			"location_id": 14,
			"incoterm_id": 1,
			"shipping_address_id": 4143,
			"shipping_method_id": null,
			"promo_code_id": null,
			"jupiter_ref_no": "",
			"seller_po": null,
			"tax": "",
			"discount": null,
			"total": "96.97",
			"note": null,
			"status": 1,
			"shipped_date": null,
			"collect_date": null,
			"tracking_code": null,
			"tracking_url": null,
			"sku_release_time": null,
			"payment_overdue": null,
			"shipment_not_collected": null,
			"created_at": "2023-11-28T03:27:44.000000Z",
			"created_by": 3,
			"updated_at": "2023-11-28T03:27:44.000000Z",
			"updated_by": 3,
			"approval_admin1": 3,
			"approval_admin2": null,
			"no_airbill": 0,
			"require_approval": 0,
			"customer_po": "123123123",
			"backorder_id": 2697,
			"shipping_charge": "0.00"
		}
	}`
}

func addLegacyIDToCtx(ctx context.Context, legacyID string) context.Context {
	return context.WithValue(ctx, proxy.LegacyOrderIDCtxValue{}, legacyID)
}
