using System.Net.Http.Json;
using System.Text.Json;

public static class BatchPipelineHelper
{
    /// <summary>
    /// Drives a batch from upload through to verified status, returning the batch ID.
    /// Uses intake1 for upload, entry1 for data entry, verifier1 for verification.
    /// </summary>
    public static async Task<Guid> CreateAndVerifyBatchAsync(
        ApiFixture fixture,
        string batchType = "VITALS_SHEET",
        string track = "BACKFILL",
        string patientFullName = "Test Patient",
        string patientDateOfBirth = "1990-05-15")
    {
        // === Upload as intake1 ===
        var client = await AuthHelper.LoginAsync(fixture, "intake1");

        var fileContent = new ByteArrayContent(GenerateTestPdf());
        fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf");

        var formData = new MultipartFormDataContent
        {
            { fileContent, "file", $"test-scan-{Guid.NewGuid()}.pdf" },
            { new StringContent(batchType), "batchType" },
            { new StringContent(track), "track" }
        };

        var uploadResponse = await client.PostAsync("/api/v1/digitization-batches", formData);
        uploadResponse.EnsureSuccessStatusCode();

        var uploadResult = await uploadResponse.Content.ReadFromJsonAsync<JsonElement>();
        var batchId = uploadResult.GetProperty("data").GetProperty("id").GetGuid();

        // === Assign to entry1 ===
        var assignResponse = await client.PatchAsJsonAsync(
            $"/api/v1/digitization-batches/{batchId}/assign",
            new { entryClerkUserId = await GetUserIdAsync(fixture, "entry1") });
        assignResponse.EnsureSuccessStatusCode();

        // === Data entry as entry1 ===
        client = await AuthHelper.LoginAsync(fixture, "entry1");

        // Add draft patient
        (await client.PutAsJsonAsync(
            $"/api/v1/digitization-batches/{batchId}/draft/patient",
            new
            {
                fullName = patientFullName,
                dateOfBirth = patientDateOfBirth,
                sex = "Male",
                bloodType = "A+",
                noKnownAllergies = true
            })).EnsureSuccessStatusCode();

        // Add draft encounter
        (await client.PutAsJsonAsync(
            $"/api/v1/digitization-batches/{batchId}/draft/encounter",
            new
            {
                admissionDate = "2024-01-15T08:00:00Z",
                department = Department.GeneralMedicine.ToDbString(),
                roomBed = "301-A",
                admissionReason = "Routine checkup",
                status = "active"
            })).EnsureSuccessStatusCode();

        // Add draft observations
        (await client.PostAsJsonAsync(
            $"/api/v1/digitization-batches/{batchId}/draft/observations",
            new
            {
                observationCode = "HR",
                value = 88.0,
                unit = "bpm",
                recordedAt = "2024-01-15T09:30:00Z",
                note = "Resting heart rate"
            })).EnsureSuccessStatusCode();

        (await client.PostAsJsonAsync(
            $"/api/v1/digitization-batches/{batchId}/draft/observations",
            new
            {
                observationCode = "TEMP",
                value = 37.2,
                unit = "C",
                recordedAt = "2024-01-15T09:30:00Z",
                note = "Oral temperature"
            })).EnsureSuccessStatusCode();

        (await client.PostAsJsonAsync(
            $"/api/v1/digitization-batches/{batchId}/draft/observations",
            new
            {
                observationCode = "BP_SYS",
                value = 120.0,
                unit = "mmHg",
                recordedAt = "2024-01-15T09:31:00Z"
            })).EnsureSuccessStatusCode();

        // Submit for verification
        (await client.PostAsync(
            $"/api/v1/digitization-batches/{batchId}/submit-for-verification",
            null)).EnsureSuccessStatusCode();

        // === Verify as verifier1 ===
        client = await AuthHelper.LoginAsync(fixture, "verifier1");

        var verifyRequest = new VerifyBatchRequest(
            new List<FieldCheck>
            {
                new("patient.fullName", "ok", null),
                new("observation.heartRate", "ok", null),
                new("observation.temperature", "ok", null),
                new("observation.bloodPressureSystolic", "ok", null)
            },
            Passed: true
        );

        var verifyResponse = await client.PostAsJsonAsync(
            $"/api/v1/digitization-batches/{batchId}/verify", verifyRequest);
        verifyResponse.EnsureSuccessStatusCode();

        return batchId;
    }

    private static async Task<Guid> GetUserIdAsync(ApiFixture fixture, string username)
    {
        var client = await AuthHelper.LoginAsync(fixture, username);
        var meResponse = await client.GetFromJsonAsync<JsonElement>("/api/v1/auth/me");
        return meResponse.GetProperty("data").GetProperty("id").GetGuid();
    }

    private static byte[] GenerateTestPdf()
    {
        // Minimal valid PDF for testing
        var pdf = "%PDF-1.4\n1 0 obj\n<< /Type /Catalog /Pages 2 0 R >>\nendobj\n" +
                  "2 0 obj\n<< /Type /Pages /Kids [3 0 R] /Count 1 >>\nendobj\n" +
                  "3 0 obj\n<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] >>\nendobj\n" +
                  $"%%EOF\n%% test-{Guid.NewGuid()}";
        return System.Text.Encoding.ASCII.GetBytes(pdf);
    }
}