package logger

import (
	"encoding/json"
	"os"
	"path/filepath"
	"testing"
	"time"
)

func setupQueryDir(t *testing.T) string {
	t.Helper()
	dir := t.TempDir()

	bot1 := filepath.Join(dir, "bot1")
	bot2 := filepath.Join(dir, "bot2")
	os.MkdirAll(bot1, 0o755)
	os.MkdirAll(bot2, 0o755)

	lines := []string{
		`{"time":"2026-03-05T10:00:00Z","level":"INFO","msg":"hello","action":"greet"}`,
		`{"time":"2026-03-05T11:00:00Z","level":"ERROR","msg":"oops","action":"fail"}`,
	}
	os.WriteFile(filepath.Join(bot1, "2026-03-05.jsonl"),
		[]byte(lines[0]+"\n"+lines[1]+"\n"), 0o644)
	os.WriteFile(filepath.Join(bot1, "2026-03-06.jsonl"),
		[]byte(`{"time":"2026-03-06T09:00:00Z","level":"INFO","msg":"day2"}`+"\n"), 0o644)

	os.WriteFile(filepath.Join(bot2, "2026-03-06.jsonl"),
		[]byte(`{"time":"2026-03-06T08:00:00Z","level":"DEBUG","msg":"bot2 log"}`+"\n"), 0o644)

	return dir
}

func TestListAgents(t *testing.T) {
	dir := setupQueryDir(t)
	agents, err := ListAgents(dir)
	if err != nil {
		t.Fatal(err)
	}
	if len(agents) != 2 {
		t.Fatalf("expected 2 agents, got %d", len(agents))
	}
	if agents[0] != "bot1" || agents[1] != "bot2" {
		t.Errorf("agents = %v, want [bot1 bot2]", agents)
	}
}

func TestListDates(t *testing.T) {
	dir := setupQueryDir(t)
	dates, err := ListDates(dir, "bot1")
	if err != nil {
		t.Fatal(err)
	}
	if len(dates) != 2 {
		t.Fatalf("expected 2 dates, got %d", len(dates))
	}
	if dates[0].Format("2006-01-02") != "2026-03-05" {
		t.Errorf("first date = %v, want 2026-03-05", dates[0])
	}
}

func TestReadDayLogs(t *testing.T) {
	dir := setupQueryDir(t)
	day := time.Date(2026, 3, 5, 0, 0, 0, 0, time.UTC)
	entries, err := ReadDayLogs(dir, "bot1", day)
	if err != nil {
		t.Fatal(err)
	}
	if len(entries) != 2 {
		t.Fatalf("expected 2 entries, got %d", len(entries))
	}
}

func TestReadLogs(t *testing.T) {
	dir := setupQueryDir(t)
	from := time.Date(2026, 3, 5, 0, 0, 0, 0, time.UTC)
	to := time.Date(2026, 3, 6, 0, 0, 0, 0, time.UTC)
	entries, err := ReadLogs(dir, "bot1", from, to)
	if err != nil {
		t.Fatal(err)
	}
	if len(entries) != 3 {
		t.Fatalf("expected 3 entries across 2 days, got %d", len(entries))
	}
}

func TestSearchLogs(t *testing.T) {
	dir := setupQueryDir(t)
	from := time.Date(2026, 3, 5, 0, 0, 0, 0, time.UTC)
	to := time.Date(2026, 3, 5, 0, 0, 0, 0, time.UTC)

	results, err := SearchLogs(dir, "bot1", "action", "fail", from, to)
	if err != nil {
		t.Fatal(err)
	}
	if len(results) != 1 {
		t.Fatalf("expected 1 match, got %d", len(results))
	}
	var m map[string]any
	json.Unmarshal(results[0], &m)
	if m["msg"] != "oops" {
		t.Errorf("msg = %v, want oops", m["msg"])
	}
}

func TestSearchLogs_NoMatch(t *testing.T) {
	dir := setupQueryDir(t)
	from := time.Date(2026, 3, 5, 0, 0, 0, 0, time.UTC)
	to := time.Date(2026, 3, 6, 0, 0, 0, 0, time.UTC)

	results, err := SearchLogs(dir, "bot1", "action", "nonexistent", from, to)
	if err != nil {
		t.Fatal(err)
	}
	if len(results) != 0 {
		t.Errorf("expected 0 matches, got %d", len(results))
	}
}

func TestListAgents_EmptyDir(t *testing.T) {
	dir := t.TempDir()
	agents, err := ListAgents(dir)
	if err != nil {
		t.Fatal(err)
	}
	if len(agents) != 0 {
		t.Errorf("expected 0 agents, got %d", len(agents))
	}
}
