using System.Text.Json;

namespace CashLineERP.Api.Tests;

public sealed class IslamicFinanceMigrationAndUatTraceabilityQaTests
{
    [Fact]
    public void Islamic_Finance_Migration_Rehearsal_Artifacts_Cover_Sprint1_And_Deferred_Operational_Extension()
    {
        var repoRoot = ResolveRepoRoot();

        var requiredPaths = new[]
        {
            Path.Combine(repoRoot, "db", "flyway", "sqlserver", "V1_4_0__islamic_finance_sprint1_core.sql"),
            Path.Combine(repoRoot, "db", "flyway", "sqlserver", "V1_5_0__islamic_finance_settlement_core.sql"),
            Path.Combine(repoRoot, "db", "flyway", "oracle", "V1_4_0__islamic_finance_sprint1_core.sql"),
            Path.Combine(repoRoot, "db", "flyway", "oracle", "V1_5_0__islamic_finance_settlement_core.sql"),
            Path.Combine(repoRoot, "ops", "flyway", "flyway.sqlserver.dev.conf"),
            Path.Combine(repoRoot, "ops", "flyway", "flyway.oracle.dev.conf"),
            Path.Combine(repoRoot, "artifacts", "cutover", "database-rehearsal", "sqlserver", "flyway-rehearsal-report.json"),
            Path.Combine(repoRoot, "artifacts", "cutover", "database-rehearsal", "oracle", "flyway-rehearsal-report.json"),
            Path.Combine(repoRoot, "docs", "MIGRATION_REHEARSAL_EVIDENCE_REGISTER_2026-04-06.md")
        };

        Assert.All(requiredPaths, path => Assert.True(File.Exists(path), $"Expected traceability artifact missing: {path}"));

        var sqlServerReport = JsonDocument.Parse(File.ReadAllText(requiredPaths[6])).RootElement;
        var oracleReport = JsonDocument.Parse(File.ReadAllText(requiredPaths[7])).RootElement;

        Assert.Equal("sqlserver", sqlServerReport.GetProperty("engine").GetString());
        Assert.Equal("oracle", oracleReport.GetProperty("engine").GetString());
        Assert.Equal("FAILED", sqlServerReport.GetProperty("status").GetString());
        Assert.Equal("FAILED", oracleReport.GetProperty("status").GetString());

        var evidenceRegister = File.ReadAllText(requiredPaths[8]);
        Assert.Contains("SQL Server", evidenceRegister, StringComparison.OrdinalIgnoreCase);
        Assert.Contains("Oracle", evidenceRegister, StringComparison.OrdinalIgnoreCase);
        Assert.Contains("Flyway", evidenceRegister, StringComparison.OrdinalIgnoreCase);
    }

    [Fact]
    public void Islamic_Finance_Uat_And_Qa_Traceability_Records_Reflect_Current_Murabaha_First_Baseline()
    {
        var repoRoot = ResolveRepoRoot();

        var qaTraceabilityPath = Path.Combine(repoRoot, "docs", "ISLAMIC_FINANCE_QA_TRACEABILITY_BASELINE_2026-04-05.md");
        var uatPlanPath = Path.Combine(repoRoot, "docs", "UAT_PLAN_AND_EXECUTION_PACK_2026-04-05.md");
        var qaModulePath = Path.Combine(repoRoot, "docs", "module-design", "qa-and-integration-validation.md");

        Assert.True(File.Exists(qaTraceabilityPath));
        Assert.True(File.Exists(uatPlanPath));
        Assert.True(File.Exists(qaModulePath));

        var qaTraceability = File.ReadAllText(qaTraceabilityPath);
        var uatPlan = File.ReadAllText(uatPlanPath);
        var qaModule = File.ReadAllText(qaModulePath);

        Assert.Contains("Murabaha/disbursement/settlement history and audit", qaTraceability, StringComparison.OrdinalIgnoreCase);
        Assert.Contains("migration-rehearsal", qaTraceability, StringComparison.OrdinalIgnoreCase);
        Assert.Contains("HTTP integration", qaTraceability, StringComparison.OrdinalIgnoreCase);

        Assert.Contains("latest verified automated QA", uatPlan, StringComparison.OrdinalIgnoreCase);
        Assert.Contains("Murabaha and settlement history/audit reads are complete", uatPlan, StringComparison.OrdinalIgnoreCase);
        Assert.Contains("migration rehearsal", uatPlan, StringComparison.OrdinalIgnoreCase);

        Assert.Contains("load and endurance", qaModule, StringComparison.OrdinalIgnoreCase);
        Assert.Contains("security validation", qaModule, StringComparison.OrdinalIgnoreCase);
        Assert.Contains("migration and UAT traceability", qaModule, StringComparison.OrdinalIgnoreCase);
    }

    private static string ResolveRepoRoot()
    {
        var directory = new DirectoryInfo(AppContext.BaseDirectory);

        while (directory is not null)
        {
            if (Directory.Exists(Path.Combine(directory.FullName, "src", "backend"))
                && Directory.Exists(Path.Combine(directory.FullName, "tests"))
                && Directory.Exists(Path.Combine(directory.FullName, "docs")))
            {
                return directory.FullName;
            }

            directory = directory.Parent;
        }

        throw new InvalidOperationException("Unable to locate repository root for migration and UAT traceability validation.");
    }
}
