package customer

import (
	"context"
	"google.golang.org/protobuf/types/known/timestamppb"
	"log"
	"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/repository"

	"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/customer"
	"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/service/history"
)

type Deps struct {
	Logger         *zap.Logger
	HistoryService *history.Service
	AccountRepo    *repository.AccountRepository
}

type Controller struct {
	logger         *zap.Logger
	historyService *history.Service
	accountRepo    *repository.AccountRepository
	customer.UnimplementedCustomerServiceServer
}

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

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

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

	return &Controller{
		logger:         deps.Logger,
		historyService: deps.HistoryService,
		accountRepo:    deps.AccountRepo,
	}
}

func (receiver *Controller) InsertHistory(ctx context.Context, in *customer.History) (*emptypb.Empty, error) {
	if _, err := receiver.historyService.CreateHistory(ctx, &models.History{
		UserID:  in.UserID,
		Comment: in.Comment,
		Key:     in.Key,
		//RawDetails: in.RawDetails,
	}); err != nil {
		receiver.logger.Error("failed to insert history on <InsertHistory> of <HistoryController>", zap.Error(err))
		return nil, errors.GRPC("failed to insert history", err)
	}

	return &emptypb.Empty{}, nil
}

func (receiver *Controller) SetAccountVerificationStatus(ctx context.Context, req *customer.SetVerificationReq) (*customer.Account, error) {
	status := customer.AccountStatus_name[int32(req.Status)]
	account, err := receiver.accountRepo.SetStatus(ctx, req.UserID, models.AccountStatus(status))
	if err != nil {
		receiver.logger.Error("failed to set status on <SetAccountVerificationStatus> of <RPC_CustomerController>", zap.Error(err))
		return nil, err
	}

	var deletedAt *timestamppb.Timestamp
	if account.DeletedAt != nil {
		deletedAt = timestamppb.New(*account.DeletedAt)
	}

	return &customer.Account{
		Id:     account.ID,
		UserID: account.UserID,
		Cart:   account.Cart,
		Wallet: &customer.Wallet{
			Cash:            account.Wallet.Cash,
			Currency:        account.Wallet.Currency,
			Spent:           account.Wallet.Spent,
			PurchasesAmount: account.Wallet.PurchasesAmount,
			Money:           account.Wallet.Money,
			LastPaymentId:   account.Wallet.LastPaymentID,
		},
		Name: &customer.Name{
			Middlename: account.Name.Middlename,
			Firstname:  account.Name.FirstName,
			Orgname:    account.Name.Orgname,
			Secondname: account.Name.Secondname,
		},
		Status:    customer.AccountStatus(customer.AccountStatus_value[string(account.Status)]),
		IsDeleted: account.Deleted,
		CreatedAt: timestamppb.New(account.CreatedAt),
		UpdatedAt: timestamppb.New(account.UpdatedAt),
		DeletedAt: deletedAt,
		From:      account.From,
		Partner:   account.Partner,
	}, nil
}
