package com.ruoyi.system.mapper;

import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Objects;

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

class LinePayOfflinePersistenceContractTest {

    @Test
    void orderSourceAndPaymentModeRoundTripThroughExplicitMappers() throws IOException {
        String orderXml = resource("mapper/system/PosOrderMapper.xml");
        String paymentXml = resource("mapper/chanting/PosOrderLinePaymentMapper.xml");
        String sql = sql();

        assertTrue(orderXml.contains("property=\"orderSource\" column=\"order_source\""));
        assertTrue(orderXml.contains("pay_type,order_source,parent_dd_id"));
        assertTrue(orderXml.contains("<if test=\"orderSource != null and orderSource != ''\">order_source,</if>"));
        assertTrue(orderXml.contains("#{orderSource}"));
        assertTrue(paymentXml.contains("payment_mode AS paymentMode"));
        assertTrue(paymentXml.contains("captured_amount AS capturedAmount"));
        assertTrue(paymentXml.contains("captured_amount = #{capturedAmount}"));
        assertTrue(paymentXml.contains("payment_mode = 'OFFLINE'"));
        assertTrue(sql.contains("order_source VARCHAR(16)"));
        assertTrue(sql.contains("DEFAULT 'USER'"));
        assertTrue(sql.contains("payment_mode VARCHAR(16)"));
        assertTrue(sql.contains("captured_amount INT"));
        assertTrue(sql.contains("DEFAULT 'ONLINE'"));
        assertTrue(sql.contains("idx_line_payment_mode_due"));
    }

    @Test
    void waitingAuthUpdateUsesDeadlineChosenByService() throws IOException {
        String paymentXml = resource("mapper/chanting/PosOrderLinePaymentMapper.xml");
        int start = paymentXml.indexOf("<update id=\"markOfflineWaitingAuth\">");
        int end = paymentXml.indexOf("</update>", start);
        assertTrue(start >= 0 && end > start);

        String statement = paymentXml.substring(start, end);
        assertTrue(statement.contains("reconcile_deadline = #{reconcileDeadline}"));
    }

    private String resource(String name) throws IOException {
        try (InputStream input = getClass().getClassLoader().getResourceAsStream(name)) {
            return new String(Objects.requireNonNull(input, name + " not found").readAllBytes(),
                    StandardCharsets.UTF_8);
        }
    }

    private String sql() throws IOException {
        for (Path candidate : List.of(Paths.get("updatesql", "sql.md"),
                Paths.get("..", "updatesql", "sql.md"))) {
            if (Files.exists(candidate)) {
                return Files.readString(candidate, StandardCharsets.UTF_8);
            }
        }
        throw new IOException("updatesql/sql.md not found");
    }
}
