package controller

import (
	"errors"
	"net/http/httptest"
	"testing"

	"github.com/go-playground/validator/v10"
	"github.com/gofiber/fiber/v2"
	entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
	service "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/services"
	validation "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/validations"
	"gorm.io/gorm"
)

type stubProductWarehouseService struct {
	lastQuery *validation.Query
}

func (s *stubProductWarehouseService) GetAll(_ *fiber.Ctx, params *validation.Query) ([]entity.ProductWarehouse, int64, error) {
	s.lastQuery = params
	return []entity.ProductWarehouse{}, 0, nil
}

func (s *stubProductWarehouseService) GetOne(_ *fiber.Ctx, _ uint) (*entity.ProductWarehouse, error) {
	return nil, gorm.ErrRecordNotFound
}

var _ service.ProductWarehouseService = (*stubProductWarehouseService)(nil)

func TestGetAllParsesLocationID(t *testing.T) {
	app := fiber.New()
	stub := &stubProductWarehouseService{}
	ctrl := NewProductWarehouseController(stub)
	app.Get("/product-warehouses", ctrl.GetAll)

	req := httptest.NewRequest("GET", "/product-warehouses?location_id=16&kandang_id=59&limit=25&search=tektrol&available_only=true", nil)
	resp, err := app.Test(req)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if resp.StatusCode != fiber.StatusOK {
		t.Fatalf("expected status 200, got %d", resp.StatusCode)
	}
	if stub.lastQuery == nil {
		t.Fatalf("expected service to receive query")
	}
	if stub.lastQuery.LocationId != 16 {
		t.Fatalf("expected location_id 16, got %d", stub.lastQuery.LocationId)
	}
	if stub.lastQuery.KandangId != 59 {
		t.Fatalf("expected kandang_id 59, got %d", stub.lastQuery.KandangId)
	}
	if stub.lastQuery.Limit != 25 {
		t.Fatalf("expected limit 25, got %d", stub.lastQuery.Limit)
	}
	if stub.lastQuery.Search != "tektrol" {
		t.Fatalf("expected search tektrol, got %s", stub.lastQuery.Search)
	}
	if !stub.lastQuery.AvailableOnly {
		t.Fatalf("expected available_only true")
	}
}

func TestStubImplementsServiceContract(t *testing.T) {
	validate := validator.New()
	if validate == nil {
		t.Fatal(errors.New("validator should not be nil"))
	}
}
