// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
//
// SPDX-License-Identifier: AGPL-3.0-or-later

//go:build integration

package lunatask_test

import (
	"os"
	"testing"
	"time"

	lunatask "git.secluded.site/go-lunatask"
)

var (
	integrationClient *lunatask.Client
	testAreaID        string
)

func TestMain(m *testing.M) {
	apiKey := os.Getenv("LUNATASK_API_KEY")
	if apiKey == "" {
		panic("LUNATASK_API_KEY environment variable required for integration tests")
	}

	testAreaID = os.Getenv("LUNATASK_TEST_AREA")
	if testAreaID == "" {
		panic("LUNATASK_TEST_AREA environment variable required for integration tests")
	}

	integrationClient = lunatask.NewClient(apiKey)

	os.Exit(m.Run())
}

// testName generates a unique name for test entities.
func testName(prefix string) string {
	return prefix + "-" + time.Now().Format("20060102-150405.000")
}

func TestIntegration_Ping(t *testing.T) {
	resp, err := integrationClient.Ping(ctx())
	if err != nil {
		t.Fatalf("Ping() error = %v", err)
	}

	t.Logf("Ping response: %+v", resp)
}

func TestIntegration_ListTasks(t *testing.T) {
	tasks, err := integrationClient.ListTasks(ctx(), nil)
	if err != nil {
		t.Fatalf("ListTasks() error = %v", err)
	}

	t.Logf("Found %d tasks", len(tasks))
}

func TestIntegration_ListNotes(t *testing.T) {
	notes, err := integrationClient.ListNotes(ctx(), nil)
	if err != nil {
		t.Fatalf("ListNotes() error = %v", err)
	}

	t.Logf("Found %d notes", len(notes))
}

func TestIntegration_ListPeople(t *testing.T) {
	people, err := integrationClient.ListPeople(ctx(), nil)
	if err != nil {
		t.Fatalf("ListPeople() error = %v", err)
	}

	t.Logf("Found %d people", len(people))
}

func TestIntegration_TaskRoundTrip(t *testing.T) {
	name := testName("integration-task")

	task, err := integrationClient.NewTask(name).
		InArea(testAreaID).
		WithStatus(lunatask.StatusNext).
		WithEstimate(15).
		Create(ctx())
	if err != nil {
		t.Fatalf("NewTask().Create() error = %v", err)
	}

	if task == nil {
		t.Fatal("NewTask().Create() returned nil (duplicate?)")
	}

	t.Cleanup(func() {
		if _, err := integrationClient.DeleteTask(ctx(), task.ID); err != nil {
			t.Errorf("DeleteTask() cleanup error = %v", err)
		}
	})

	t.Logf("Created task: %s", task.ID)

	// Verify we can fetch it
	fetched, err := integrationClient.GetTask(ctx(), task.ID)
	if err != nil {
		t.Fatalf("GetTask() error = %v", err)
	}

	if fetched.ID != task.ID {
		t.Errorf("GetTask().ID = %s, want %s", fetched.ID, task.ID)
	}

	// Update it
	updated, err := integrationClient.NewTaskUpdate(task.ID).
		WithEstimate(30).
		Update(ctx())
	if err != nil {
		t.Fatalf("NewTaskUpdate().Update() error = %v", err)
	}

	if updated.Estimate == nil || *updated.Estimate != 30 {
		t.Errorf("updated estimate = %v, want 30", updated.Estimate)
	}

	t.Logf("Updated task estimate to 30 minutes")
}

func TestIntegration_NoteRoundTrip(t *testing.T) {
	name := testName("integration-note")

	note, err := integrationClient.NewNote().
		WithName(name).
		WithContent("# Test Note\n\nThis is a test.").
		Create(ctx())
	if err != nil {
		t.Fatalf("NewNote().Create() error = %v", err)
	}

	if note == nil {
		t.Fatal("NewNote().Create() returned nil (duplicate?)")
	}

	t.Cleanup(func() {
		if _, err := integrationClient.DeleteNote(ctx(), note.ID); err != nil {
			t.Errorf("DeleteNote() cleanup error = %v", err)
		}
	})

	t.Logf("Created note: %s", note.ID)

	// Verify we can fetch it
	fetched, err := integrationClient.GetNote(ctx(), note.ID)
	if err != nil {
		t.Fatalf("GetNote() error = %v", err)
	}

	if fetched.ID != note.ID {
		t.Errorf("GetNote().ID = %s, want %s", fetched.ID, note.ID)
	}

	// Update it
	updated, err := integrationClient.NewNoteUpdate(note.ID).
		WithContent("# Updated\n\nNew content.").
		Update(ctx())
	if err != nil {
		t.Fatalf("NewNoteUpdate().Update() error = %v", err)
	}

	t.Logf("Updated note: %s", updated.ID)
}
