package builtin

// datetime_test.go tarih araçlarını sınar. En kritik kısım İŞ GÜNÜ hesabı:
// hafta sonu ve tatil ele alınmazsa planlama tarihleri yanlış çıkar.

import (
	"context"
	"testing"
	"time"

	"fiko-ai/internal/tool"
)

func TestDateDiff(t *testing.T) {
	_, ex := testReg(t, Options{})
	// 2024-01-01 (Pazartesi) -> 2024-01-08 (Pazartesi): 7 gün farkı (aralık 8 gün),
	got := run(t, ex, "date.diff", map[string]any{"from": "2024-01-01", "to": "2024-01-08"})
	if d, _ := toInt(got["days"]); d != 7 {
		t.Errorf("gün farkı 7 olmalı: %v", got)
	}
	if w, _ := toInt(got["workdays"]); w != 6 {
		t.Errorf("iş günü 6 olmalı (1 Ocak pazartesi değil, Pazar): %v", got)
	}
}

func TestDateAdd(t *testing.T) {
	_, ex := testReg(t, Options{})
	cases := []struct {
		date, unit string
		amount     int
		want       string
	}{
		{"2024-01-31", "day", 1, "2024-02-01"},
		{"2024-01-01", "week", 2, "2024-01-15"},
		{"2024-01-15", "month", 1, "2024-02-15"},
		{"2024-02-29", "year", 1, "2025-02-28"}, // artık yıl -> 28 Şubat (Go normalleştirir)
		{"2024-01-10", "day", -5, "2024-01-05"},
	}
	for _, c := range cases {
		got := run(t, ex, "date.add", map[string]any{"date": c.date, "unit": c.unit, "amount": float64(c.amount)})
		if got["date"] != c.want {
			t.Errorf("%s + %d %s = %v, beklenen %s", c.date, c.amount, c.unit, got["date"], c.want)
		}
	}
}

// TestWorkdaysExcludesWeekendAndHolidays: hafta sonu VE resmi tatil düşülmeli.
func TestWorkdaysExcludesWeekendAndHolidays(t *testing.T) {
	_, ex := testReg(t, Options{})
	// 2024-01-01..2024-01-07: 7 gün, 5 iş günü.
	got := run(t, ex, "date.workdays", map[string]any{"from": "2024-01-01", "to": "2024-01-07"})
	if w, _ := toInt(got["workdays"]); w != 5 {
		t.Errorf("iş günü 5 olmalı: %v", got)
	}
	// 1 Ocak tatil eklenince 4 olmalı.
	got2 := run(t, ex, "date.workdays", map[string]any{
		"from": "2024-01-01", "to": "2024-01-07",
		"holidays": []any{"2024-01-01"},
	})
	if w, _ := toInt(got2["workdays"]); w != 4 {
		t.Errorf("tatil sonrası iş günü 4 olmalı: %v", got2)
	}
}

func TestDateRejectsBadInput(t *testing.T) {
	_, ex := testReg(t, Options{})
	// Geçersiz tarih biçimi, geçersiz birim ve geçersiz saat dilimi reddedilir.
	for _, tc := range []struct {
		ref string
		in  map[string]any
	}{
		{"date.diff", map[string]any{"from": "01/01/2024"}},
		{"date.diff", map[string]any{"from": "2024-01-01", "to": "abc"}},
		{"date.diff", map[string]any{"from": "2024-01-01", "timezone": "Mars/Olympus"}},
		{"date.add", map[string]any{"date": "2024-01-01", "amount": float64(1), "unit": "fortnight"}},
	} {
		if _, err := ex.Execute(context.Background(), tool.Request{Ref: tc.ref, Input: tc.in, Actor: "user"}); err == nil {
			t.Errorf("%v reddedilmeliydi", tc.in)
		}
	}
}

// TestDateDiffReversedOrder: ters tarih sırası HATA vermez, normalize edilir.
func TestDateDiffReversedOrder(t *testing.T) {
	_, ex := testReg(t, Options{})
	got := run(t, ex, "date.diff", map[string]any{"from": "2024-01-08", "to": "2024-01-01"})
	if d, _ := toInt(got["days"]); d != 7 {
		t.Errorf("ters sırada gün farkı 7 olmalı: %v", got)
	}
}

func TestTurkishWeekday(t *testing.T) {
	if got := turkishWeekday(time.Monday); got != "Pazartesi" {
		t.Errorf("haftanın günü Türkçe olmalı: %q", got)
	}
	if got := turkishWeekday(time.Saturday); got != "Cumartesi" {
		t.Errorf("Cumartesi: %q", got)
	}
}
