// SPDX-License-Identifier: GPL-3.0-or-later

// Package output provides table formatting utilities.
package output

import (
	"io"
	"strings"

	"github.com/olekukonko/tablewriter"
)

// Table represents a table for output.
type Table struct {
	headers []string
	rows    [][]string
	writer  io.Writer
	colors  *Colors
	narrow  bool
}

// NewTable creates a new table.
func NewTable(writer io.Writer, colors *Colors) *Table {
	return &Table{
		writer: writer,
		colors: colors,
	}
}

// SetHeaders sets the table headers.
func (t *Table) SetHeaders(headers ...string) *Table {
	t.headers = headers
	return t
}

// AddRow adds a row to the table.
func (t *Table) AddRow(row ...string) *Table {
	t.rows = append(t.rows, row)
	return t
}

// SetNarrow enables narrow mode (fewer columns).
func (t *Table) SetNarrow(narrow bool) *Table {
	t.narrow = narrow
	return t
}

// Render renders the table.
func (t *Table) Render() {
	if len(t.rows) == 0 {
		return
	}

	tw := tablewriter.NewWriter(t.writer)

	// Configure table style
	tw.SetAutoWrapText(false)
	tw.SetAutoFormatHeaders(false)
	tw.SetHeaderAlignment(tablewriter.ALIGN_LEFT)
	tw.SetAlignment(tablewriter.ALIGN_LEFT)
	tw.SetCenterSeparator("")
	tw.SetColumnSeparator("  ")
	tw.SetRowSeparator("")
	tw.SetHeaderLine(false)
	tw.SetBorder(false)
	tw.SetTablePadding("  ")
	tw.SetNoWhiteSpace(true)

	// Set headers
	if len(t.headers) > 0 {
		tw.SetHeader(t.headers)
	}

	// Add rows
	for _, row := range t.rows {
		tw.Append(row)
	}

	tw.Render()
}

// RenderPlain renders a plain text version (for scripting).
func (t *Table) RenderPlain(delim string) {
	for _, row := range t.rows {
		line := strings.Join(row, delim)
		if _, err := io.WriteString(t.writer, line+"\n"); err != nil {
			return
		}
	}
}

// TableBuilder provides a fluent interface for building tables.
type TableBuilder struct {
	renderer *Renderer
	table    *Table
}

// NewTableBuilder creates a new table builder.
func NewTableBuilder(r *Renderer) *TableBuilder {
	return &TableBuilder{
		renderer: r,
		table:    NewTable(r.writer, r.colors),
	}
}

// Headers sets the table headers.
func (b *TableBuilder) Headers(headers ...string) *TableBuilder {
	b.table.SetHeaders(headers...)
	return b
}

// Row adds a row.
func (b *TableBuilder) Row(cells ...string) *TableBuilder {
	b.table.AddRow(cells...)
	return b
}

// Narrow enables narrow mode.
func (b *TableBuilder) Narrow() *TableBuilder {
	b.table.SetNarrow(true)
	return b
}

// Render renders the table based on format.
func (b *TableBuilder) Render() {
	switch b.renderer.format {
	case FormatJSON:
		// JSON output is handled elsewhere
	case FormatPlain:
		b.table.RenderPlain("\t")
	default:
		b.table.Render()
	}
}
