package com.ruoyi.app.user;

import com.ruoyi.app.user.dto.MerchantSubaccountCreateRequest;
import com.ruoyi.app.user.dto.MerchantSubaccountPasswordRequest;
import com.ruoyi.app.user.dto.MerchantSubaccountStatusRequest;
import com.ruoyi.app.user.dto.MerchantSubaccountUpdateRequest;
import com.ruoyi.app.user.dto.MerchantSubaccountView;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.system.utils.AuthContext;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;

import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

class MerchantSubaccountControllerTest {

    private MerchantSubaccountApplicationService applicationService;
    private MerchantSubaccountController controller;
    private MockedStatic<MessageUtils> messages;
    private MockedStatic<AuthContext> authContext;

    @BeforeEach
    void setUp() {
        messages = mockStatic(MessageUtils.class);
        messages.when(() -> MessageUtils.message(org.mockito.ArgumentMatchers.anyString()))
                .thenAnswer(invocation -> invocation.getArgument(0));
        authContext = mockStatic(AuthContext.class);
        authContext.when(AuthContext::requireUserId).thenReturn(10L);
        applicationService = mock(MerchantSubaccountApplicationService.class);
        controller = new MerchantSubaccountController(applicationService);
    }

    @AfterEach
    void tearDown() {
        authContext.close();
        messages.close();
    }

    @Test
    void listUsesAuthenticatedMerchantInsteadOfRequestOwner() {
        MerchantSubaccountView view = new MerchantSubaccountView();
        view.setUserId(20L);
        when(applicationService.listForOwner(10L)).thenReturn(List.of(view));

        AjaxResult result = controller.list("token");

        assertEquals(List.of(view), result.get(AjaxResult.DATA_TAG));
        verify(applicationService).listForOwner(10L);
    }

    @Test
    void mutationsAlwaysUseAuthenticatedOwner() {
        MerchantSubaccountCreateRequest create = new MerchantSubaccountCreateRequest();
        MerchantSubaccountUpdateRequest update = new MerchantSubaccountUpdateRequest();
        MerchantSubaccountPasswordRequest password = new MerchantSubaccountPasswordRequest();
        MerchantSubaccountStatusRequest status = new MerchantSubaccountStatusRequest();

        controller.create("token", create);
        controller.update("token", 20L, update);
        controller.updatePassword("token", 20L, password);
        controller.updateStatus("token", 20L, status);

        verify(applicationService).create(10L, create);
        verify(applicationService).update(10L, 20L, update);
        verify(applicationService).updatePassword(10L, 20L, password);
        verify(applicationService).updateOwnerStatus(10L, 20L, status);
    }
}
