package iostreams

import (
	"fmt"
	"strings"
	"text/tabwriter"
)

// TablePrinter prints TTY-aware tables. In TTY mode it uses aligned columns with
// bold headers. In pipe mode it emits tab-separated values without headers.
type TablePrinter struct {
	ios     *IOStreams
	headers []string
	rows    [][]string
}

// NewTablePrinter creates a TablePrinter that writes to ios.Out.
func NewTablePrinter(ios *IOStreams) *TablePrinter {
	return &TablePrinter{
		ios: ios,
	}
}

// AddHeader sets the column headers. Headers are only displayed in TTY mode.
func (t *TablePrinter) AddHeader(headers ...string) {
	t.headers = headers
}

// AddRow appends a row of fields to the table.
func (t *TablePrinter) AddRow(fields ...string) {
	t.rows = append(t.rows, fields)
}

// Render writes the table to the IOStreams output. In TTY mode it uses tabwriter
// with bold headers. In pipe mode it emits tab-separated values without headers.
func (t *TablePrinter) Render() error {
	if !t.ios.IsStdoutTTY() {
		// Pipe mode: tab-separated, no headers
		for _, row := range t.rows {
			if _, err := fmt.Fprintln(t.ios.Out, strings.Join(row, "\t")); err != nil {
				return err
			}
		}
		return nil
	}

	// TTY mode: use tabwriter with aligned columns
	w := tabwriter.NewWriter(t.ios.Out, 0, 0, 2, ' ', 0)

	if len(t.headers) > 0 {
		cs := t.ios.ColorScheme()
		boldHeaders := make([]string, len(t.headers))
		for i, h := range t.headers {
			boldHeaders[i] = cs.Bold(h)
		}
		fmt.Fprintln(w, strings.Join(boldHeaders, "\t"))
	}

	for _, row := range t.rows {
		fmt.Fprintln(w, strings.Join(row, "\t"))
	}

	return w.Flush()
}
