package com.ruoyi.system.mapper.flash;

import com.ruoyi.system.domain.flash.FlashDeliveryOrder;
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.mapping.ResultMapping;
import org.apache.ibatis.session.Configuration;
import org.junit.jupiter.api.Test;

import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Set;
import java.util.stream.Collectors;

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

class FlashDeliveryMapperXmlTest {

    @Test
    void receiverLookupRequiresUniqueEligibleNormalizedPhoneCandidate() throws Exception {
        String resource = "mapper/infouser/InfoUserMapper.xml";
        String xml;
        try (InputStream input = getClass().getClassLoader().getResourceAsStream(resource)) {
            assertNotNull(input);
            xml = new String(input.readAllBytes(), StandardCharsets.UTF_8).toLowerCase();
        }

        assertTrue(xml.contains("selectordinaryuseridsbynormalizedphone"));
        assertTrue(xml.contains("user_type = '0'"));
        assertTrue(xml.contains("status = '0'"));
        assertTrue(xml.contains("del_flag = '0' or del_flag is null"));
        assertTrue(xml.contains("regexp_replace(phone"));
        assertTrue(xml.contains("limit 2"));
    }

    @Test
    void orderMapperMapsSnapshotsAndUsesConditionalAtomicUpdates() throws Exception {
        String resource = "mapper/flash/FlashDeliveryOrderMapper.xml";
        Configuration configuration = new Configuration();
        configuration.getTypeAliasRegistry().registerAlias("FlashDeliveryOrder", FlashDeliveryOrder.class);
        String xml;
        try (InputStream input = getClass().getClassLoader().getResourceAsStream(resource)) {
            assertNotNull(input);
            xml = new String(input.readAllBytes(), StandardCharsets.UTF_8);
        }
        try (InputStream input = getClass().getClassLoader().getResourceAsStream(resource)) {
            new XMLMapperBuilder(input, configuration, resource, configuration.getSqlFragments()).parse();
        }

        ResultMapping amount = configuration
                .getResultMap("com.ruoyi.system.mapper.flash.FlashDeliveryOrderMapper.FlashDeliveryOrderResult")
                .getResultMappings().stream().filter(item -> "amount".equals(item.getProperty()))
                .findFirst().orElseThrow();
        assertEquals("amount", amount.getColumn());
        Set<String> mappedProperties = configuration
                .getResultMap("com.ruoyi.system.mapper.flash.FlashDeliveryOrderMapper.FlashDeliveryOrderResult")
                .getResultMappings().stream()
                .map(ResultMapping::getProperty)
                .collect(Collectors.toSet());
        assertTrue(mappedProperties.containsAll(Set.of(
                "receiverUserId",
                "deliveryType", "quantity", "totalWeightKg", "specification",
                "pricingId", "pricingVersion", "pricingStartTime", "pricingEndTime",
                "startingDistance", "startingFare", "distance", "freight", "distanceFee",
                "baseDeliveryFee", "urgentRate", "minimumUrgentFee", "urgentFee", "tipAmount")));
        assertTrue(xml.contains("status = 'WAITING_ACCEPTANCE'"));
        assertTrue(xml.contains("rider_id is null"));
        assertTrue(xml.contains("scheduled_pickup_start_at &lt;= #{now}"));
        assertTrue(xml.contains("package_type"));
        assertTrue(xml.contains("delivery_pin_code"));
        assertTrue(xml.contains("delivered_at &lt;="));
        assertTrue(xml.contains("version = version + 1"));
        assertTrue(xml.contains("receiver_user_id = #{userId}"));
    }
}
