package paid_order

import (
	"context"

	paidorderpb "github.com/UpmeshLTD/urus-aio/paid-order/server/grpc/pb"
	"github.com/UpmeshLTD/urus-aio/shipment/config"
	"github.com/UpmeshLTD/urus-aio/shipment/log"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
)

type Service interface {
	GetPaidOrders(ctx context.Context, request *paidorderpb.GetPaidOrdersRequest) (*paidorderpb.GetPaidOrderResponse, error)
	UpdatePaidOrderIncorrectInformation(ctx context.Context, request *paidorderpb.UpdatePaidOrderIncorrectInformationRequest) error
	UpdatePaidOrderShipmentId(ctx context.Context, request *paidorderpb.UpdatePaidOrderShipmentIdRequest) error
	GetFulfillment(ctx context.Context, request *paidorderpb.GetFulfillmentRequest) (*paidorderpb.GetFulfillmentResponse, error)
	UpdateFulfillmentDraftStatus(ctx context.Context, request *paidorderpb.UpdateFulfillmentDraftStatusRequest) error
	CancelArrangedShipPaidOrder(ctx context.Context, request *paidorderpb.CancelArrangedShipPaidOrderRequest) error
	ReArrangeShipPaidOrders(ctx context.Context, request *paidorderpb.ReArrangeShipPaidOrdersRequest) (*paidorderpb.ReArrangeShipPaidOrdersResponse, error)
}

type serviceImpl struct {
	cc     *grpc.ClientConn
	client paidorderpb.PaidOrderServiceClient
	logger log.Logger
}

func NewService(cfg config.Config, logger log.Logger) (Service, error) {
	address := cfg.GetGRPCConfig().PaidOrderAddress
	cc, err := grpc.Dial(
		address,
		grpc.WithTransportCredentials(insecure.NewCredentials()))

	if err != nil {
		logger.Errorw("initializing Paid Order client failed", "address", address, "error", err)
		return nil, err
	}

	client := paidorderpb.NewPaidOrderServiceClient(cc)

	return &serviceImpl{
		cc:     cc,
		client: client,
		logger: logger,
	}, nil
}

func (s *serviceImpl) GetPaidOrders(ctx context.Context, request *paidorderpb.GetPaidOrdersRequest) (*paidorderpb.GetPaidOrderResponse, error) {
	return s.client.GetPaidOrders(ctx, request)
}

func (s *serviceImpl) UpdatePaidOrderIncorrectInformation(ctx context.Context, request *paidorderpb.UpdatePaidOrderIncorrectInformationRequest) error {
	_, err := s.client.UpdatePaidOrderIncorrectInformation(ctx, request)
	return err
}

func (s *serviceImpl) UpdatePaidOrderShipmentId(ctx context.Context, request *paidorderpb.UpdatePaidOrderShipmentIdRequest) error {
	_, err := s.client.UpdatePaidOrderShipmentId(ctx, request)
	return err
}

func (s *serviceImpl) GetFulfillment(ctx context.Context, request *paidorderpb.GetFulfillmentRequest) (*paidorderpb.GetFulfillmentResponse, error) {
	return s.client.GetFulfillmentByID(ctx, request)
}

func (s *serviceImpl) UpdateFulfillmentDraftStatus(ctx context.Context, request *paidorderpb.UpdateFulfillmentDraftStatusRequest) error {
	_, err := s.client.UpdateFulfillmentDraftStatus(ctx, request)
	return err
}

func (s *serviceImpl) CancelArrangedShipPaidOrder(ctx context.Context, request *paidorderpb.CancelArrangedShipPaidOrderRequest) error {
	_, err := s.client.CancelArrangedShipPaidOrder(ctx, request)
	return err
}

func (s *serviceImpl) ReArrangeShipPaidOrders(ctx context.Context, request *paidorderpb.ReArrangeShipPaidOrdersRequest) (*paidorderpb.ReArrangeShipPaidOrdersResponse, error) {
	return s.client.ReArrangeShipPaidOrders(ctx, request)
}
