package contact

import (
	"context"
	"fmt"

	lark "github.com/larksuite/oapi-sdk-go/v3"
	larkcontact "github.com/larksuite/oapi-sdk-go/v3/service/contact/v3"
)

func New(larkCli *lark.Client) Contact {
	return &client{
		larkCli: larkCli,
	}
}

type client struct {
	larkCli *lark.Client
}

func (c *client) BatchGetUsers(ctx context.Context, userIds []string) ([]*larkcontact.User, error) {
	users := make([]*larkcontact.User, 0, len(userIds))
	for i := 0; i < len(userIds); i = i + 50 {
		end := i + 50
		if end > len(userIds) {
			end = len(userIds)
		}
		req := larkcontact.NewBatchUserReqBuilder().
			UserIds(userIds[i:end]).
			UserIdType("user_id").
			DepartmentIdType("department_id").
			Build()
		resp, err := c.larkCli.Contact.User.Batch(ctx, req)
		if err != nil {
			return nil, fmt.Errorf("fail to batch get lark users, err: %w", err)
		}
		if !resp.Success() {
			return nil, fmt.Errorf("fail to batch get lark users, code: %d, message: %s", resp.Code, resp.Msg)
		}
		users = append(users, resp.Data.Items...)
	}
	return users, nil
}

func (c *client) BetchGetUserIds(ctx context.Context, emails []string) ([]*larkcontact.UserContactInfo, error) {
	userContactInfos := make([]*larkcontact.UserContactInfo, 0, len(emails))
	for i := 0; i < len(emails); i = i + 50 {
		end := i + 50
		if end > len(emails) {
			end = len(emails)
		}
		req := larkcontact.NewBatchGetIdUserReqBuilder().
			UserIdType("user_id").
			Body(larkcontact.NewBatchGetIdUserReqBodyBuilder().Emails(emails[i:end]).Build()).
			Build()
		resp, err := c.larkCli.Contact.User.BatchGetId(ctx, req)
		if err != nil {
			return nil, fmt.Errorf("fail to batch get lark user ids, err: %w", err)
		}
		if !resp.Success() {
			return nil, fmt.Errorf("fail to batch get lark user ids, code: %d, message: %s", resp.Code, resp.Msg)
		}
		userContactInfos = append(userContactInfos, resp.Data.UserList...)
	}
	return userContactInfos, nil
}

func (c *client) GetUser(ctx context.Context, userId string) (*larkcontact.User, error) {
	req := larkcontact.NewGetUserReqBuilder().
		UserId(userId).
		UserIdType("user_id").
		DepartmentIdType("department_id").
		Build()
	resp, err := c.larkCli.Contact.User.Get(context.Background(), req)
	if err != nil {
		return nil, fmt.Errorf("get user's information %s via lark api: %w", userId, err)
	}
	if !resp.Success() {
		return nil, fmt.Errorf("get user's information %s via lark api, code: %d, msg: %s", userId, resp.Code, resp.Msg)
	}
	return resp.Data.User, nil
}
