package main

import (
	"context"
	"image/color"
	"log"

	uv "github.com/charmbracelet/ultraviolet"
	"github.com/charmbracelet/ultraviolet/screen"
)

var (
	gray       = color.RGBA{R: 104, G: 104, B: 104, A: 255} // #686868
	white      = color.RGBA{R: 180, G: 180, B: 180, A: 255} // #b4b4b4
	yellow     = color.RGBA{R: 180, G: 180, B: 16, A: 255}  // #b4b416
	cyan       = color.RGBA{R: 16, G: 180, B: 180, A: 255}  // #10b4b4
	green      = color.RGBA{R: 16, G: 180, B: 16, A: 255}   // #10b410
	magenta    = color.RGBA{R: 180, G: 16, B: 180, A: 255}  // #b410b4
	red        = color.RGBA{R: 180, G: 16, B: 16, A: 255}   // #b41010
	blue       = color.RGBA{R: 16, G: 16, B: 180, A: 255}   // #1010b4
	black      = color.RGBA{R: 16, G: 16, B: 16, A: 255}    // #101010
	fullWhite  = color.RGBA{R: 235, G: 235, B: 235, A: 255} // #ebebeb
	fullBlack  = color.RGBA{R: 0, G: 0, B: 0, A: 255}       // #000000
	lightBlack = color.RGBA{R: 26, G: 26, B: 26, A: 255}    // #1a1a1a
	purple     = color.RGBA{R: 72, G: 16, B: 116, A: 255}   // #481074
	brown      = color.RGBA{R: 106, G: 52, B: 16, A: 255}   // #6a3410
	navy       = color.RGBA{R: 16, G: 70, B: 106, A: 255}   // #10466a
)

func main() {
	t := uv.DefaultTerminal()
	scr := t.Screen()

	if err := t.Start(); err != nil {
		log.Fatalf("Error starting terminal: %v", err)
	}

	defer t.Stop()

	scr.EnterAltScreen()

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	const barCount = 7
	const botBarCount = 6
	rowColors := [3][]color.RGBA{
		0: {
			0: white,
			1: yellow,
			2: cyan,
			3: green,
			4: magenta,
			5: red,
			6: blue,
		},
		1: {
			0: blue,
			1: black,
			2: magenta,
			3: black,
			4: cyan,
			5: black,
			6: white,
		},
		2: {
			0: navy,
			1: fullWhite,
			2: purple,
			3: black,
			4: black,
			5: black,
		},
	}

	display := func() {
		screen.Clear(scr)

		area := scr.Bounds()
		topRow := uv.Rect(0, 0, area.Max.X, (area.Max.Y*66)/100)
		midRow := uv.Rect(0, topRow.Max.Y, area.Max.X, (area.Max.Y*8)/100)
		botRow := uv.Rect(0, midRow.Max.Y, area.Max.X, (area.Max.Y*26)/100)

		barWidth := topRow.Max.X / barCount
		for i, row := range []uv.Rectangle{
			topRow, midRow,
		} {
			for j := 0; j < barCount; j++ {
				bar := uv.Rect(j*barWidth, row.Min.Y, (j+1)*barWidth, row.Max.Y)
				cell := uv.EmptyCell
				cell.Style.Bg = rowColors[i][j%len(rowColors[i])]
				screen.FillArea(scr, &cell, bar)
			}
		}

		botBarWidth := botRow.Max.X / botBarCount
		for i := 0; i < botBarCount; i++ {
			bar := uv.Rect(i*botBarWidth, botRow.Min.Y, (i+1)*botBarWidth, botRow.Max.Y)
			cell := uv.EmptyCell
			cell.Style.Bg = rowColors[2][i%len(rowColors[2])]
			screen.FillArea(scr, &cell, bar)
		}

		// Special case for the before last bar
		const specialRow = 5
		subBarWidth := barWidth / 3
		for i := 0; i < 3; i++ {
			bar := uv.Rect(specialRow*barWidth+i*subBarWidth, botRow.Min.Y, subBarWidth, botRow.Max.Y)
			cell := uv.EmptyCell
			switch i {
			case 0:
				cell.Style.Bg = fullBlack
			case 1:
				continue
			case 2:
				cell.Style.Bg = lightBlack
			}
			screen.FillArea(scr, &cell, bar)
		}

		scr.Render()
		scr.Flush()
	}

	// initial render
	display()

LOOP:
	for {
		select {
		case <-ctx.Done():
			break LOOP
		case ev := <-t.Events():
			switch ev := ev.(type) {
			case uv.WindowSizeEvent:
				scr.Resize(ev.Width, ev.Height)
				display()
			case uv.KeyPressEvent:
				switch {
				case ev.MatchString("q", "ctrl+c"):
					cancel()
				}
			}
		}
	}
}
