package service

import (
	"context"

	"git.gocasts.ir/ebhomengo/niki/domain/benefactor/entity"
	richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
	"git.gocasts.ir/ebhomengo/niki/pkg/types"
)

type Repository interface {
	Create(ctx context.Context, b entity.Benefactor) (entity.Benefactor, error)
	GetBenefactorByID(ctx context.Context, benefactorID types.ID) (entity.Benefactor, error)
	Activate(ctx context.Context, benefactorID types.ID) error
	Deactivate(ctx context.Context, benefactorID types.ID) error
}

type Service struct {
	repo Repository
}

func New(repo Repository) Service {
	return Service{repo: repo}
}

func (s Service) CreateBenefactor(ctx context.Context, req CreateBenefactorRequest) (CreateBenefactorResponse, error) {
	const op = "beneafactorservice.CreateBenefactor"

	benefactor := entity.Benefactor{
		ID: 0,
		FirstName: req.FirstName,
		LastName: req.LastName,
		PhoneNumber: req.PhoneNumber,
		Description: req.Description,
		Email: req.Email,
		Gender: req.Gender,
		BirthDate: req.BirthDate,
		Status: entity.BenefactorActiveStatus,
	}

	createdBenefactor, err := s.repo.Create(ctx, benefactor)
	if err != nil {
		return CreateBenefactorResponse{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected)
	}

	return CreateBenefactorResponse{
		Name: createdBenefactor.FirstName + " " + createdBenefactor.LastName,
		Email: createdBenefactor.Email,
	}, nil
}

func(s Service) Profile(ctx context.Context, req ProfileRequest) (ProfileResponse, error) {
	const op = "benefactorservice.Profile"

	benefactor, err := s.repo.GetBenefactorByID(ctx, types.ID(req.BenefactorID))
	if err != nil {
		return ProfileResponse{}, richerror.New(op).WithErr(err).
													WithMeta(map[string]interface{}{"req": req})
	}

	return ProfileResponse{Name: benefactor.FirstName + " " + benefactor.LastName}, nil

}

func (s Service) Activate(ctx context.Context, req ActivenessRequest) error {
	const op = "benefactorservice.Activate"

	err := s.repo.Activate(ctx, types.ID(req.BenefactorID))
	if err != nil {
		return richerror.New(op).WithErr(err).
				WithKind(richerror.KindUnexpected)
	}

	return nil
}

func (s Service) Dectivate(ctx context.Context, req ActivenessRequest) error {
	const op = "benefactorservice.Deactivate"

	err := s.repo.Deactivate(ctx, types.ID(req.BenefactorID))
	if err != nil {
		return richerror.New(op).WithErr(err).
				WithKind(richerror.KindUnexpected)
	}

	return nil
}