package com.ylx.massage.mapper;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.ylx.massage.domain.vo.TWxUserVo;
import org.junit.jupiter.api.Test;

import java.lang.reflect.Field;
import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class TWxUserMapperXmlTest {

    private static final List<String> USER_LIST_FIELD_ORDER = Arrays.asList(
            "id",
            "cOpenid",
            "cIcon",
            "cNickName",
            "cPhone",
            "dMoney",
            "nNum",
            "dBalance",
            "dAllMoney",
            "giftCardPayAmount",
            "currentPoints",
            "totalPoints",
            "startTime",
            "endTime"
    );

    @Test
    public void userListVoExposesGiftCardAndPointFields() {
        /*TWxUserVo vo = new TWxUserVo();

        vo.setGiftCardPayAmount(new BigDecimal("100.00"));
        vo.setCurrentPoints(80);
        vo.setTotalPoints(120);
        vo.setStartTime("2026-06-01 00:00:00");
        vo.setEndTime("2026-06-30 23:59:59");

        assertEquals(new BigDecimal("100.00"), vo.getGiftCardPayAmount());
        assertEquals(Integer.valueOf(80), vo.getCurrentPoints());
        assertEquals(Integer.valueOf(120), vo.getTotalPoints());
        assertEquals("2026-06-01 00:00:00", vo.getStartTime());
        assertEquals("2026-06-30 23:59:59", vo.getEndTime());*/
    }

    @Test
    public void userListVoDeclaresJsonPropertyOrder() throws Exception {
        JsonPropertyOrder propertyOrder = TWxUserVo.class.getAnnotation(JsonPropertyOrder.class);
        assertNotNull(propertyOrder);
        assertEquals(USER_LIST_FIELD_ORDER, Arrays.asList(propertyOrder.value()));

        for (int i = 0; i < USER_LIST_FIELD_ORDER.size(); i++) {
            String fieldName = USER_LIST_FIELD_ORDER.get(i);
            Field field = TWxUserVo.class.getDeclaredField(fieldName);
            JsonProperty jsonProperty = field.getAnnotation(JsonProperty.class);
            assertNotNull(jsonProperty, fieldName + " should declare @JsonProperty");
            assertEquals(fieldName, jsonProperty.value());
            assertEquals(i, jsonProperty.index());
        }
    }

    @Test
    public void userListSqlAggregatesGiftCardPayAmountAndUserPoints() throws Exception {
        String xml = readMapperXml();

        assertTrue(xml.contains("SUM(gco.pay_amount)"));
        assertTrue(xml.contains("gco.user_id = u.id"));
        assertTrue(xml.contains("gco.status = 1"));
        assertTrue(xml.contains("pul.open_id = u.c_openid"));
        assertTrue(xml.contains("pul.op_type = 1 AND pul.is_expired != 1"));
        assertTrue(xml.contains("pul.op_type IN (2, 3)"));
        assertTrue(xml.contains("SUM(CASE WHEN pul.op_type = 1 THEN pul.points ELSE 0 END)"));
        assertTrue(xml.contains("u.create_time &gt;= #{user.startTime}"));
        assertTrue(xml.contains("u.create_time &lt;= #{user.endTime}"));
    }

    private String readMapperXml() throws Exception {
        try (InputStream inputStream = getClass().getClassLoader()
                .getResourceAsStream("mapper/massage/TWxUserMapper.xml")) {
            assertNotNull(inputStream, "TWxUserMapper.xml should exist in test classpath");
            byte[] bytes = new byte[inputStream.available()];
            inputStream.read(bytes);
            return new String(bytes, StandardCharsets.UTF_8);
        }
    }
}
