package courier

import (
	"context"
	"github.com/UpmeshLTD/urus-aio/infrastructure/utils"

	"github.com/UpmeshLTD/urus-aio/shipment/config"

	"github.com/UpmeshLTD/urus-aio/infrastructure/db/entities"
)

type Service interface {
	GetCourier(ctx context.Context, params *entities.GetCourierParams) (*entities.Courier, error)
	GetCouriers(ctx context.Context, params *entities.GetCouriersParams) ([]*entities.Courier, error)
	GetCourierByID(ctx context.Context, id entities.ID) (*entities.Courier, error)
	CreateCourier(ctx context.Context, params *entities.Courier) (*entities.Courier, error)
	UpdateCourier(ctx context.Context, id entities.ID, entity *entities.Courier) error
	DeleteCourier(ctx context.Context, id entities.ID) error

	GetCouriersByWorkspaceID(ctx context.Context, params *entities.GetSellerCouriersParams) ([]*entities.SellerCourier, error)
	GetSellerCourierByID(ctx context.Context, id entities.ID) (*entities.SellerCourier, error)
	GetSellerCourier(ctx context.Context, workspaceID string, courierID int64) (*entities.SellerCourier, error)
	CreateSellerCourier(ctx context.Context, entity *entities.SellerCourier) (*entities.SellerCourier, error)
	UpdateSellerCourier(ctx context.Context, id entities.ID, entity *entities.SellerCourier) error
	UpdateSellerCourierStatus(ctx context.Context, id entities.ID, deactivate bool) error
	UpdateSellerCourierVerifyStatus(ctx context.Context, id entities.ID, verified bool) error
	DeleteSellerCourier(ctx context.Context, id entities.ID) error
	SaveSellerCourier(ctx context.Context, entity *entities.SellerCourier) (*entities.SellerCourier, error)
}

type serviceImpl struct {
	repo Repository
	cfg  config.Config
}

func NewService(repo Repository, cfg config.Config) Service {
	return &serviceImpl{
		repo: repo,
		cfg:  cfg,
	}
}

func (s *serviceImpl) GetCourier(ctx context.Context, params *entities.GetCourierParams) (*entities.Courier, error) {
	return s.repo.GetCourier(ctx, params)
}

func (s *serviceImpl) GetCouriers(ctx context.Context, params *entities.GetCouriersParams) ([]*entities.Courier, error) {
	return s.repo.GetCouriers(ctx, params)
}

func (s *serviceImpl) GetCourierByID(ctx context.Context, id entities.ID) (*entities.Courier, error) {
	return s.repo.GetCourierByID(ctx, id)
}

func (s *serviceImpl) CreateCourier(ctx context.Context, params *entities.Courier) (*entities.Courier, error) {
	return s.repo.CreateCourier(ctx, params)
}

func (s *serviceImpl) UpdateCourier(ctx context.Context, id entities.ID, entity *entities.Courier) error {
	return s.repo.UpdateCourier(ctx, id, entity)
}

func (s *serviceImpl) DeleteCourier(ctx context.Context, id entities.ID) error {
	return s.repo.DeleteCourier(ctx, id)
}

func (s *serviceImpl) GetCouriersByWorkspaceID(ctx context.Context, params *entities.GetSellerCouriersParams) ([]*entities.SellerCourier, error) {
	return s.repo.GetCouriersByWorkspaceID(ctx, params)
}

func (s *serviceImpl) GetSellerCourier(ctx context.Context, workspaceID string, courierID int64) (*entities.SellerCourier, error) {
	sellerCourier, err := s.repo.GetSellerCourier(ctx, workspaceID, courierID)
	if err != nil {
		return nil, err
	}
	sellerCourier.RawCourierAuthenticationInfo = utils.Decrypt(s.cfg.GetShipmentProviderConfig().ShipmentEncryptPassphrase, sellerCourier.CourierAuthenticationInfo, []byte(sellerCourier.Salt))
	return sellerCourier, nil
}

func (s *serviceImpl) CreateSellerCourier(ctx context.Context, entity *entities.SellerCourier) (*entities.SellerCourier, error) {
	return s.repo.CreateSellerCourier(ctx, entity)
}

func (s *serviceImpl) SaveSellerCourier(ctx context.Context, entity *entities.SellerCourier) (*entities.SellerCourier, error) {
	return s.repo.SaveSellerCourier(ctx, entity)
}

func (s *serviceImpl) UpdateSellerCourier(ctx context.Context, id entities.ID, entity *entities.SellerCourier) error {
	return s.repo.UpdateSellerCourier(ctx, id, entity)
}

func (s *serviceImpl) UpdateSellerCourierStatus(ctx context.Context, id entities.ID, deactivate bool) error {
	return s.repo.UpdateSellerCourierStatus(ctx, id, deactivate)
}

func (s *serviceImpl) UpdateSellerCourierVerifyStatus(ctx context.Context, id entities.ID, verified bool) error {
	return s.repo.UpdateSellerCourierVerifyStatus(ctx, id, verified)
}

func (s *serviceImpl) DeleteSellerCourier(ctx context.Context, id entities.ID) error {
	return s.repo.DeleteSellerCourier(ctx, id)
}

func (s *serviceImpl) GetSellerCourierByID(ctx context.Context, id entities.ID) (*entities.SellerCourier, error) {
	sc, err := s.repo.GetSellerCourierByID(ctx, id)
	if err != nil {
		return nil, err
	}
	sc.RawCourierAuthenticationInfo = utils.Decrypt(s.cfg.GetShipmentProviderConfig().ShipmentEncryptPassphrase, sc.CourierAuthenticationInfo, []byte(sc.Salt))
	return sc, nil
}
