package integration_test

import (
	"testing"

	v1 "github.com/AlchemyTelcoSolutions/callisto-so-bff/api/v1"
	"github.com/AlchemyTelcoSolutions/callisto-so-bff/cmd/app/config"
	"github.com/AlchemyTelcoSolutions/callisto-so-bff/integration_tests/app"
	"github.com/AlchemyTelcoSolutions/callisto-so-bff/integration_tests/expect"
	"github.com/AlchemyTelcoSolutions/callisto-so-bff/integration_tests/fakes"
	suiteclient "github.com/AlchemyTelcoSolutions/callisto-so-bff/integration_tests/suite-client"
	testclient "github.com/AlchemyTelcoSolutions/callisto-so-bff/integration_tests/test-client"
	"github.com/AlchemyTelcoSolutions/callisto-so-bff/internal/domain/model"
	"github.com/AlchemyTelcoSolutions/xutils-go/xlogger"
	"github.com/stretchr/testify/suite"
)

type saleOrderSummarySuite struct {
	suite.Suite
	Log             xlogger.Logger
	Server          *testclient.ServerClientBuilder
	ClientGenerator *suiteclient.ClientGenerator
}

func (s *saleOrderSummarySuite) TestSaleOrderSummary() {
	t := s.T()

	result := model.SaleOrderSummaryResponse{
		Status: model.SOSummaryStatusResponse{
			Details: []model.SOSummaryDetailResponse{},
			Groups:  model.SOSummaryGroupResponse{},
		},
	}

	tests := []struct {
		name    string
		caseAPI string
		cfg     config.Config
		assert  func(t *testing.T, resp *v1.Response)
	}{
		{
			name:    "SUCCESS_GET_SO_SUMMARY_FROM_CALLISTO_SO",
			caseAPI: fakes.Success,
			cfg: config.Config{
				CallistoSO: config.CallistoSOConfig{
					Enabled: true,
					Config: config.CallistoSORPCConfig{
						GetSOSummary: config.FeatureFlag{
							IsEnabled: true,
						},
					},
				},
				CallistoAPI: config.CallistoAPIConfig{
					Host:      "http://127.0.0.1:4000",
					SaleOrder: config.SaleOrderAPI{},
					Bids:      config.BidsAPI{},
					Auth: config.AuthAPI{
						Me: "/v1/auth/me/proxy/success",
					},
				},
			},
			assert: func(t *testing.T, resp *v1.Response) {
				expect.ValidateSOSummaryResponse(t, *resp, v1.Response{
					Result:  result,
					Success: true,
				})
			},
		},
		{
			name:    "SUCCESS_GET_SO_SUMMARY_FROM_API",
			caseAPI: fakes.SuccessProxy,
			cfg: config.Config{
				CallistoSO: config.CallistoSOConfig{
					Enabled: true,
					Config: config.CallistoSORPCConfig{
						GetSOSummary: config.FeatureFlag{
							IsEnabled: false,
						},
					},
				},
				HTTP: config.HTTPServerConfig{
					ApiPrefix:      "callisto",
					AllowedOrigins: nil,
					Proxy: config.Proxy{
						IsEnabled: true,
					},
				},
			},
			assert: func(t *testing.T, resp *v1.Response) {
				expect.ValidateSOSummaryResponse(t, *resp, v1.Response{
					Result:  result,
					Success: true,
				})
			},
		},
		{
			name:    "FAILED_GET_SO_SUMMARY_FROM_CALLISTO_SO_INVALID_ID",
			caseAPI: fakes.Success,
			cfg: config.Config{
				CallistoSO: config.CallistoSOConfig{
					Enabled: true,
					Config: config.CallistoSORPCConfig{
						GetSOSummary: config.FeatureFlag{
							IsEnabled: true,
						},
					},
				},
				CallistoAPI: config.CallistoAPIConfig{
					Host:      "http://127.0.0.1:4000",
					SaleOrder: config.SaleOrderAPI{},
					Bids:      config.BidsAPI{},
					Auth: config.AuthAPI{
						Me: "/v1/auth/me/proxy/success-0",
					},
				},
			},
			assert: func(t *testing.T, resp *v1.Response) {
				expect.BadRequestResponseError(t, *resp, v1.Response{
					Error: &map[string]interface{}{
						"message": "failed get summary to callisto-so",
					},
				})
			},
		},
		{
			name:    "FAILED_GET_SO_SUMMARY_FROM_API_UNAUTHORIZED",
			caseAPI: fakes.ErrorUnauthorized,
			cfg: config.Config{
				CallistoSO: config.CallistoSOConfig{
					Enabled: true,
					Config: config.CallistoSORPCConfig{
						GetSOSummary: config.FeatureFlag{
							IsEnabled: false,
						},
					},
				},
				CallistoAPI: config.CallistoAPIConfig{
					Host:      "http://127.0.0.1:4000",
					SaleOrder: config.SaleOrderAPI{},
					Bids:      config.BidsAPI{},
					Auth: config.AuthAPI{
						Me: "/v1/auth/me/proxy/unauthorized",
					},
				},
			},
			assert: func(t *testing.T, resp *v1.Response) {
				expect.BadRequestResponseError(t, *resp, v1.Response{
					Error: &map[string]interface{}{
						"code":    float64(401),
						"message": "Unauthorized",
					},
				})
			},
		},
		{
			name:    "FAILED_GET_SO_SUMMARY_FROM_API_ERROR",
			caseAPI: fakes.APIFailed,
			cfg: config.Config{
				CallistoSO: config.CallistoSOConfig{
					Enabled: true,
					Config: config.CallistoSORPCConfig{
						GetSOSummary: config.FeatureFlag{
							IsEnabled: false,
						},
					},
				},
				CallistoAPI: config.CallistoAPIConfig{
					Host:      "http://127.0.0.1:4000",
					SaleOrder: config.SaleOrderAPI{},
					Bids:      config.BidsAPI{},
					Auth: config.AuthAPI{
						Me: "/v1/auth/me/proxy/failed",
					},
				},
			},
			assert: func(t *testing.T, resp *v1.Response) {
				expect.BadRequestResponseError(t, *resp, v1.Response{
					Error: &map[string]interface{}{
						"code":    float64(500),
						"message": "error from api",
					},
				})
			},
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			// setup new testApp
			testApp := app.NewTestApp(&test.cfg, s.Log)

			// build new server with custom config
			server := s.Server.SetTestApp(testApp).SetAppConfig(&test.cfg).Build()

			// create suite client by custom server
			cli := suiteclient.NewClientGenerator(server).NewClient(t)

			resp := cli.GetSOSummary(test.caseAPI)
			test.assert(t, resp)
		})
	}
}
