package com.ruoyi.app.flashdelivery.service;

import com.ruoyi.app.flashdelivery.dto.InfoAddressRequest;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.ruoyi.system.domain.InfoAddress;
import com.ruoyi.system.service.IInfoAddressService;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

class InfoAddressBookServiceTest {

    @Test
    void updateCannotOverwriteAnotherUsersAddress() {
        IInfoAddressService addresses = mock(IInfoAddressService.class);
        InfoAddress other = new InfoAddress();
        other.setId(9L);
        other.setUserId(2L);
        when(addresses.getById(9L)).thenReturn(other);
        InfoAddressRequest request = validRequest();
        request.setId(9L);

        assertThrows(RuntimeException.class, () -> new InfoAddressBookService(addresses).save(1L, request));
        verify(addresses, never()).update(any(), any());
        verify(addresses, never()).update(any(Wrapper.class));
    }

    @Test
    void createAlwaysUsesAuthenticatedUser() {
        IInfoAddressService addresses = mock(IInfoAddressService.class);
        InfoAddressRequest request = validRequest();
        new InfoAddressBookService(addresses).save(7L, request);

        var captor = org.mockito.ArgumentCaptor.forClass(InfoAddress.class);
        verify(addresses).save(captor.capture());
        assertEquals(7L, captor.getValue().getUserId());
    }

    @Test
    void updateCanExplicitlyClearOptionalAddressFields() {
        IInfoAddressService addresses = mock(IInfoAddressService.class);
        InfoAddress existing = new InfoAddress();
        existing.setId(9L);
        existing.setUserId(1L);
        existing.setAddressDetail("old detail");
        when(addresses.getById(9L)).thenReturn(existing);
        when(addresses.update(any(Wrapper.class))).thenReturn(true);
        InfoAddressRequest request = validRequest();
        request.setId(9L);
        request.setAddressDetail(null);

        new InfoAddressBookService(addresses).save(1L, request);

        var captor = org.mockito.ArgumentCaptor.forClass(Wrapper.class);
        verify(addresses).update(captor.capture());
        assertTrue(captor.getValue().getSqlSet().contains("address_detail"));
    }

    private InfoAddressRequest validRequest() {
        InfoAddressRequest request = new InfoAddressRequest();
        request.setName("A"); request.setPhone("0911111111"); request.setAddress("road");
        request.setLongitude(java.math.BigDecimal.valueOf(121.5));
        request.setLatitude(java.math.BigDecimal.valueOf(25));
        return request;
    }
}
