package util

import (
	"testing"
	"time"
)

func TestParseDateToJakartaTime(t *testing.T) {
	tests := []struct {
		name     string
		dateStr  string
		expected *time.Time
		hasError bool
	}{
		{
			name:     "valid date",
			dateStr:  "06-08-2025",
			expected: nil, // Will be set during test
			hasError: false,
		},
		{
			name:     "empty string",
			dateStr:  "",
			expected: nil,
			hasError: false,
		},
		{
			name:     "invalid date format",
			dateStr:  "2025-08-06",
			hasError: true,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result, err := ParseDateToJakartaTime(tt.dateStr)

			if tt.hasError {
				if err == nil {
					t.Errorf("Expected error but got none")
				}
				return
			}

			if err != nil {
				t.Errorf("Unexpected error: %v", err)
				return
			}

			if tt.expected == nil && tt.dateStr == "" {
				if result != nil {
					t.Errorf("Expected nil but got %v", result)
				}
				return
			}

			if result == nil && tt.dateStr != "" {
				t.Errorf("Expected time but got nil")
				return
			}

			// Check if it's in Jakarta timezone
			jakartaLoc, _ := time.LoadLocation("Asia/Jakarta")
			if result.Location().String() != jakartaLoc.String() {
				t.Errorf("Expected Jakarta timezone but got %v", result.Location())
			}

			// Check if it's start of day
			if result.Hour() != 0 || result.Minute() != 0 || result.Second() != 0 {
				t.Errorf("Expected start of day but got %v", result.Format("15:04:05"))
			}
		})
	}
}

func TestParseDateToJakartaTimeEndOfDay(t *testing.T) {
	tests := []struct {
		name     string
		dateStr  string
		expected *time.Time
		hasError bool
	}{
		{
			name:     "valid date",
			dateStr:  "06-08-2025",
			expected: nil, // Will be set during test
			hasError: false,
		},
		{
			name:     "empty string",
			dateStr:  "",
			expected: nil,
			hasError: false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result, err := ParseDateToJakartaTimeEndOfDay(tt.dateStr)

			if tt.hasError {
				if err == nil {
					t.Errorf("Expected error but got none")
				}
				return
			}

			if err != nil {
				t.Errorf("Unexpected error: %v", err)
				return
			}

			if tt.expected == nil && tt.dateStr == "" {
				if result != nil {
					t.Errorf("Expected nil but got %v", result)
				}
				return
			}

			if result == nil && tt.dateStr != "" {
				t.Errorf("Expected time but got nil")
				return
			}

			// Check if it's in Jakarta timezone
			jakartaLoc, _ := time.LoadLocation("Asia/Jakarta")
			if result.Location().String() != jakartaLoc.String() {
				t.Errorf("Expected Jakarta timezone but got %v", result.Location())
			}

			// Check if it's end of day
			if result.Hour() != 23 || result.Minute() != 59 || result.Second() != 59 {
				t.Errorf("Expected end of day but got %v", result.Format("15:04:05"))
			}
		})
	}
}

func TestParseDateRangeToJakartaTime(t *testing.T) {
	tests := []struct {
		name     string
		dateFrom string
		dateTo   string
		hasError bool
	}{
		{
			name:     "valid date range",
			dateFrom: "06-08-2025",
			dateTo:   "06-08-2025",
			hasError: false,
		},
		{
			name:     "empty strings",
			dateFrom: "",
			dateTo:   "",
			hasError: false,
		},
		{
			name:     "only date_from",
			dateFrom: "06-08-2025",
			dateTo:   "",
			hasError: false,
		},
		{
			name:     "only date_to",
			dateFrom: "",
			dateTo:   "06-08-2025",
			hasError: false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			fromTime, toTime, err := ParseDateRangeToJakartaTime(tt.dateFrom, tt.dateTo)

			if tt.hasError {
				if err == nil {
					t.Errorf("Expected error but got none")
				}
				return
			}

			if err != nil {
				t.Errorf("Unexpected error: %v", err)
				return
			}

			// If dateFrom is provided, check it's start of day
			if tt.dateFrom != "" && fromTime != nil {
				jakartaLoc, _ := time.LoadLocation("Asia/Jakarta")
				if fromTime.Location().String() != jakartaLoc.String() {
					t.Errorf("Expected Jakarta timezone for date_from but got %v", fromTime.Location())
				}
				if fromTime.Hour() != 0 || fromTime.Minute() != 0 || fromTime.Second() != 0 {
					t.Errorf("Expected start of day for date_from but got %v", fromTime.Format("15:04:05"))
				}
			}

			// If dateTo is provided, check it's end of day
			if tt.dateTo != "" && toTime != nil {
				jakartaLoc, _ := time.LoadLocation("Asia/Jakarta")
				if toTime.Location().String() != jakartaLoc.String() {
					t.Errorf("Expected Jakarta timezone for date_to but got %v", toTime.Location())
				}
				if toTime.Hour() != 23 || toTime.Minute() != 59 || toTime.Second() != 59 {
					t.Errorf("Expected end of day for date_to but got %v", toTime.Format("15:04:05"))
				}
			}
		})
	}
}
