package output

import (
	"bytes"
	"fmt"
	"io"

	"git.bissendorf.co/bissendorf/unifood/m/v2/core/interfaces"
	"git.bissendorf.co/bissendorf/unifood/m/v2/util"
	"github.com/jedib0t/go-pretty/table"
)

type tableRenderFormat string

const (
	tableFormatNormal   tableRenderFormat = "table"
	tableFormatCSV      tableRenderFormat = "csv"
	tableFormatHTML     tableRenderFormat = "html"
	tableFormatMarkdown tableRenderFormat = "markdown"
)

type TableFormatter struct {
	HideSummary  bool
	RenderFormat tableRenderFormat
}

func (f *TableFormatter) Format(list *interfaces.ResourceList) (io.Reader, error) {

	var buffer = make([]byte, 0, 1024)
	outputBuffer := bytes.NewBuffer(buffer)

	if !f.HideSummary {
		outputBuffer.WriteString(
			fmt.Sprintf("Resource: %s\r\nCount: %v\r\n\r\n", list.ItemKind, len(list.Items)),
		)
	}

	if len(list.Items) <= 0 {
		return outputBuffer, nil
	}

	// Setup table
	t := table.NewWriter()
	t.SetOutputMirror(outputBuffer)
	t.SetStyle(table.StyleLight)

	// Write header
	tableFormat, ok := list.Items[0].(interfaces.TableOutput)
	headerRow := []any{"Name"}
	if ok {
		columnHeaders := util.Transform(tableFormat.ColumnNames(), func(i *string) any { return *i })
		headerRow = append(headerRow, columnHeaders...)
	}
	t.AppendHeader(headerRow)

	// Write rows
	for _, item := range list.Items {
		rowOutput := []any{item.ItemName()}

		itemFormatter, ok := item.(interfaces.TableOutput)
		if ok {
			rowOutput = append(rowOutput, itemFormatter.Columns()...)
		}

		t.AppendRow(rowOutput)
	}

	// Render
	switch f.RenderFormat {
	case tableFormatCSV:
		t.RenderCSV()
	case tableFormatHTML:
		t.RenderHTML()
	case tableFormatMarkdown:
		t.RenderMarkdown()
	default:
		t.Render()
	}

	return outputBuffer, nil
}
