package com.ruoyi.ccdi.project.sql;

import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;

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

class CcdiModelParamSqlDefaultsTest {

    @Test
    void defaultSql_shouldUseQuarterlyStableIncomeMinAndMaxParams() throws IOException {
        String initSql = readProjectFile("sql", "ccdi_model_param.sql");
        String updateSql = readProjectFile("sql", "2026-03-16-update-ccdi-model-param-defaults.sql");

        assertQuarterlyStableIncomeRangeConfig(initSql);
        assertQuarterlyStableIncomeRangeConfig(updateSql);
    }

    @Test
    void defaultSql_shouldUseUppercaseParamCodesForBankTagModels() throws IOException {
        String initSql = readProjectFile("sql", "ccdi_model_param.sql");
        String updateSql = readProjectFile("sql", "2026-03-16-update-ccdi-model-param-defaults.sql");

        assertUppercaseBankTagParamCodes(initSql);
        assertUppercaseBankTagParamCodes(updateSql);
    }

    private void assertQuarterlyStableIncomeRangeConfig(String sqlContent) {
        assertAll(
            () -> assertTrue(sqlContent.contains("FIXED_COUNTERPARTY_TRANSFER_MIN"),
                "应包含季度稳定收入金额下限参数编码"),
            () -> assertTrue(sqlContent.contains("FIXED_COUNTERPARTY_TRANSFER_MAX"),
                "应包含季度稳定收入金额上限参数编码"),
            () -> assertTrue(sqlContent.contains("季度稳定收入金额下限"),
                "应包含季度稳定收入金额下限参数名称"),
            () -> assertTrue(sqlContent.contains("季度稳定收入金额上限"),
                "应包含季度稳定收入金额上限参数名称"),
            () -> assertTrue(sqlContent.contains("'3000'"),
                "应包含季度稳定收入金额下限默认值3000"),
            () -> assertTrue(sqlContent.contains("'15000'"),
                "应包含季度稳定收入金额上限默认值15000"),
            () -> assertFalse(sqlContent.contains("'FIXED_COUNTERPARTY_TRANSFER'"),
                "不应继续保留旧的单值季度稳定收入金额参数编码")
        );
    }

    private void assertUppercaseBankTagParamCodes(String sqlContent) {
        assertAll(
            () -> assertTrue(sqlContent.contains("ANNUAL_TURNOVER"),
                "应包含大写参数编码 ANNUAL_TURNOVER"),
            () -> assertTrue(sqlContent.contains("STOCK_TFR_LARGE"),
                "应包含大写参数编码 STOCK_TFR_LARGE"),
            () -> assertTrue(sqlContent.contains("WITHDRAW_CNT"),
                "应包含大写参数编码 WITHDRAW_CNT"),
            () -> assertTrue(sqlContent.contains("WITHDRAW_AMT"),
                "应包含大写参数编码 WITHDRAW_AMT"),
            () -> assertTrue(sqlContent.contains("MULTI_PARTY_AMT_MIN"),
                "应包含大写参数编码 MULTI_PARTY_AMT_MIN"),
            () -> assertTrue(sqlContent.contains("MULTI_PARTY_AMT_MAX"),
                "应包含大写参数编码 MULTI_PARTY_AMT_MAX"),
            () -> assertFalse(sqlContent.contains("'annual_turnover'"),
                "不应继续保留小写参数编码 annual_turnover"),
            () -> assertFalse(sqlContent.contains("'stock_tfr_large'"),
                "不应继续保留小写参数编码 stock_tfr_large"),
            () -> assertFalse(sqlContent.contains("'withdraw_cnt'"),
                "不应继续保留小写参数编码 withdraw_cnt"),
            () -> assertFalse(sqlContent.contains("'withdraw_amt'"),
                "不应继续保留小写参数编码 withdraw_amt"),
            () -> assertFalse(sqlContent.contains("'multi_party_amt_min'"),
                "不应继续保留小写参数编码 multi_party_amt_min"),
            () -> assertFalse(sqlContent.contains("'multi_party_amt_max'"),
                "不应继续保留小写参数编码 multi_party_amt_max")
        );
    }

    private String readProjectFile(String... parts) throws IOException {
        Path path = Path.of("..", parts);
        return Files.readString(path, StandardCharsets.UTF_8);
    }
}
