package domain

import (
	"database/sql/driver"
	"testing"
	"time"

	"github.com/stretchr/testify/require"
)

func TestSocialAccountStatus_Constants(t *testing.T) {
	require.Equal(t, SocialAccountStatus(1), SocialAccountStatusActive)
	require.Equal(t, SocialAccountStatus(0), SocialAccountStatusInactive)
	require.Equal(t, SocialAccountStatus(2), SocialAccountStatusDisabled)
}

func TestExtraData_Value(t *testing.T) {
	tests := []struct {
		name string
		data ExtraData
		want driver.Value
	}{
		{
			name: "nil",
			data: nil,
			want: nil,
		},
		{
			name: "empty",
			data: ExtraData{},
			want: []byte("{}"),
		},
		{
			name: "with_data",
			data: ExtraData{"key": "value", "num": 42},
			want: []byte(`{"key":"value","num":42}`),
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got, err := tt.data.Value()
			require.NoError(t, err)
			if tt.want == nil {
				require.Nil(t, got)
			} else {
				require.Equal(t, tt.want, got)
			}
		})
	}
}

func TestExtraData_Scan(t *testing.T) {
	tests := []struct {
		name    string
		value   interface{}
		want    ExtraData
		wantErr bool
	}{
		{
			name:  "nil",
			value: nil,
			want:  nil,
		},
		{
			name:  "valid_json",
			value: []byte(`{"key":"value"}`),
			want:  ExtraData{"key": "value"},
		},
		{
			name:  "invalid_type",
			value: "not bytes",
			want:  nil,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			var e ExtraData
			err := e.Scan(tt.value)
			if tt.wantErr {
				require.Error(t, err)
			} else {
				require.NoError(t, err)
				require.Equal(t, tt.want, e)
			}
		})
	}
}

func TestSocialAccount_ToInfo(t *testing.T) {
	now := time.Now()
	sa := &SocialAccount{
		ID:        1,
		Provider:  "github",
		Nickname:  "testuser",
		Avatar:    "https://example.com/avatar.png",
		Status:    SocialAccountStatusActive,
		CreatedAt: &now,
	}

	info := sa.ToInfo()
	require.NotNil(t, info)
	require.Equal(t, sa.ID, info.ID)
	require.Equal(t, sa.Provider, info.Provider)
	require.Equal(t, sa.Nickname, info.Nickname)
	require.Equal(t, sa.Avatar, info.Avatar)
	require.Equal(t, sa.Status, info.Status)
	require.Equal(t, sa.CreatedAt, info.CreatedAt)
}

func TestSocialAccountInfo_Fields(t *testing.T) {
	now := time.Now()
	info := SocialAccountInfo{
		ID:        1,
		Provider:  "google",
		Nickname:  "user",
		Avatar:    "avatar.png",
		Status:    SocialAccountStatusInactive,
		CreatedAt: &now,
	}

	require.Equal(t, int64(1), info.ID)
	require.Equal(t, "google", info.Provider)
	require.Equal(t, "user", info.Nickname)
	require.Equal(t, "avatar.png", info.Avatar)
	require.Equal(t, SocialAccountStatusInactive, info.Status)
}
