package main

import (
	"fmt"
	"math/rand"
	"sync"
)

var (
	promet     float64
	stNarocil  int
	mutex      sync.Mutex
	printMutex sync.Mutex
)

type narocilo interface {
	obdelaj()
}

type izdelek struct {
	imeIzdelka string
	cena       float64
	teza       float64
}

type eknjiga struct {
	naslovKnjige string
	cena         float64
}

type spletniTecaj struct {
	imeTecaja   string
	trajanjeUre int
	cenaUre     float64
}

func (i izdelek) obdelaj() {
	printMutex.Lock()
	stNarocil++
	fmt.Printf("Številka naročila: %d\n", stNarocil)
	fmt.Println("Ime izdelka:", i.imeIzdelka)
	fmt.Printf("Cena: %.2f €\n", i.cena)
	fmt.Printf("Teža: %.2f kg\n\n", i.teza)
	printMutex.Unlock()

	mutex.Lock()
	promet += i.cena
	mutex.Unlock()
}

func (e eknjiga) obdelaj() {
	printMutex.Lock()
	stNarocil++
	fmt.Printf("Številka naročila: %d\n", stNarocil)
	fmt.Println("Naslov e-knjige:", e.naslovKnjige)
	fmt.Printf("Cena: %.2f €\n\n", e.cena)
	printMutex.Unlock()

	mutex.Lock()
	promet += e.cena
	mutex.Unlock()
}

func (s spletniTecaj) obdelaj() {
	cena := float64(s.trajanjeUre) * s.cenaUre

	printMutex.Lock()
	stNarocil++
	fmt.Printf("Številka naročila: %d\n", stNarocil)
	fmt.Println("Ime tečaja:", s.imeTecaja)
	fmt.Printf("Trajanje: %d ur\n", s.trajanjeUre)
	fmt.Printf("Cena na uro: %.2f €\n", s.cenaUre)
	fmt.Printf("Skupna cena: %.2f €\n\n", cena)
	printMutex.Unlock()

	mutex.Lock()
	promet += cena
	mutex.Unlock()
}

func main() {

	var narocila []narocilo
	for range 10 {
		t := rand.Intn(3)
		switch t {
		case 0:
			narocila = append(narocila, izdelek{
				imeIzdelka: fmt.Sprintf("Izdelek %d", rand.Intn(100)),
				cena:       float64(10 + rand.Intn(200)),
				teza:       rand.Float64()*5 + 0.5,
			})
		case 1:
			narocila = append(narocila, eknjiga{
				naslovKnjige: fmt.Sprintf("E-knjiga %d", rand.Intn(100)),
				cena:         float64(5 + rand.Intn(50)),
			})
		case 2:
			narocila = append(narocila, spletniTecaj{
				imeTecaja:   fmt.Sprintf("Tečaj %d", rand.Intn(100)),
				trajanjeUre: rand.Intn(10) + 1,
				cenaUre:     float64(10 + rand.Intn(30)),
			})
		}
	}

	var wg sync.WaitGroup

	for _, n := range narocila {
		wg.Add(1)
		go func(n narocilo) {
			n.obdelaj()
			wg.Done()
		}(n)
	}
	wg.Wait()
	fmt.Println("Skupno število naročil:", stNarocil)
	fmt.Printf("Skupni promet: %.2f €\n", promet)
}
