package handlers

import (
	"testing"

	"github.com/jackc/pgx/v5/pgtype"
	"github.com/stretchr/testify/assert"
)

func TestGetDeviceIcon_Kobo(t *testing.T) {
	result := getDeviceIcon("kobo")
	assert.Equal(t, "📚", result)
}

func TestGetDeviceIcon_KOReader(t *testing.T) {
	result := getDeviceIcon("koreader")
	assert.Equal(t, "📖", result)
}

func TestGetDeviceIcon_Kindle(t *testing.T) {
	result := getDeviceIcon("kindle")
	assert.Equal(t, "📱", result)
}

func TestGetDeviceIcon_Unknown(t *testing.T) {
	result := getDeviceIcon("unknown")
	assert.Equal(t, "📚", result)

	result = getDeviceIcon("")
	assert.Equal(t, "📚", result)
}

func TestTextPtrToPgText(t *testing.T) {
	t.Run("nil returns invalid", func(t *testing.T) {
		result := textPtrToPgText(nil)
		assert.False(t, result.Valid)
	})
	t.Run("non-nil returns valid", func(t *testing.T) {
		s := "epubcfi(/6/4/2:10)"
		result := textPtrToPgText(&s)
		assert.True(t, result.Valid)
		assert.Equal(t, s, result.String)
	})
	t.Run("empty string returns valid", func(t *testing.T) {
		s := ""
		result := textPtrToPgText(&s)
		assert.True(t, result.Valid)
		assert.Equal(t, "", result.String)
	})
}

func TestIntPtrToPgInt4(t *testing.T) {
	t.Run("nil returns invalid", func(t *testing.T) {
		result := intPtrToPgInt4(nil)
		assert.False(t, result.Valid)
	})
	t.Run("non-nil returns valid", func(t *testing.T) {
		v := 5
		result := intPtrToPgInt4(&v)
		assert.True(t, result.Valid)
		assert.Equal(t, int32(5), result.Int32)
	})
}

func TestInt64PtrToPgInt8(t *testing.T) {
	t.Run("nil returns invalid", func(t *testing.T) {
		result := int64PtrToPgInt8(nil)
		assert.False(t, result.Valid)
	})
	t.Run("non-nil returns valid", func(t *testing.T) {
		v := int64(10000)
		result := int64PtrToPgInt8(&v)
		assert.True(t, result.Valid)
		assert.Equal(t, int64(10000), result.Int64)
	})
}

func TestFloat64PtrHelpers(t *testing.T) {
	t.Run("pgtype float64 valid", func(t *testing.T) {
		v := pgtype.Float8{Float64: 0.5, Valid: true}
		result := float64PtrVal(v)
		assert.NotNil(t, result)
		assert.InDelta(t, 0.5, *result, 0.001)
	})
	t.Run("pgtype float64 invalid", func(t *testing.T) {
		v := pgtype.Float8{Valid: false}
		result := float64PtrVal(v)
		assert.Nil(t, result)
	})
	t.Run("pgtype text valid", func(t *testing.T) {
		v := pgtype.Text{String: "hello", Valid: true}
		result := textPtrVal(v)
		assert.NotNil(t, result)
		assert.Equal(t, "hello", *result)
	})
	t.Run("pgtype text invalid", func(t *testing.T) {
		v := pgtype.Text{Valid: false}
		result := textPtrVal(v)
		assert.Nil(t, result)
	})
	t.Run("pgtype int4 valid", func(t *testing.T) {
		v := pgtype.Int4{Int32: 42, Valid: true}
		result := int32PtrVal(v)
		assert.NotNil(t, result)
		assert.Equal(t, 42, *result)
	})
	t.Run("pgtype int4 invalid", func(t *testing.T) {
		v := pgtype.Int4{Valid: false}
		result := int32PtrVal(v)
		assert.Nil(t, result)
	})
	t.Run("pgtype int8 valid", func(t *testing.T) {
		v := pgtype.Int8{Int64: 10000, Valid: true}
		result := int64PtrVal(v)
		assert.NotNil(t, result)
		assert.Equal(t, int64(10000), *result)
	})
	t.Run("pgtype int8 invalid", func(t *testing.T) {
		v := pgtype.Int8{Valid: false}
		result := int64PtrVal(v)
		assert.Nil(t, result)
	})
}

func float64PtrVal(v pgtype.Float8) *float64 {
	if v.Valid {
		return &v.Float64
	}
	return nil
}

func textPtrVal(v pgtype.Text) *string {
	if v.Valid {
		return &v.String
	}
	return nil
}

func int32PtrVal(v pgtype.Int4) *int {
	if v.Valid {
		val := int(v.Int32)
		return &val
	}
	return nil
}

func int64PtrVal(v pgtype.Int8) *int64 {
	if v.Valid {
		return &v.Int64
	}
	return nil
}
