package persistence

import (
	"testing"
	"time"
)

func TestParseTime(t *testing.T) {
	tests := []struct {
		name       string
		input      interface{}
		wantZero   bool
		wantYear   int
		wantMonth  time.Month
		wantDay    int
		wantHour   int
		wantMinute int
		wantSecond int
	}{
		{
			name:     "nil returns zero time",
			input:    nil,
			wantZero: true,
		},
		{
			name:       "time.Time value returned as-is",
			input:      time.Date(2024, 6, 15, 10, 30, 45, 0, time.UTC),
			wantYear:   2024,
			wantMonth:  time.June,
			wantDay:    15,
			wantHour:   10,
			wantMinute: 30,
			wantSecond: 45,
		},
		{
			name:       "[]uint8 MySQL datetime format",
			input:      []uint8("2024-06-15 10:30:45"),
			wantYear:   2024,
			wantMonth:  time.June,
			wantDay:    15,
			wantHour:   10,
			wantMinute: 30,
			wantSecond: 45,
		},
		{
			name:       "[]uint8 RFC3339 format",
			input:      []uint8("2024-06-15T10:30:45Z"),
			wantYear:   2024,
			wantMonth:  time.June,
			wantDay:    15,
			wantHour:   10,
			wantMinute: 30,
			wantSecond: 45,
		},
		{
			name:     "[]uint8 invalid format returns zero time",
			input:    []uint8("not-a-date"),
			wantZero: true,
		},
		{
			name:     "[]uint8 empty string returns zero time",
			input:    []uint8(""),
			wantZero: true,
		},
		{
			name:     "unsupported type int returns zero time",
			input:    12345,
			wantZero: true,
		},
		{
			name:     "unsupported type string returns zero time",
			input:    "2024-06-15 10:30:45",
			wantZero: true,
		},
		{
			name:     "unsupported type bool returns zero time",
			input:    true,
			wantZero: true,
		},
		{
			name:       "time.Time zero value returned as zero",
			input:      time.Time{},
			wantZero:   true,
			wantYear:   1,
			wantMonth:  time.January,
			wantDay:    1,
			wantHour:   0,
			wantMinute: 0,
			wantSecond: 0,
		},
		{
			name:       "[]uint8 date only with time defaults",
			input:      []uint8("2025-01-01 00:00:00"),
			wantYear:   2025,
			wantMonth:  time.January,
			wantDay:    1,
			wantHour:   0,
			wantMinute: 0,
			wantSecond: 0,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got := parseTime(tt.input)

			if tt.wantZero {
				if !got.IsZero() {
					t.Errorf("parseTime() = %v, want zero time", got)
				}
				return
			}

			if got.Year() != tt.wantYear {
				t.Errorf("parseTime().Year() = %d, want %d", got.Year(), tt.wantYear)
			}
			if got.Month() != tt.wantMonth {
				t.Errorf("parseTime().Month() = %v, want %v", got.Month(), tt.wantMonth)
			}
			if got.Day() != tt.wantDay {
				t.Errorf("parseTime().Day() = %d, want %d", got.Day(), tt.wantDay)
			}
			if got.Hour() != tt.wantHour {
				t.Errorf("parseTime().Hour() = %d, want %d", got.Hour(), tt.wantHour)
			}
			if got.Minute() != tt.wantMinute {
				t.Errorf("parseTime().Minute() = %d, want %d", got.Minute(), tt.wantMinute)
			}
			if got.Second() != tt.wantSecond {
				t.Errorf("parseTime().Second() = %d, want %d", got.Second(), tt.wantSecond)
			}
		})
	}
}
