package organizationimp

import (
	"context"

	api "github.com/tech/sendico/pkg/api/http"
	"github.com/tech/sendico/pkg/auth"
	"github.com/tech/sendico/pkg/db/invitation"
	"github.com/tech/sendico/pkg/db/organization"
	"github.com/tech/sendico/pkg/mlogger"
	"github.com/tech/sendico/pkg/mservice"
	eapi "github.com/tech/sendico/server/interface/api"
	"github.com/tech/sendico/server/interface/services/fileservice"
	mutil "github.com/tech/sendico/server/internal/mutil/param"
	"go.uber.org/zap"
)

type OrganizationAPI struct {
	logger   mlogger.Logger
	db       organization.DB
	idb      invitation.DB
	images   mservice.MicroService
	enforcer auth.Enforcer
}

func (a *OrganizationAPI) Name() mservice.Type {
	return mservice.Organizations
}

func (a *OrganizationAPI) Finish(ctx context.Context) error {
	return a.images.Finish(ctx)
}

func CreateAPI(a eapi.API) (*OrganizationAPI, error) {
	p := new(OrganizationAPI)
	p.logger = a.Logger().Named(p.Name())
	p.enforcer = a.Permissions().Enforcer()
	var err error
	if p.db, err = a.DBFactory().NewOrganizationDB(); err != nil {
		p.logger.Error("Failed to create organizations database", zap.Error(err))
		return nil, err
	}
	if p.idb, err = a.DBFactory().NewInvitationsDB(); err != nil {
		p.logger.Error("Failed to create invitations database", zap.Error(err))
		return nil, err
	}

	a.Register().AccountHandler(mservice.Organizations, "", api.Get, p.list)
	a.Register().AccountHandler(mservice.Organizations, mutil.AddOrganizaztionRef("/"), api.Get, p.get)
	a.Register().AccountHandler(mservice.Organizations, "", api.Put, p.update)
	a.Register().AccountHandler(mservice.Organizations, mutil.AddInvitationRef("/invitation"), api.Get, p.invitation)

	if p.images, err = fileservice.CreateAPI(a, p.Name()); err != nil {
		p.logger.Error("Failed to create image server", zap.Error(err))
		return nil, err
	}

	return p, nil
}
