//go:build end2end

package end2end

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"testing"

	"git.gocasts.ir/ebhomengo/niki/delivery/http_server/end2end/setup"
	benefactorkindboxparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box"
	"github.com/stretchr/testify/suite"
)

type BenefactorKindBoxTestSuite struct {
	suite.Suite
	benefactorPhone        string
	benefactorID           uint
	kindBoxID              uint
	kindBboxGetAllExpected map[string]interface{}
	kindBoxGetExpected     benefactorkindboxparam.KindBoxGetResponse
}

func TestBenefactorKindBoxTestSuite(t *testing.T) {
	suite.Run(t, new(BenefactorKindBoxTestSuite))
}

func (suite *BenefactorKindBoxTestSuite) SetupTest() {
	teardown := setup.SeedMariaDB(testContainer.GetMariaDBConfig())
	suite.T().Cleanup(teardown)
	suite.benefactorPhone = "09384664404"
	suite.benefactorID = 1
	suite.kindBoxID = 1
	suite.kindBboxGetAllExpected = map[string]interface{}{
		"count": 1,
	}
}

// Test for GET /benefactor/kindboxes (Get All Kind Boxes)
func (suite *BenefactorKindBoxTestSuite) TestBenefactorKindBoxGetAll() {
	suite.Run("Success", func() {
		token := LoginBenefactor(suite.benefactorPhone)
		url := fmt.Sprintf("/benefactors/kindboxes")
		responseRecord := CreateRequest("GET", url, token, nil)
		suite.Require().Equal(http.StatusOK, responseRecord.Code)

		var response benefactorkindboxparam.KindBoxGetAllResponse
		err := json.NewDecoder(responseRecord.Body).Decode(&response)
		suite.Require().NoError(err, "could not decode response")
		suite.Require().Equal(suite.kindBboxGetAllExpected["count"], len(response.Data))
	})

	suite.Run("Failure_Unauthorized", func() {
		url := fmt.Sprintf("/benefactors/kindboxes")
		responseRecord := CreateRequest("GET", url, "invalid_token", nil)
		suite.Require().Equal(http.StatusUnauthorized, responseRecord.Code)
	})
}

// Test for GET /benefactor/kindboxes/:id (Get Single Kind Box)
func (suite *BenefactorKindBoxTestSuite) TestBenefactorKindBoxGet() {
	suite.Run("Success", func() {
		token := LoginBenefactor(suite.benefactorPhone)
		url := fmt.Sprintf("/benefactors/kindboxes/%d", suite.kindBoxID)
		responseRecord := CreateRequest("GET", url, token, nil)
		suite.Require().Equal(http.StatusOK, responseRecord.Code)

		var response benefactorkindboxparam.KindBoxGetResponse
		err := json.NewDecoder(responseRecord.Body).Decode(&response)
		suite.Require().NoError(err, "could not decode response body")

		kindBox, sErr := services.BenefactorKindBoxSvc.Get(context.Background(),
			benefactorkindboxparam.KindBoxGetRequest{
				BenefactorID: suite.benefactorID,
				KindBoxID:    suite.kindBoxID,
			})
		suite.Require().NoError(sErr, "failed to get benefactor kind box")

		suite.Require().Equal(kindBox.Data.ID, response.Data.ID)
		suite.Require().Equal(kindBox.Data.KindBoxReqID, response.Data.KindBoxReqID)
		suite.Require().Equal(kindBox.Data.BenefactorID, response.Data.BenefactorID)
		suite.Require().Equal(kindBox.Data.KindBoxType, response.Data.KindBoxType)
		suite.Require().Equal(kindBox.Data.Amount, response.Data.Amount)
		suite.Require().Equal(kindBox.Data.SerialNumber, response.Data.SerialNumber)
		suite.Require().Equal(kindBox.Data.Status, response.Data.Status)
		suite.Require().Equal(kindBox.Data.DeliverReferTimeID, response.Data.DeliverReferTimeID)
		suite.Require().Equal(kindBox.Data.DeliverReferDate, response.Data.DeliverReferDate)
	})

	suite.Run("Failure_NotFound", func() {
		token := LoginBenefactor(suite.benefactorPhone)
		url := fmt.Sprintf("/benefactors/kindboxes/%d", 9999) // Non-existent ID
		responseRecord := CreateRequest("GET", url, token, nil)
		suite.Require().Equal(http.StatusUnprocessableEntity, responseRecord.Code)
	})

	suite.Run("Failure_Unauthorized", func() {
		url := fmt.Sprintf("/benefactors/kindboxes/%d", suite.kindBoxID)
		responseRecord := CreateRequest("GET", url, "invalid_token", nil)
		suite.Require().Equal(http.StatusUnauthorized, responseRecord.Code)
	})
}
