package mods

import (
	"context"

	"github.com/gin-gonic/gin"
	"github.com/google/wire"
	"github.guxuan/haibei/internal/mods/activity"
	"github.guxuan/haibei/internal/mods/app"
	"github.guxuan/haibei/internal/mods/common"
	"github.guxuan/haibei/internal/mods/customer"
	"github.guxuan/haibei/internal/mods/point"
	"github.guxuan/haibei/internal/mods/product"
	"github.guxuan/haibei/internal/mods/rbac"
)

const (
	apiPrefix = "/api/"
)

// Collection of wire providers
var Set = wire.NewSet(
	wire.Struct(new(Mods), "*"),
	rbac.Set,
	customer.Set,
	common.Set,
	product.Set,
	activity.Set,
	point.Set,
	app.Set,
)

type Mods struct {
	RBAC     *rbac.RBAC
	Customer *customer.Customer
	Common   *common.Common
	Product  *product.Product
	Activity *activity.Activity
	Point    *point.Point
	App      *app.App
}

func (a *Mods) Init(ctx context.Context) error {
	if err := a.RBAC.Init(ctx); err != nil {
		return err
	}
	if err := a.Customer.Init(ctx); err != nil {
		return err
	}
	if err := a.Common.Init(
		ctx); err != nil {
		return err
	}
	if err := a.Product.Init(ctx); err != nil {
		return err
	}
	if err := a.Activity.Init(ctx); err != nil {
		return err
	}
	if err := a.Point.Init(
		ctx,
	); err != nil {
		return err
	}
	if err := a.App.Init(ctx); err != nil {
		return err
	}

	return nil
}

func (a *Mods) RouterPrefixes() []string {
	return []string{
		apiPrefix,
	}
}

func (a *Mods) RegisterRouters(ctx context.Context, e *gin.Engine) error {
	gAPI := e.Group(apiPrefix)
	v1 := gAPI.Group("v1")

	if err := a.RBAC.RegisterV1Routers(ctx, v1); err != nil {
		return err
	}
	if err := a.Customer.RegisterV1Routers(ctx,
		v1,
	); err != nil {
		return err
	}
	if err := a.Common.RegisterV1Routers(ctx, v1); err != nil {
		return err
	}
	if err := a.Product.RegisterV1Routers(ctx, v1); err != nil {
		return err
	}
	if err := a.Activity.RegisterV1Routers(ctx,
		v1,
	); err != nil {
		return err
	}
	if err := a.Point.RegisterV1Routers(ctx, v1); err != nil {
		return err
	}
	if err := a.App.RegisterV1Routers(ctx, v1); err != nil {
		return err
	}

	return nil
}

func (a *Mods) Release(ctx context.Context) error {
	if err := a.RBAC.Release(ctx); err != nil {
		return err
	}
	if err := a.Customer.Release(ctx); err != nil {
		return err
	}
	if err := a.Common.Release(ctx); err != nil {
		return err
	}
	if err := a.Product.Release(ctx); err != nil {
		return err
	}
	if err := a.Activity.Release(ctx); err != nil {
		return err
	}
	if err := a.Point.Release(ctx); err != nil {
		return err
	}
	if err := a.App.Release(
		ctx); err != nil {
		return err
	}
	if err := a.Product.Release(ctx); err != nil {
		return err
	}

	return nil
}
