package com.tt.honeyDue.ui.screens.residence

import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertNotNull
import kotlin.test.assertNull
import kotlin.test.assertTrue

/**
 * Behaviour spec for [ResidenceFormState] — container that wires
 * [ResidenceFormFields] to the pure validators and to typed request
 * builders. Mirrors Stream W's `TaskFormStateTest` structure.
 */
class ResidenceFormStateTest {

    private fun validFields() = ResidenceFormFields(
        name = "Main House",
        propertyTypeId = 2,
        streetAddress = "123 Main St",
        apartmentUnit = "Apt 4",
        city = "Springfield",
        stateProvince = "IL",
        postalCode = "62701",
        country = "USA",
        bedrooms = "3",
        bathrooms = "2.5",
        squareFootage = "1800",
        lotSize = "0.25",
        yearBuilt = "1998",
        description = "Three-bedroom single-family home",
        isPrimary = true,
    )

    // --- defaults / empty --------------------------------------------------

    @Test
    fun default_fields_have_usa_country_and_blank_name() {
        val fields = ResidenceFormFields()
        assertEquals("USA", fields.country)
        assertEquals("", fields.name)
        assertFalse(fields.isPrimary)
    }

    @Test
    fun empty_state_isValid_false_and_name_error_present() {
        val state = ResidenceFormState()
        assertFalse(state.isValid)
        assertEquals("Name is required", state.errors.name)
    }

    @Test
    fun empty_state_toCreateRequest_null() {
        assertNull(ResidenceFormState().toCreateRequest())
    }

    // --- valid path --------------------------------------------------------

    @Test
    fun valid_fields_isValid_true() {
        val state = ResidenceFormState(validFields())
        assertTrue(state.isValid)
        val e = state.errors
        assertNull(e.name)
        assertNull(e.bedrooms)
        assertNull(e.bathrooms)
        assertNull(e.squareFootage)
        assertNull(e.lotSize)
        assertNull(e.yearBuilt)
    }

    @Test
    fun only_name_required_for_validity() {
        // iOS canSave: !name.isEmpty — no other required fields.
        val state = ResidenceFormState(ResidenceFormFields(name = "Cabin"))
        assertTrue(state.isValid)
    }

    // --- toCreateRequest ---------------------------------------------------

    @Test
    fun toCreateRequest_maps_fields_correctly_when_valid() {
        val state = ResidenceFormState(validFields())
        val req = state.toCreateRequest()
        assertNotNull(req)
        assertEquals("Main House", req.name)
        assertEquals(2, req.propertyTypeId)
        assertEquals("123 Main St", req.streetAddress)
        assertEquals("Apt 4", req.apartmentUnit)
        assertEquals("Springfield", req.city)
        assertEquals("IL", req.stateProvince)
        assertEquals("62701", req.postalCode)
        assertEquals("USA", req.country)
        assertEquals(3, req.bedrooms)
        assertEquals(2.5, req.bathrooms)
        assertEquals(1800, req.squareFootage)
        assertEquals(0.25, req.lotSize)
        assertEquals(1998, req.yearBuilt)
        assertEquals("Three-bedroom single-family home", req.description)
        assertEquals(true, req.isPrimary)
    }

    @Test
    fun toCreateRequest_blank_optional_strings_map_to_null() {
        val state = ResidenceFormState(
            validFields().copy(
                streetAddress = "",
                apartmentUnit = "   ",
                city = "",
                stateProvince = "",
                postalCode = "",
                country = "",
                description = "",
            )
        )
        val req = state.toCreateRequest()
        assertNotNull(req)
        assertNull(req.streetAddress)
        assertNull(req.apartmentUnit)
        assertNull(req.city)
        assertNull(req.stateProvince)
        assertNull(req.postalCode)
        assertNull(req.country)
        assertNull(req.description)
    }

    @Test
    fun toCreateRequest_empty_numeric_fields_map_to_null() {
        val state = ResidenceFormState(
            validFields().copy(
                bedrooms = "",
                bathrooms = "",
                squareFootage = "",
                lotSize = "",
                yearBuilt = "",
            )
        )
        val req = state.toCreateRequest()
        assertNotNull(req)
        assertNull(req.bedrooms)
        assertNull(req.bathrooms)
        assertNull(req.squareFootage)
        assertNull(req.lotSize)
        assertNull(req.yearBuilt)
    }

    @Test
    fun toCreateRequest_invalid_numeric_returns_null() {
        val state = ResidenceFormState(validFields().copy(bedrooms = "-1"))
        assertFalse(state.isValid)
        assertNull(state.toCreateRequest())
        assertNotNull(state.errors.bedrooms)
    }

    @Test
    fun toCreateRequest_invalid_yearBuilt_returns_null() {
        val state = ResidenceFormState(validFields().copy(yearBuilt = "42"))
        assertFalse(state.isValid)
        assertNull(state.toCreateRequest())
    }

    // --- toUpdateRequest ---------------------------------------------------

    @Test
    fun toUpdateRequest_maps_fields_correctly_when_valid() {
        val state = ResidenceFormState(validFields())
        val req = state.toUpdateRequest(residenceId = 42)
        assertNotNull(req)
        assertEquals("Main House", req.name)
        assertEquals(2, req.propertyTypeId)
        assertEquals(3, req.bedrooms)
        assertEquals(2.5, req.bathrooms)
        assertEquals(1800, req.squareFootage)
        assertEquals(1998, req.yearBuilt)
        assertEquals(true, req.isPrimary)
    }

    @Test
    fun toUpdateRequest_returns_null_when_invalid() {
        assertNull(ResidenceFormState().toUpdateRequest(residenceId = 1))
    }

    // --- update / validate -------------------------------------------------

    @Test
    fun update_recomputes_errors_and_isValid() {
        val state = ResidenceFormState()
        assertFalse(state.isValid)
        assertEquals("Name is required", state.errors.name)

        state.update(validFields())
        assertTrue(state.isValid)
        assertNull(state.errors.name)

        state.update(state.fields.copy(name = ""))
        assertFalse(state.isValid)
        assertEquals("Name is required", state.errors.name)
    }

    @Test
    fun validate_returns_current_errors_snapshot() {
        val state = ResidenceFormState()
        val snapshot = state.validate()
        assertEquals("Name is required", snapshot.name)
    }

    @Test
    fun toUpdateRequest_long_overload_narrows_to_int() {
        val state = ResidenceFormState(validFields())
        val req = state.toUpdateRequest(residenceId = 99L)
        assertNotNull(req)
        assertEquals("Main House", req.name)
    }
}
