package service

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

	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"

	"github.com/UpmeshLTD/urus-aio/infrastructure/db/entities"
	"github.com/UpmeshLTD/urus-aio/mdm/server/grpc/pb"
)

type iGRPC interface {
	Ping(ctx context.Context, req *pb.PingRequest) (*pb.PingResponse, error)
	GetCountryByID(ctx context.Context, req *pb.GetCountryByIDRequest) (*pb.GetCountryResponse, error)
	GetCountryByCode(ctx context.Context, req *pb.GetCountryByCodeRequest) (*pb.GetCountryResponse, error)
	GetAddressByID(ctx context.Context, req *pb.GetAddressByIDRequest) (*pb.GetAddressByIDResponse, error)
}

func (s *serviceImpl) Ping(ctx context.Context, req *pb.PingRequest) (*pb.PingResponse, error) {
	info := utils.GetInfo(s.cfg.IsDevelopment())
	return &pb.PingResponse{
		Timestamps:  info["timestamps"].(int64),
		Environment: info["environment"].(string),
		Hostname:    info["hostname"].(string),
	}, nil
}

func (s *serviceImpl) GetCountryByID(ctx context.Context, req *pb.GetCountryByIDRequest) (*pb.GetCountryResponse, error) {
	country, err := s.locationDomain.GetCountryByID(ctx, req.Id)
	if err != nil {
		return nil, status.Error(codes.NotFound, "country not found")
	}
	return &pb.GetCountryResponse{
		CountryId:         country.ID.ToInt64(),
		InternationalName: country.InternationalName,
		LocalizedName:     country.LocalizedName,
		Code:              country.Code,
	}, err
}

func (s *serviceImpl) GetCountryByCode(ctx context.Context, req *pb.GetCountryByCodeRequest) (*pb.GetCountryResponse, error) {
	country, err := s.locationDomain.GetCountryByCode(ctx, req.Code)
	if err != nil {
		return nil, status.Error(codes.NotFound, "country not found")
	}
	return &pb.GetCountryResponse{
		CountryId:         country.ID.ToInt64(),
		InternationalName: country.InternationalName,
		LocalizedName:     country.LocalizedName,
		Code:              country.Code,
	}, err
}

func (s *serviceImpl) GetAddressByID(ctx context.Context, req *pb.GetAddressByIDRequest) (*pb.GetAddressByIDResponse, error) {
	address, err := s.addressDomain.GetAddressByID(ctx, entities.IDFromInt64(req.AddressID))
	if err != nil {
		return nil, status.Error(codes.NotFound, "address not found")
	}

	subLevelLocations := make([]*pb.SubLevelLocation, 0)
	for _, v := range address.SubLevelLocations {
		subLevelLocations = append(subLevelLocations, &pb.SubLevelLocation{
			InternationalName: v.InternationalName,
			LocalizedName:     v.LocalizedName,
		})
	}

	return &pb.GetAddressByIDResponse{
		Address1:          address.Address1,
		Address2:          address.Address2,
		PostalCode:        address.PostalCode,
		CountryID:         address.CountryID,
		UnitNumber:        address.UnitNumber,
		SubLevelLocations: subLevelLocations,
	}, err
}
