package models

import (
	"encoding/json"
	"testing"

	"github.com/shopspring/decimal"
	"github.com/stretchr/testify/assert"
)

func TestResidence_TableName(t *testing.T) {
	r := Residence{}
	assert.Equal(t, "residence_residence", r.TableName())
}

func TestResidenceType_TableName(t *testing.T) {
	rt := ResidenceType{}
	assert.Equal(t, "residence_residencetype", rt.TableName())
}

func TestResidenceShareCode_TableName(t *testing.T) {
	sc := ResidenceShareCode{}
	assert.Equal(t, "residence_residencesharecode", sc.TableName())
}

func TestResidence_JSONSerialization(t *testing.T) {
	bedrooms := 3
	bathrooms := decimal.NewFromFloat(2.5)
	sqft := 2000
	yearBuilt := 2020

	residence := Residence{
		Name:          "Test House",
		StreetAddress: "123 Main St",
		City:          "Austin",
		StateProvince: "TX",
		PostalCode:    "78701",
		Country:       "USA",
		Bedrooms:      &bedrooms,
		Bathrooms:     &bathrooms,
		SquareFootage: &sqft,
		YearBuilt:     &yearBuilt,
		IsActive:      true,
		IsPrimary:     true,
	}
	residence.ID = 1

	data, err := json.Marshal(residence)
	assert.NoError(t, err)

	var result map[string]interface{}
	err = json.Unmarshal(data, &result)
	assert.NoError(t, err)

	// Check JSON field names
	assert.Equal(t, float64(1), result["id"])
	assert.Equal(t, "Test House", result["name"])
	assert.Equal(t, "123 Main St", result["street_address"])
	assert.Equal(t, "Austin", result["city"])
	assert.Equal(t, "TX", result["state_province"])
	assert.Equal(t, "78701", result["postal_code"])
	assert.Equal(t, "USA", result["country"])
	assert.Equal(t, float64(3), result["bedrooms"])
	assert.Equal(t, "2.5", result["bathrooms"]) // Decimal serializes as string
	assert.Equal(t, float64(2000), result["square_footage"])
	assert.Equal(t, float64(2020), result["year_built"])
	assert.Equal(t, true, result["is_active"])
	assert.Equal(t, true, result["is_primary"])
}

func TestResidenceType_JSONSerialization(t *testing.T) {
	rt := ResidenceType{
		Name: "House",
	}
	rt.ID = 1

	data, err := json.Marshal(rt)
	assert.NoError(t, err)

	var result map[string]interface{}
	err = json.Unmarshal(data, &result)
	assert.NoError(t, err)

	assert.Equal(t, float64(1), result["id"])
	assert.Equal(t, "House", result["name"])
}

func TestResidence_NilOptionalFields(t *testing.T) {
	residence := Residence{
		Name:          "Test House",
		StreetAddress: "123 Main St",
		City:          "Austin",
		StateProvince: "TX",
		PostalCode:    "78701",
		Country:       "USA",
		IsActive:      true,
		IsPrimary:     false,
		// All optional fields are nil
	}

	data, err := json.Marshal(residence)
	assert.NoError(t, err)

	var result map[string]interface{}
	err = json.Unmarshal(data, &result)
	assert.NoError(t, err)

	// Nil pointer fields should serialize as null
	assert.Nil(t, result["bedrooms"])
	assert.Nil(t, result["bathrooms"])
	assert.Nil(t, result["square_footage"])
	assert.Nil(t, result["year_built"])
}
