package main

import (
	"errors"
	"strings"
	"time"
)

// Task menyimpan satu tugas pada daftar tugas.
type Task struct {
	ID      int       `json:"id"`
	Judul   string    `json:"judul"`
	Selesai bool      `json:"selesai"`
	Dibuat  time.Time `json:"dibuat"`
}

// ErrJudulKosong adalah sentinel error untuk judul yang kosong
// atau hanya berisi spasi.
var ErrJudulKosong = errors.New("judul tugas tidak boleh kosong")

// ValidasiJudul memeriksa bahwa judul berisi teks yang berarti,
// bukan string kosong ataupun hanya spasi.
func ValidasiJudul(judul string) error {
	if strings.TrimSpace(judul) == "" {
		return ErrJudulKosong
	}
	return nil
}

// Equal melaporkan apakah dua Task memiliki isi field yang sama persis.
// Perbandingan waktu memakai time.Time.Equal sehingga dua instan waktu
// yang sama tetap dianggap setara meski zona waktunya berbeda.
func (t Task) Equal(other Task) bool {
	return t.ID == other.ID &&
		t.Judul == other.Judul &&
		t.Selesai == other.Selesai &&
		t.Dibuat.Equal(other.Dibuat)
}

// Bandingkan membandingkan dua Task menurut waktu dibuat, dengan ID
// sebagai pemecah seri. Hasil negatif bila t dibuat lebih dulu, nol
// bila keduanya setara, dan positif bila t dibuat lebih lambat.
func Bandingkan(t, other Task) int {
	if c := t.Dibuat.Compare(other.Dibuat); c != 0 {
		return c
	}
	return t.ID - other.ID
}

// IDBerikutnya menghitung id untuk tugas baru: id terbesar saat ini + 1.
// Id tidak pernah dipakai ulang meskipun ada tugas yang dihapus.
func IDBerikutnya(tasks []Task) int {
	terbesar := 0
	for _, t := range tasks {
		if t.ID > terbesar {
			terbesar = t.ID
		}
	}
	return terbesar + 1
}

// TugasAktif mengembalikan hanya tugas yang belum selesai.
func TugasAktif(tasks []Task) []Task {
	var aktif []Task
	for _, t := range tasks {
		if !t.Selesai {
			aktif = append(aktif, t)
		}
	}
	return aktif
}

// CariIndeks mencari indeks tugas berdasarkan id pada slice.
// Fungsi mengembalikan -1 bila id tidak ditemukan.
func CariIndeks(tasks []Task, id int) int {
	for i, t := range tasks {
		if t.ID == id {
			return i
		}
	}
	return -1
}
