package tui

import (
	"context"
	"fmt"
	"sync/atomic"
	"time"

	"github.com/gdamore/tcell/v2"
	"github.com/rivo/tview"
)

type LoadingBar struct {
	*tview.Box
	view           *tview.TextView
	secondsElapsed atomic.Int64
	needDrawFunc   func()
	reset          func()
}

func NewLoadingBar(needDrawFunc func()) *LoadingBar {
	b := &LoadingBar{
		Box:          tview.NewBox(),
		view:         tview.NewTextView(),
		needDrawFunc: needDrawFunc,
	}
	b.view.SetBackgroundColor(tview.Styles.PrimaryTextColor)
	b.view.SetTextColor(b.GetBackgroundColor())

	return b
}

func (b *LoadingBar) Start(ctx context.Context) {
	ctx, b.reset = context.WithCancel(ctx)

	go func() {
		ticker := time.NewTicker(1 * time.Second)
		defer ticker.Stop()

		b.secondsElapsed.Store(0)
		for {
			select {
			case <-ctx.Done():
				return
			case <-ticker.C:
				b.secondsElapsed.Add(1)
				b.needDrawFunc()
			}
		}
	}()
}

func (b *LoadingBar) Stop() {
	b.reset()
}

func (b *LoadingBar) Draw(screen tcell.Screen) {
	seconds := b.secondsElapsed.Load()

	var time string
	switch {
	case seconds < 60:
		time = fmt.Sprintf("%ds", seconds)
	default:
		time = fmt.Sprintf("%dm%ds", seconds/60, seconds%60)
	}
	b.view.SetText(fmt.Sprintf(" Loading... %s (press Escape to cancel) ", time))

	x, y, width, _ := b.GetInnerRect()
	b.view.SetRect(x, y, width, 1)
	b.view.Draw(screen)
}