package payment

import (
	"context"
	"github.com/themakers/hlog"
	"log"

	"go.uber.org/zap"
	"google.golang.org/protobuf/types/known/emptypb"
	"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
	"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
	"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/proto/payment_callback"
	"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/service/callback"
)

type Deps struct {
	Logger                 *zap.Logger
	PaymentCallbackService *callback.PaymentCallbackService
	HLogger                hlog.Logger
}

type Controller struct {
	logger                 *zap.Logger
	paymentCallbackService *callback.PaymentCallbackService
	hLogger                hlog.Logger
}

func New(deps Deps) *Controller {
	if deps.Logger == nil {
		log.Panicln("logger is nil on <NewPaymentController>")
	}

	if deps.PaymentCallbackService == nil {
		log.Panicln("PaymentCallbackService is nil on <NewPaymentController>")
	}

	return &Controller{
		logger:                 deps.Logger,
		paymentCallbackService: deps.PaymentCallbackService,
		hLogger:                deps.HLogger,
	}
}

func (receiver *Controller) OnSuccess(ctx context.Context, in *payment_callback.Event) (*emptypb.Empty, error) {
	if err := receiver.paymentCallbackService.SuccessEvent(ctx, &models.PaymentEvent{
		Key:       in.Key,
		Message:   in.Message,
		PaymentID: in.Payment.PaymentID,
		Currency:  in.Payment.Currency,
		Amount:    in.Payment.Amount,
		UserID:    in.Payment.UserID,
		Type:      in.Payment.Type,
	}); err != nil {
		receiver.logger.Error("failed to send success event on <OnSuccess> of <PaymentController>", zap.Error(err))
		return nil, errors.GRPC("failed to send success event", err)
	}

	receiver.hLogger.Emit(models.InfoMoneyIncome{
		CtxUserID:      in.Payment.UserID,
		CtxPrice:       int64(in.Payment.Amount),
		KeyCurrency:    in.Payment.Currency,
		CtxID:          in.Payment.PaymentID,
		KeyPaymentType: in.Payment.Type,
	})

	return &emptypb.Empty{}, nil
}

func (receiver *Controller) OnFailure(ctx context.Context, in *payment_callback.Event) (*emptypb.Empty, error) {
	if err := receiver.paymentCallbackService.FailureEvent(ctx, &models.PaymentEvent{
		Key:       in.Key,
		Message:   in.Message,
		PaymentID: in.Payment.PaymentID,
		Currency:  in.Payment.Currency,
		Amount:    in.Payment.Amount,
		UserID:    in.Payment.UserID,
	}); err != nil {
		receiver.logger.Error("failed to send failure event on <OnFailure> of <PaymentController>", zap.Error(err))
		return nil, errors.GRPC("failed to send failure event", err)
	}

	return &emptypb.Empty{}, nil
}
