package expenses

import (
	"context"
	"fmt"

	"github.com/go-playground/validator/v10"
	"github.com/gofiber/fiber/v2"
	"gorm.io/gorm"

	commonRepo "gitlab.com/mbugroup/lti-api.git/internal/common/repository"
	commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
	rExpense "gitlab.com/mbugroup/lti-api.git/internal/modules/expenses/repositories"
	sExpense "gitlab.com/mbugroup/lti-api.git/internal/modules/expenses/services"
	rUser "gitlab.com/mbugroup/lti-api.git/internal/modules/users/repositories"
	sUser "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services"

	rNonstock "gitlab.com/mbugroup/lti-api.git/internal/modules/master/nonstocks/repositories"
	rSupplier "gitlab.com/mbugroup/lti-api.git/internal/modules/master/suppliers/repositories"
	rProjectFlockKandang "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"

	"gitlab.com/mbugroup/lti-api.git/internal/utils"
)

type ExpenseModule struct{}

func (ExpenseModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validate *validator.Validate) {
	expenseRepo := rExpense.NewExpenseRepository(db)
	userRepo := rUser.NewUserRepository(db)
	supplierRepo := rSupplier.NewSupplierRepository(db)
	nonstockRepo := rNonstock.NewNonstockRepository(db)
	approvalRepo := commonRepo.NewApprovalRepository(db)
	realizationRepo := rExpense.NewExpenseRealizationRepository(db)
	projectFlockKandangRepo := rProjectFlockKandang.NewProjectFlockKandangRepository(db)
	documentRepo := commonRepo.NewDocumentRepository(db)

	approvalSvc := commonSvc.NewApprovalService(approvalRepo)
	documentSvc, err := commonSvc.NewDocumentServiceFromConfig(context.Background(), documentRepo)
	if err != nil {
		panic(fmt.Sprintf("failed to create document service: %v", err))
	}

	// Register workflow steps for EXPENSES approval
	if err := approvalSvc.RegisterWorkflowSteps(utils.ApprovalWorkflowExpense, utils.ExpenseApprovalSteps); err != nil {
		panic(fmt.Sprintf("failed to register expense approval workflow: %v", err))
	}

	expenseService := sExpense.NewExpenseService(expenseRepo, supplierRepo, nonstockRepo, approvalSvc, realizationRepo, projectFlockKandangRepo, documentSvc, validate)
	userService := sUser.NewUserService(userRepo, validate)

	ExpenseRoutes(router, userService, expenseService)
}
