package lake

import (
	"context"
	"strings"

	"github.com/tidbcloud/aisupport/services/jsm-syncer/config"
)

type Client interface {
	Configured() bool
	ListLakes(ctx context.Context, opts ListOptions) (LakePage, error)
	ListMemberships(ctx context.Context, opts ListOptions) (MembershipPage, error)
}

type ListOptions struct {
	Page     int
	PageSize int
}

type LakePage struct {
	Lakes []Lake
	Total int
}

type MembershipPage struct {
	Memberships []Membership
	Total       int
}

type Lake struct {
	ID     string
	Name   string
	Tier   string
	OrgID  string
	Status string
}

type Membership struct {
	LakeID string
	UserID string
	Status string
}

type mockClient struct {
	enabled     bool
	lakes       []Lake
	memberships []Membership
}

func NewMockClient(conf config.LakeMockConfig) Client {
	lakes := make([]Lake, 0, len(conf.Lakes))
	for _, item := range conf.Lakes {
		lake := Lake{
			ID:     strings.TrimSpace(item.ID),
			Name:   strings.TrimSpace(item.Name),
			Tier:   strings.TrimSpace(item.Tier),
			OrgID:  strings.TrimSpace(item.OrgID),
			Status: strings.TrimSpace(item.Status),
		}
		if lake.ID == "" {
			continue
		}
		lakes = append(lakes, lake)
	}

	memberships := make([]Membership, 0, len(conf.Memberships))
	for _, item := range conf.Memberships {
		membership := Membership{
			LakeID: strings.TrimSpace(item.LakeID),
			UserID: strings.TrimSpace(item.UserID),
			Status: strings.TrimSpace(item.Status),
		}
		if membership.LakeID == "" || membership.UserID == "" {
			continue
		}
		memberships = append(memberships, membership)
	}

	return &mockClient{
		enabled:     conf.Enabled,
		lakes:       lakes,
		memberships: memberships,
	}
}

func (c *mockClient) Configured() bool {
	return c != nil && c.enabled
}

func (c *mockClient) ListLakes(ctx context.Context, opts ListOptions) (LakePage, error) {
	if !c.Configured() {
		return LakePage{}, nil
	}
	lakes := paginate(c.lakes, opts)
	return LakePage{
		Lakes: append([]Lake(nil), lakes...),
		Total: len(c.lakes),
	}, nil
}

func (c *mockClient) ListMemberships(ctx context.Context, opts ListOptions) (MembershipPage, error) {
	if !c.Configured() {
		return MembershipPage{}, nil
	}
	memberships := paginate(c.memberships, opts)
	return MembershipPage{
		Memberships: append([]Membership(nil), memberships...),
		Total:       len(c.memberships),
	}, nil
}

func paginate[T any](items []T, opts ListOptions) []T {
	page := opts.Page
	if page <= 0 {
		page = 1
	}
	pageSize := opts.PageSize
	if pageSize <= 0 {
		pageSize = len(items)
	}
	if pageSize <= 0 {
		return nil
	}

	start := (page - 1) * pageSize
	if start >= len(items) {
		return nil
	}
	end := start + pageSize
	if end > len(items) {
		end = len(items)
	}
	return items[start:end]
}
