package main

import (
	"errors"
	"strings"
	"time"
	"unicode/utf8"
)

// Item adalah entitas domain: barang yang dijual beserta harganya dalam
// satuan rupiah utuh (tanpa pecahan) agar bebas galat pembulatan.
type Item struct {
	ID        int64     `json:"id"`
	Name      string    `json:"name"`
	Price     int64     `json:"price"`
	CreatedAt time.Time `json:"created_at"`
}

// ItemInput adalah data yang dikirim klien untuk membuat atau mengganti
// item. Struct ini dipisah dari Item supaya ID dan CreatedAt tidak bisa
// dipalsukan dari luar.
type ItemInput struct {
	Name  string `json:"name"`
	Price int64  `json:"price"`
}

// Batas aturan domain untuk masukan item.
const (
	namaMaksRune = 100
	hargaMaks    = 1_000_000_000_000
)

// Validasi memeriksa seluruh aturan domain pada ItemInput dan
// mengembalikan gabungan ValidationError lewat errors.Join. Nilai nil
// berarti masukan lolos validasi.
func (in ItemInput) Validasi() error {
	var galat []error
	name := strings.TrimSpace(in.Name)

	switch {
	case name == "":
		galat = append(galat, ValidationError{Field: "name", Message: "wajib diisi"})
	case utf8.RuneCountInString(name) > namaMaksRune:
		galat = append(galat, ValidationError{Field: "name", Message: "maksimal 100 karakter"})
	}
	if in.Price < 0 {
		galat = append(galat, ValidationError{Field: "price", Message: "tidak boleh negatif"})
	}
	if in.Price > hargaMaks {
		galat = append(galat, ValidationError{Field: "price", Message: "maksimal 1000000000000"})
	}
	return errors.Join(galat...)
}
