package progress

import (
	"fmt"
	"time"

	"gitbase.de/apairon/mark2web/pkg/helper"
	"gitbase.de/apairon/mark2web/pkg/logger"
	"github.com/gosuri/uiprogress"
	"github.com/mattn/go-tty"
)

type bar struct {
	Bar         *uiprogress.Bar
	Description string
}

var bars = make(map[string]*bar)
var initialized = false
var terminalWidth = 80

// OverallTotal is number of total jobs
var OverallTotal = 0

// OverallDone is number of done jobs
var OverallDone = 0

func init() {
	updateLoggerPrefix()
}

// Start initializes the bar drawing
func Start() {
	if t, err := tty.Open(); err == nil && t != nil {
		terminalWidth, _, _ = t.Size()
		t.Close()
	}
	uiprogress.Start() // start rendering
	initialized = true
}

func updateLoggerPrefix() {
	logger.Prefix = fmt.Sprintf("%3d/%3d: ", OverallDone, OverallTotal)
}

// IncrTotal increases the total jobs for the bar
func IncrTotal(barname string) {
	OverallTotal++
	updateLoggerPrefix()

	if initialized {
		_bar := bars[barname]
		if _bar == nil {
			_bar = new(bar)
			_bar.Bar = uiprogress.AddBar(1)
			_bar.Bar.Width = 25

			_bar.Bar.PrependFunc(func(b *uiprogress.Bar) string {
				return fmt.Sprintf("%15s: %3d/%3d", helper.ShortenStringLeft(barname, 15), b.Current(), b.Total)
			})
			_bar.Bar.AppendFunc(func(b *uiprogress.Bar) string {
				return fmt.Sprintf("%s", helper.ShortenStringLeft(_bar.Description, terminalWidth-80))
			})

			bars[barname] = _bar
		} else {
			_bar.Bar.Total++
		}
	}
}

// IncrDone increases to done jobs counter
func IncrDone(barname string) {
	OverallDone++
	updateLoggerPrefix()

	if initialized {
		bars[barname].Bar.Incr()
		bars[barname].Description = ""
	}
}

// DescribeCurrent describes the current job
func DescribeCurrent(barname, description string) {
	if initialized {
		bars[barname].Description = description
	}
}

// Stop stops the bar drawing
func Stop() {
	if initialized {
		time.Sleep(time.Millisecond * 200)
		uiprogress.Stop()
	}
}
