package products

import (
	"fmt"
	pb "sipro-mps/api/generated/v1/wb/products"
	"sipro-mps/internal/marketplace"
	"sipro-mps/pkg/utils"

	"google.golang.org/grpc"
)

type AdapterGRPC struct {
	pb.UnimplementedProductsServiceServer
	repo Repository
}

func NewAdapterGRPC(repo Repository) *AdapterGRPC {
	return &AdapterGRPC{
		repo: repo,
	}
}

func RegisterAdapterGRPC(server *grpc.Server, marketplacesRepository marketplace.Repository) (*Repository, error) {
	repo := NewAPIRepository(marketplacesRepository)
	adapter := NewAdapterGRPC(repo)
	pb.RegisterProductsServiceServer(server, adapter)
	return &repo, nil
}
func (a *AdapterGRPC) GetProducts(req *pb.GetProductsRequest, stream pb.ProductsService_GetProductsServer) error {
	ctx := stream.Context()
	resultChan := make(chan []pb.Product, 10)
	errChan := make(chan error)
	go a.repo.StreamAllProductsCache(ctx, int(req.MarketplaceId), resultChan, errChan)
	for {
		select {
		case <-ctx.Done():
			fmt.Println("context done")
			return ctx.Err()
		case products, ok := <-resultChan:
			if !ok {
				fmt.Println("result channel closed")
				return nil
			}
			resp := &pb.GetProductsResponse{
				Products: utils.ToPtrs(products),
			}
			if err := stream.Send(resp); err != nil {
				fmt.Println("error sending response", err)
				return err
			}
		case err, ok := <-errChan:
			if !ok {
				return nil
			}
			if ok && err != nil {
				fmt.Println("error in channel", err)
				return err
			}
		}

	}
}
