package k8sresource

import (
	"bytes"
	"strings"

	regionalpb "github.com/tidbcloud/infra-provider/api/tidbcloud/regional-server/v1"
	bizerr "github.com/tidbcloud/infra-provider/regional-server/pkg/common/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/cli-runtime/pkg/printers"
	"sigs.k8s.io/yaml"
)

func marshalDetailYAML(single *unstructured.Unstructured, list *unstructured.UnstructuredList, gvk schema.GroupVersionKind) (string, error) {
	if single != nil {
		data, err := yaml.Marshal(single.Object)
		if err != nil {
			return "", bizerr.New(bizerr.MarshalError, err.Error())
		}
		return string(data), nil
	}
	if list == nil {
		return "", nil
	}
	items := make([]any, 0, len(list.Items))
	for i := range list.Items {
		items = append(items, list.Items[i].Object)
	}
	listObj := map[string]any{
		"apiVersion": gvk.GroupVersion().String(),
		"kind":       gvk.Kind + "List",
		"items":      items,
	}
	if strings.TrimSpace(gvk.Group) == "" {
		listObj["apiVersion"] = gvk.Version
	}
	data, err := yaml.Marshal(listObj)
	if err != nil {
		return "", bizerr.New(bizerr.MarshalError, err.Error())
	}
	return string(data), nil
}

func marshalDetailWithEventsYAML(single *resourceWithEvents, list []resourceWithEvents) (string, error) {
	if single != nil {
		data, err := yaml.Marshal(single)
		if err != nil {
			return "", bizerr.New(bizerr.MarshalError, err.Error())
		}
		return string(data), nil
	}
	data, err := yaml.Marshal(list)
	if err != nil {
		return "", bizerr.New(bizerr.MarshalError, err.Error())
	}
	return string(data), nil
}

func marshalSummaryText(table *metav1.Table, opts printers.PrintOptions) (string, error) {
	if table == nil {
		return "", nil
	}
	opts.Wide = true
	var buf bytes.Buffer
	printer := printers.NewTablePrinter(opts)
	if err := printer.PrintObj(table, &buf); err != nil {
		return "", bizerr.New(bizerr.MarshalError, err.Error())
	}
	return buf.String(), nil
}

func detailYAMLResponse(content string, itemCount int32, truncated bool, hints string) *regionalpb.ListK8SResourcesResponse {
	return &regionalpb.ListK8SResourcesResponse{
		ContentType: regionalpb.ContentType_YAML,
		Content:     content,
		Truncated:   truncated,
		Hints:       hints,
		ItemCount:   itemCount,
	}
}

func summaryTextResponse(content string, itemCount int32, truncated bool, hints string) *regionalpb.ListK8SResourcesResponse {
	return &regionalpb.ListK8SResourcesResponse{
		ContentType: regionalpb.ContentType_TEXT,
		Content:     content,
		Truncated:   truncated,
		Hints:       hints,
		ItemCount:   itemCount,
	}
}
