package services

import (
	"testing"

	"github.com/google/uuid"
)

func TestDeadlineUID(t *testing.T) {
	id := uuid.MustParse("550e8400-e29b-41d4-a716-446655440000")
	uid := deadlineUID(id)
	want := "kanzlai-deadline-550e8400-e29b-41d4-a716-446655440000@kanzlai.msbls.de"
	if uid != want {
		t.Errorf("deadlineUID = %q, want %q", uid, want)
	}
}

func TestAppointmentUID(t *testing.T) {
	id := uuid.MustParse("550e8400-e29b-41d4-a716-446655440000")
	uid := appointmentUID(id)
	want := "kanzlai-appointment-550e8400-e29b-41d4-a716-446655440000@kanzlai.msbls.de"
	if uid != want {
		t.Errorf("appointmentUID = %q, want %q", uid, want)
	}
}

func TestIsKanzlAIUID(t *testing.T) {
	tests := []struct {
		uid        string
		objectType string
		want       bool
	}{
		{"kanzlai-deadline-550e8400-e29b-41d4-a716-446655440000@kanzlai.msbls.de", "deadline", true},
		{"kanzlai-appointment-550e8400-e29b-41d4-a716-446655440000@kanzlai.msbls.de", "appointment", true},
		{"kanzlai-deadline-550e8400-e29b-41d4-a716-446655440000@kanzlai.msbls.de", "appointment", false},
		{"random-uid@other.com", "deadline", false},
		{"", "deadline", false},
	}
	for _, tt := range tests {
		got := isKanzlAIUID(tt.uid, tt.objectType)
		if got != tt.want {
			t.Errorf("isKanzlAIUID(%q, %q) = %v, want %v", tt.uid, tt.objectType, got, tt.want)
		}
	}
}

func TestExtractIDFromUID(t *testing.T) {
	id := uuid.MustParse("550e8400-e29b-41d4-a716-446655440000")

	tests := []struct {
		uid        string
		objectType string
		want       uuid.UUID
	}{
		{"kanzlai-deadline-550e8400-e29b-41d4-a716-446655440000@kanzlai.msbls.de", "deadline", id},
		{"kanzlai-appointment-550e8400-e29b-41d4-a716-446655440000@kanzlai.msbls.de", "appointment", id},
		{"invalid-uid", "deadline", uuid.Nil},
		{"kanzlai-deadline-not-a-uuid@kanzlai.msbls.de", "deadline", uuid.Nil},
	}
	for _, tt := range tests {
		got := extractIDFromUID(tt.uid, tt.objectType)
		if got != tt.want {
			t.Errorf("extractIDFromUID(%q, %q) = %v, want %v", tt.uid, tt.objectType, got, tt.want)
		}
	}
}

func TestCalendarObjectPath(t *testing.T) {
	tests := []struct {
		calendarPath string
		uid          string
		want         string
	}{
		{"/dav/calendars/user/cal", "kanzlai-deadline-abc@kanzlai.msbls.de", "/dav/calendars/user/cal/kanzlai-deadline-abc@kanzlai.msbls.de.ics"},
		{"/dav/calendars/user/cal/", "kanzlai-deadline-abc@kanzlai.msbls.de", "/dav/calendars/user/cal/kanzlai-deadline-abc@kanzlai.msbls.de.ics"},
	}
	for _, tt := range tests {
		got := calendarObjectPath(tt.calendarPath, tt.uid)
		if got != tt.want {
			t.Errorf("calendarObjectPath(%q, %q) = %q, want %q", tt.calendarPath, tt.uid, got, tt.want)
		}
	}
}

func TestParseCalDAVConfig(t *testing.T) {
	settings := []byte(`{"caldav": {"url": "https://dav.example.com", "username": "user", "password": "pass", "calendar_path": "/cal", "sync_enabled": true, "sync_interval_minutes": 30}}`)
	cfg, err := parseCalDAVConfig(settings)
	if err != nil {
		t.Fatalf("parseCalDAVConfig: %v", err)
	}
	if cfg.URL != "https://dav.example.com" {
		t.Errorf("URL = %q, want %q", cfg.URL, "https://dav.example.com")
	}
	if cfg.Username != "user" {
		t.Errorf("Username = %q, want %q", cfg.Username, "user")
	}
	if cfg.SyncIntervalMinutes != 30 {
		t.Errorf("SyncIntervalMinutes = %d, want 30", cfg.SyncIntervalMinutes)
	}
	if !cfg.SyncEnabled {
		t.Error("SyncEnabled = false, want true")
	}
}

func TestParseCalDAVConfig_Empty(t *testing.T) {
	cfg, err := parseCalDAVConfig(nil)
	if err != nil {
		t.Fatalf("parseCalDAVConfig(nil): %v", err)
	}
	if cfg.URL != "" {
		t.Errorf("expected empty config, got URL=%q", cfg.URL)
	}
}

func TestParseCalDAVConfig_NoCalDAV(t *testing.T) {
	settings := []byte(`{"other_setting": true}`)
	cfg, err := parseCalDAVConfig(settings)
	if err != nil {
		t.Fatalf("parseCalDAVConfig: %v", err)
	}
	if cfg.URL != "" {
		t.Errorf("expected empty caldav config, got URL=%q", cfg.URL)
	}
}
