package auth

import (
	"errors"
	"net/http"
	"net/http/httptest"
	"reflect"
	"testing"

	"github.com/AlchemyTelcoSolutions/callisto-so-bff/cmd/app/config"
	"github.com/AlchemyTelcoSolutions/callisto-so-bff/internal/domain/model"
	proxy_mock "github.com/AlchemyTelcoSolutions/callisto-so-bff/internal/proxy/mocks"
	"github.com/AlchemyTelcoSolutions/xutils-go/xlogger"
	"github.com/stretchr/testify/mock"
)

func TestService_AuthMeByRequest(t *testing.T) {
	mockProxy := proxy_mock.NewProxyService(t)

	httpRequest := httptest.NewRequest(http.MethodGet, "http://localhost.com/v1/sale-orders/summary", nil)

	type args struct {
		req *http.Request
	}
	tests := []struct {
		name    string
		args    args
		want    *model.AuthMeResponse
		wantErr bool
		fn      func()
	}{
		{
			name:    "ShouldError_FailedSendRequestToClient",
			args:    args{req: httpRequest},
			want:    nil,
			wantErr: true,
			fn: func() {
				mockProxy.Mock.On("SendRequestToClient", mock.Anything, "/v1/auth/me", mock.Anything).Return(nil, errors.New("failed")).Once()
			},
		},
		{
			name:    "ShouldError_SuccessToClient_ButNot2xx",
			args:    args{req: httpRequest},
			want:    nil,
			wantErr: true,
			fn: func() {
				mockProxy.Mock.On("SendRequestToClient", mock.Anything, "/v1/auth/me", mock.Anything).Return(&model.ProxyResponse{
					StatusCode: http.StatusBadRequest,
					BodyBytes:  []byte(""),
				}, nil).Once()
			},
		},
		{
			name:    "ShouldError_SuccessToClient_FailedUnmarshal",
			args:    args{req: httpRequest},
			want:    nil,
			wantErr: true,
			fn: func() {
				mockProxy.Mock.On("SendRequestToClient", mock.Anything, "/v1/auth/me", mock.Anything).Return(&model.ProxyResponse{
					StatusCode: http.StatusOK,
					BodyBytes:  []byte(`{"company_id": "x"}`),
				}, nil).Once()
			},
		},
		{
			name: "Success",
			args: args{req: httpRequest},
			want: &model.AuthMeResponse{
				CompanyId: uint64(123),
			},
			wantErr: false,
			fn: func() {
				mockProxy.Mock.On("SendRequestToClient", mock.Anything, "/v1/auth/me", mock.Anything).Return(&model.ProxyResponse{
					StatusCode: http.StatusOK,
					BodyBytes:  []byte(`{"company_id": 123}`),
				}, nil).Once()
			},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			tt.fn()

			s := NewAuthService().
				SetLogger(xlogger.NoOpLogger{}).
				SetProxyService(mockProxy).
				SetConfigs(&config.Config{
					CallistoAPI: config.CallistoAPIConfig{
						Auth: config.AuthAPI{
							Me: "/v1/auth/me",
						}},
				})

			got, err := s.AuthMeByRequest(tt.args.req)
			if (err != nil) != tt.wantErr {
				t.Errorf("AuthMeByRequest() error = %v, wantErr %v", err, tt.wantErr)
				return
			}
			if !reflect.DeepEqual(got, tt.want) {
				t.Errorf("AuthMeByRequest() got = %v, want %v", got, tt.want)
			}
		})
	}
}
