<?php

namespace App\Services;

use Carbon\Carbon;
use App\ResultSample;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;

use Exception;
use App\DataListiner;
use App\Periksa; 
use App\RekapAntibiotik;
use App\PendaftaranOnListiner;
use App\Organisms;
use App\KomponenJawaban;
use App\Riwayat;

// Proses untuk Growth and Detection Result
function processGrowthDetectionResult($rawData){
    // Format: R|1| ^ ^ ^GND_MGIT^430100001234|INST_POSITIVE ^87| ...
    $resultData = explode('|', $rawData);

    return [
        'test_type'         => 'Growth/Detection',
        'accession_number'  => $resultData[2],
        'status'            => $resultData[3], // Positif atau Negatif
        'completion_time'   => $resultData[7]
    ];
}
// Proses untuk Isolate Result
function processIsolateResult($rawData){
    $resultData = explode('|', $rawData);
    return [
        'test_type'         => 'Isolate',
        'isolate_result'    => $resultData[3] ?? null,
        'antibiotic'        => $resultData[4] ?? null,
        'value'             => $resultData[5] ?? null,
        'status'            => $resultData[6] ?? null,
        'completion_time'   => $resultData[10] ?? null
    ];
}
// Proses untuk Other Test Result
function processOtherResult($rawData){
    // Format: R|1| ^ ^ ^OTHER^Seq123|Complete| ...
    $resultData = explode('|', $rawData);

    return [
        'test_type'         => 'Other',
        'sequence_number'   => $resultData[3],
        'result'            => $resultData[4],
        'description'       => $resultData[5],
        'completion_time'   => $resultData[6]
    ];
}

class AstmMessageService
{
    /**
     * Membersihkan string dari karakter non-printable
     */
    private function cleanString($string)
    {
        return preg_replace('/[^\x20-\x7E|]+/', '', $string);
    }

    protected function updatePeriksaStatusByHierarchy($nofoto, $proposedStatus): void
    {
        $proposedStatus = trim((string) $proposedStatus);

        if ($nofoto === null || $nofoto === '' || $proposedStatus === '') {
            return;
        }

        Periksa::where('nofoto', $nofoto)->get()->each(function ($periksa) use ($proposedStatus) {
            if (in_array($periksa->status, ['Arsip', 'Dibatalkan (Arsip)', 'Batal'], true)) {
                return;
            }

            $resolvedStatus = $this->resolvePeriksaHierarchyStatus($periksa->status, $proposedStatus);

            if ($resolvedStatus !== $periksa->status) {
                $periksa->update(['status' => $resolvedStatus]);
            }
        });
    }

    protected function resolvePeriksaHierarchyStatus($currentStatus, $proposedStatus): string
    {
        $currentStatus = trim((string) $currentStatus);
        $proposedStatus = trim((string) $proposedStatus);

        if ($proposedStatus === '') {
            return $currentStatus;
        }

        $currentRank = $this->periksaHierarchyStatusRank($currentStatus);
        $proposedRank = $this->periksaHierarchyStatusRank($proposedStatus);

        if ($currentStatus === '') {
            return $proposedStatus;
        }

        if ($proposedRank === null) {
            return $currentRank === null ? $proposedStatus : $currentStatus;
        }

        if ($currentRank === null || $proposedRank >= $currentRank) {
            return $proposedStatus;
        }

        return $currentStatus;
    }

    protected function periksaHierarchyStatusRank($status): ?int
    {
        $normalized = $this->normalizePeriksaStatus($status);

        if ($normalized === '') {
            return null;
        }

        if ($normalized === 'penerimaan sampel') {
            return 1;
        }

        if (in_array($normalized, ['pemeriksaan awal', 'pemeriksaan sampel', 'proses analisis sampel'], true)) {
            return 2;
        }

        if (str_starts_with($normalized, 'data bd di terima') || str_starts_with($normalized, 'data bd diterima')) {
            return 3;
        }

        if ($normalized === 'pewarnaan langsung') {
            return 4;
        }

        if ($this->isProsesingKoloniMediaStatus($normalized)) {
            return 5;
        }

        if (str_starts_with($normalized, 'data malditof diterima')
            || str_starts_with($normalized, 'data malditof di terima')
            || str_starts_with($normalized, 'data genexpert diterima')
            || str_starts_with($normalized, 'data genexpert di terima')) {
            return 6;
        }

        if (str_starts_with($normalized, 'otor maldi (un verified)')) {
            return 7;
        }

        if (str_starts_with($normalized, 'preliminary results')) {
            return 8;
        }

        if (str_starts_with($normalized, 'data vitek di terima') || str_starts_with($normalized, 'data vitek diterima')) {
            return 9;
        }

        if (str_starts_with($normalized, 'id/ast pending result') || $normalized === 'sedang id+ast') {
            return 10;
        }

        if (str_starts_with($normalized, 'expertise saved (un verified)')
            || in_array($normalized, ['expertise', 'selesai', 'final result'], true)) {
            return 11;
        }

        return null;
    }

    protected function normalizePeriksaStatus($status): string
    {
        $status = strtolower(trim((string) $status));
        $status = str_replace(['_', '-'], ' ', $status);
        $status = preg_replace('/\s+/', ' ', $status);

        return trim($status);
    }

    protected function isProsesingKoloniMediaStatus(string $normalizedStatus): bool
    {
        $exactStatuses = [
            'tidak ada pertumbuhan',
            'tidak lanjut identifikasi',
            'tidak tindak lanjut identifikasi',
            'inkubasi lanjutan',
            'sub kultur',
            'menunggu kultur yg lain',
            'menunggu kultur yang lain',
            'proses identifikasi dan uji kepekaan',
            'sedang malditof',
            'pertumbuhan primer',
        ];

        if (in_array($normalizedStatus, $exactStatuses, true)) {
            return true;
        }

        return str_starts_with($normalizedStatus, 'prosesing koloni media')
            || str_starts_with($normalizedStatus, 'processing koloni media')
            || str_starts_with($normalizedStatus, 'proses identifikasi')
            || str_starts_with($normalizedStatus, 'proses uji kepekaan');
    }

    /**
     * Parsing data berdasarkan format yang diberikan
     */
    private function parseResultData($rawData, $format)
    {
        $resultData = explode('|', $rawData);
        $parsedData = [];

        foreach ($format as $key => $index) {
            $parsedData[$key] = $resultData[$index] ?? null;
        }

        return $parsedData;
    }
    /**
     * Proses hasil AST Record
     */
    public function processAstResult($rawData)
    {
        $format = [
            'test_type' => 0,
            'accession_number' => 2,
            'antibiotic' => 3,
            'susceptibility' => 4,
            'value' => 5,
            'status' => 6,
            'completion_time' => 10
        ];

        return $this->parseResultData($rawData, $format);
    }
    /**
     * Proses hasil ID Record
     */
    public function processIdResult($rawData)
    {
        $format = [
            'test_type'         => 0,
            'accession_number'  => 2,
            'organism_name'     => 3,
            'status'            => 6,
            'completion_time'   => 10
        ];

        return $this->parseResultData($rawData, $format);
    }
    public function createHeader($senderName, $versionNumber)
    {
        $messageDateTime = Carbon::now()->format('YmdHis');
        return "H|{$senderName}|{$versionNumber}|{$messageDateTime}";
    }


    // Fungsi untuk membuat Patient Record (P)
    public function createPatientRecord($patient)
    {
        // Extract fields from $patient array, adjust field positions based on mapping
        return "P|{$patient['id']}|{$patient['last_name']}|{$patient['first_name']}|{$patient['middle_name']}|{$patient['suffix']}|{$patient['dob']}|{$patient['sex']}|{$patient['address']}||{$patient['phone']}|{$patient['admitting_physician']}";
    }

    // Fungsi untuk membuat Order Record (O)
    public function createOrderRecord($order)
    {
        // Order fields based on mapping (Accession Number, Test ID, etc.)
        return "O|{$order['accession_number']}|{$order['isolate_number']}|{$order['organism']}|{$order['exclude_isolate']}|{$order['priority']}|{$order['collection_date_time']}|{$order['collected_by']}|{$order['received_by']}|{$order['specimen_action_code']}|{$order['isolate_source_test']}|{$order['isolate_source_test_start_time']}|{$order['receipt_date_time']}|{$order['specimen_type']}|{$order['body_site']}|{$order['ordering_physician']}|{$order['ordering_physician_phone']}|{$order['ordering_physician_fax']}|{$order['ordering_physician_pager']}|{$order['specimen_user_field_1']}|{$order['specimen_user_field_2']}|{$order['specimen_user_field_3']}|{$order['specimen_user_field_4']}|{$order['specimen_user_field_5']}|{$order['finalized_date_time']}|{$order['specimen_reimbursement_value']}|{$order['test_reimbursement_value']}|{$order['isolate_classification']}";    }
    public function createTerminatorRecord($order)
    {
        // Order fields based on mapping (Accession Number, Test ID, etc.)
        return "L|1|N";
    }
    // Fungsi untuk membuat pesan lengkap (header + patient + order)
    public function createMessage($senderName, $versionNumber, $patient, $order)
    {
        $header         = $this->createHeader($senderName, $versionNumber);
        $patientRecord  = $this->createPatientRecord($patient);
        $orderRecord    = $this->createOrderRecord($order);
        $terimatorRecord= $this->createTerminatorRecord($order);
        return implode("\n", [$header, $patientRecord, $orderRecord, $terimatorRecord]);
    }

    /**
     * Proses data ASTM Response
     */
    protected function astmToDateTime(?string $value): ?string
    {
        if (!$value) return null;

        if (preg_match('/(\d{14})/', $value, $m)) {
            return Carbon::createFromFormat(
                'YmdHis',
                $m[1]
            )->format('Y-m-d H:i:s');
        }

        return null;
    }
    protected function splitBDAstmMessages(string $raw): array
    {
        // bersihkan karakter kontrol
        $clean = preg_replace('/[\x02\x03\x04\x17]/', '', $raw);

        $lines = preg_split("/\r\n|\n|\r/", $clean);

        $messages = [];
        $current  = [];

        foreach ($lines as $line) {

            // Ketemu H baru → simpan pesan sebelumnya
            if (str_starts_with($line, 'H|') && !empty($current)) {
                $messages[] = implode("\n", $current);
                $current = [];
            }

            $current[] = $line;

            // Akhir pesan
            if (str_starts_with($line, 'L|')) {
                $messages[] = implode("\n", $current);
                $current = [];
            }
        }

        // sisa buffer
        if (!empty($current)) {
            $messages[] = implode("\n", $current);
        }

        return $messages;
    }
    protected function reassembleAstmFrames(string $raw): string
    {
        $buffer = '';
        $frames = explode("\x02", $raw);

        foreach ($frames as $frame) {
            if ($frame === '') {
                continue;
            }

            $content = $frame;
            $etxPos = strpos($content, "\x03");
            $etbPos = strpos($content, "\x17");

            if ($etxPos !== false && ($etbPos === false || $etxPos < $etbPos)) {
                $content = substr($content, 0, $etxPos);
            } elseif ($etbPos !== false) {
                $content = substr($content, 0, $etbPos);
            }

            if ($content !== '' && ctype_digit($content[0])) {
                $content = substr($content, 1);
            }

            $buffer .= $content;
        }

        return trim($buffer) !== '' ? trim($buffer) : trim($raw);
    }
    protected function normalizeBDResult(?string $value): ?string
    {
        $value = trim((string) $value);
        if ($value === '') {
            return null;
        }

        if (stripos($value, 'NEGATIVE') !== false) {
            return 'NEGATIVE';
        }

        if (stripos($value, 'POSITIVE') !== false) {
            return 'POSITIVE';
        }

        return explode('^', $value)[0] ?: null;
    }
    protected function normalizeAstmRecordLines(string $raw): string
    {
        $normalized = str_replace(["\r\n", "\r"], "\n", $raw);

        if (str_contains($normalized, "\n")) {
            return $normalized;
        }

        $fields = explode('|', $normalized);
        $records = [];
        $current = [];

        foreach ($fields as $index => $field) {
            $isSegmentStart = $this->isAstmSegmentStart($fields, $index);

            if ($isSegmentStart && !empty($current)) {
                $records[] = implode('|', $current);
                $current = [];
            }

            $current[] = $field;
        }

        if (!empty($current)) {
            $records[] = implode('|', $current);
        }

        return !empty($records) ? implode("\n", $records) : $normalized;
    }
    protected function isAstmSegmentStart(array $fields, int $index): bool
    {
        $field = $fields[$index] ?? '';

        if ($field === 'H') {
            return $index === 0;
        }

        if (!in_array($field, ['P', 'O', 'R', 'L'], true)) {
            return false;
        }

        $next = $fields[$index + 1] ?? null;

        return $next !== null && preg_match('/^\d+$/', (string) $next) === 1;
    }
    protected function processBDAstmResponse(string $raw, $data): bool
    {
        try {
            // =========================
            // PREPARE
            // =========================
            $accnumber= '';
            $resultDateTime = null;
            $bdResult = null;
            $rawClean = preg_replace('/[\x02\x03\x04\x17]/', '', $this->reassembleAstmFrames($raw));
            $lines    = preg_split("/\r\n|\n|\r/", $rawClean);

            $parsed = [
                'header' => [],
                'patient'=> [],
                'order'  => [],
                'result' => [],
                'instrument' => []
            ];

            // =========================
            // PARSE LOOP
            // =========================
            foreach ($lines as $line) {

                if (str_starts_with($line, 'H|')) {
                    $f              = explode('|', $line);
                    $resultDateTime = $this->astmToDateTime($f[13] ?? null);
                    
                    $parsed['header'] = [
                        'sender_name'      => $data->alat ?? ($f[4] ?? 'BD Instrument'),
                        'version_number'   => $f[12] ?? 'V1.0',
                        'message_datetime' => $this->astmToDateTime($f[13] ?? null)
                    ];
                } elseif (str_starts_with($line, 'P|')) {
                    $f = explode('|', $line);
                    $name = explode(' ', $f[5] ?? '');

                    $parsed['patient'] = [
                        'patient_id'        => $f[3] ?? null,
                        'patient_name_last' => $name[0] ?? null,
                        'patient_name_first'=> $name[1] ?? null,
                        'patient_dob'       => $this->astmToDateTime($f[7] ?? null),
                        'patient_sex'       => $f[8] ?? null,
                        'patient_phone'     => $f[13] ?? null,
                        'address_street'    => $f[11] ?? null,
                        'hospital_client'   => $f[29] ?? null,
                    ];
                } elseif (str_starts_with($line, 'O|')) {
                    $f              = explode('|', $line);
                    $test           = explode('^', $f[4] ?? '');
                    $accnumber      = $f[2] ?? null;
                    $parsed['order'] = [
                        'accession_number'   => $f[2] ?? null,
                        'test_id'            => $test[3] ?? null,
                        'specimen_type'      => $f[15] ?? null,
                        'body_site'          => $f[16] ?? null,
                        'test_start_datetime'=> $this->astmToDateTime($f[7] ?? null),
                    ];
                } elseif (str_starts_with($line, 'R|')) {
                    $f              = explode('|', $line);
                    $test           = explode('^', $f[2] ?? '');
                    $bdResult       = $this->normalizeBDResult($f[3] ?? null) ?? $bdResult;
                    $resultDateTime = $this->astmToDateTime($f[12] ?? null)
                        ?? $this->astmToDateTime($f[11] ?? null)
                        ?? $resultDateTime;
                    
                    // Instrument detail di akhir baris
                    preg_match('/(MGIT960|BACTECFX)[^|]*/', $line, $inst);

                    $parsed['result'] = [
                        'organism'                  => $test[2] ?? null,
                        'test_status'               => $bdResult ?? explode('^', $f[3] ?? '')[0],
                        'result_status_datetime'    => $resultDateTime,
                    ];

                    $parsed['instrument'] = [
                        'instrument_type'   => str_contains($line, 'MGIT960') ? 'MGIT960' : 'BACTECFX',
                        'instrument_number' => $inst[0] ?? null,
                    ];
                } else {
                    $cekline = explode('|F|', $line);
                    if (isset($cekline[1])){
                        $f = explode('|', $cekline[1]);
                        $resultDateTime2 = $this->astmToDateTime($f[3] ?? null);
                        if ($resultDateTime2){
                            $parsed['result'] = array_merge($parsed['result'], [
                                'result_status_datetime'    => $resultDateTime2,
                            ]);
                            $parsed['instrument'] = array_merge($parsed['instrument'], [
                                'instrument_type'    => $f[4] ?? null,
                            ]);
                        }
                        
                    }
                }
            }

            // =========================
            // SAVE TO DATABASE
            // =========================
            $resultSample = new ResultSample();
            $resultSample->fill(array_merge(
                $parsed['header'],
                $parsed['patient'],
                $parsed['order'],
                $parsed['result'],
                $parsed['instrument']
            ));

            $resultSample->additional_result = [
                'raw_astm' => $raw,
                'source'   => 'BD'
            ];

            $resultSample->save();
            if ($accnumber != '' AND isset($resultDateTime)){
                KomponenJawaban::updateOrCreate(
                    [
                        'accnumber'		=> $accnumber,
                        'komponen'		=> 'bd_result_date',
                        'isidata'		=> $resultDateTime,
                    ],
                    [
                        'template'		=> 'Kultur',
                        'created_by'	=> 'BD'
                    ]
                );
            }
            if ($accnumber != '' && $bdResult){
                KomponenJawaban::updateOrCreate(
                    [
                        'accnumber'		=> $accnumber,
                        'komponen'		=> 'bd_result',
                        'isidata'		=> $bdResult,
                    ],
                    [
                        'template'		=> 'Kultur',
                        'created_by'	=> 'BD'
                    ]
                );
            }
            //Log::info("Data BD ASTM Berhasil di Parse dan di simpan ", $resultSample->toArray());
            

            return true;

        } catch (\Throwable $e) {
            Log::error('BD ASTM parse error', [
                'msg' => $e->getMessage()
            ]);
            return false;
        }
    }
    protected function splitHl7LikeMessages(string $raw): array
    {
        $normalized = str_replace(["\r\n", "\r"], "\n", $raw);
        $normalized = preg_replace('/[\x00-\x08\x0B-\x1F\x7F]/', '', $normalized);
        $normalized = preg_replace('/(?=MSH\|)/', "\n", $normalized);
        $parts = preg_split('/\n\s*\n+/', trim($normalized)) ?: [];

        $messages = [];
        foreach ($parts as $part) {
            $part = trim($part);
            if ($part === '' || !str_contains($part, 'MSH|')) {
                continue;
            }

            $start = strpos($part, 'MSH|');
            if ($start !== false) {
                $part = substr($part, $start);
            }

            $messages[] = trim($part);
        }

        return $messages;
    }
    protected function formatLocalInstrumentText(array $parsed, string $alat, ?string $accessionNumber, ?string $messageDateTime): string
    {
        $msh = $parsed['MSH'][0] ?? [];
        $pid = $parsed['PID'][0] ?? [];
        $obr = $parsed['OBR'][0] ?? [];
        $obx = $parsed['OBX'][0] ?? [];
        $nte = $parsed['NTE'][0] ?? [];
        $qpd = $parsed['QPD'][0] ?? [];
        $qid = $parsed['QID'][0] ?? [];
        $spm = $parsed['SPM'][0] ?? [];

        $messageType = $msh[8] ?? '-';
        $patientName = $pid[3] ?? $pid[5] ?? '-';
        $patientName = trim((string) $patientName, "\" \t\n\r\0\x0B");
        $testId = $obr[4] ?? ($qpd[1] ?? '-');
        $receivedAt = $messageDateTime ?? '-';
        $escape = static fn ($value) => e($value ?: '-');

        if (str_starts_with($alat, 'MYLA')) {
            $organism = $obx[5] ?? '-';
            $abnormalFlag = $obx[8] ?? '-';
            $confidence = $obx[9] ?? '-';
            $status = $obx[11] ?? '-';
            $operator = $obx[16] ?? '-';
            $resultAt = $this->astmToDateTime($obx[14] ?? null) ?? '-';
            $comment = $nte[3] ?? '-';
            $specimen = $spm[3] ?? '-';

            return
                '<div class="instrument-result instrument-result-myla">'.
                    '<div><strong>HASIL ALAT MYLA</strong></div>'.
                    '<table>'.
                        '<tr><td>No. Foto</td><td>: '.$escape($accessionNumber).'</td></tr>'.
                        '<tr><td>No. Spesimen</td><td>: '.$escape($specimen).'</td></tr>'.
                        '<tr><td>Pasien</td><td>: '.$escape($patientName).'</td></tr>'.
                        '<tr><td>Jenis Pesan</td><td>: '.$escape($messageType).'</td></tr>'.
                        '<tr><td>Test</td><td>: '.$escape($testId).'</td></tr>'.
                        '<tr><td>Hasil</td><td>: '.$escape($organism).'</td></tr>'.
                        '<tr><td>Abnormal Flag</td><td>: '.$escape($abnormalFlag).'</td></tr>'.
                        '<tr><td>Confidence</td><td>: '.$escape($confidence).'</td></tr>'.
                        '<tr><td>Status</td><td>: '.$escape($status).'</td></tr>'.
                        '<tr><td>Operator</td><td>: '.$escape($operator).'</td></tr>'.
                        '<tr><td>Komentar</td><td>: '.$escape($comment).'</td></tr>'.
                        '<tr><td>Tanggal Hasil</td><td>: '.$escape($resultAt).'</td></tr>'.
                        '<tr><td>Tanggal Diterima LIS</td><td>: '.$escape($receivedAt).'</td></tr>'.
                    '</table>'.
                '</div>';
        }

        $orderAt = $this->astmToDateTime($parsed['ORC'][0][8] ?? null) ?? '-';
        $queryId = $qid[1] ?? ($msh[9] ?? '-');

        return
            '<div class="instrument-result instrument-result-genexpert">'.
                '<div><strong>HASIL ALAT GENEXPERT</strong></div>'.
                '<table>'.
                    '<tr><td>No. Foto</td><td>: '.$escape($accessionNumber).'</td></tr>'.
                    '<tr><td>Pasien</td><td>: '.$escape($patientName).'</td></tr>'.
                    '<tr><td>Jenis Pesan</td><td>: '.$escape($messageType).'</td></tr>'.
                    '<tr><td>Test/Assay</td><td>: '.$escape($testId).'</td></tr>'.
                    '<tr><td>Order/Run ID</td><td>: '.$escape($queryId).'</td></tr>'.
                    '<tr><td>Tanggal Order</td><td>: '.$escape($orderAt).'</td></tr>'.
                    '<tr><td>Tanggal Diterima LIS</td><td>: '.$escape($receivedAt).'</td></tr>'.
                    '<tr><td>Catatan</td><td>: Payload alat disimpan sebagai raw untuk ditinjau analis.</td></tr>'.
                '</table>'.
            '</div>';
    }
    protected function saveInstrumentRawResult(string $raw, string $alat): bool
    {
        try {
            $segments = preg_split("/\r\n|\n|\r/", trim($raw)) ?: [];
            $parsed = [];

            foreach ($segments as $segment) {
                $segment = trim($segment);
                if ($segment === '' || !str_contains($segment, '|')) {
                    continue;
                }

                $fields = explode('|', $segment);
                $segmentType = strtoupper(trim($fields[0] ?? ''));
                if ($segmentType !== '') {
                    $parsed[$segmentType][] = $fields;
                }
            }

            $msh = $parsed['MSH'][0] ?? [];
            $pid = $parsed['PID'][0] ?? [];
            $obr = $parsed['OBR'][0] ?? [];
            $obx = $parsed['OBX'][0] ?? [];
            $spm = $parsed['SPM'][0] ?? [];
            $nte = $parsed['NTE'][0] ?? [];
            $qpd = $parsed['QPD'][0] ?? [];
            $qid = $parsed['QID'][0] ?? [];

            $messageDateTime = $this->astmToDateTime($msh[6] ?? null);
            $accessionNumber = $spm[3] ?? $pid[2] ?? $pid[3] ?? $qpd[3] ?? $qid[1] ?? null;
            if ($accessionNumber) {
                $accessionNumber = trim((string) $accessionNumber, "\"@ \t\n\r\0\x0B");
            }

            $patientName    = $pid[3] ?? $pid[5] ?? null;
            $patientName    = $patientName ? trim((string) $patientName, "\" \t\n\r\0\x0B") : null;
            $organism       = $obx[5] ?? null;
            $resultSample = new ResultSample();
            $resultSample->sender_name = $alat;
            $resultSample->version_number = $msh[11] ?? null;
            $resultSample->message_datetime = $messageDateTime;
            $resultSample->patient_id = $accessionNumber;
            $resultSample->patient_name_last = $patientName;
            $resultSample->accession_number = $accessionNumber;
            $resultSample->test_id = $obr[4] ?? ($qpd[1] ?? null);
            $resultSample->result_type_code = $obx[3] ?? ($msh[8] ?? null);
            $resultSample->organism = $organism;
            $resultSample->test_status = $obx[11] ?? null;
            $resultSample->result_status_datetime = $this->astmToDateTime($obx[14] ?? null);
            $resultSample->instrument_type = $alat;
            $resultSample->protocol_name = $obr[4] ?? null;
            $resultSample->result_data = $obx ? json_encode($obx) : null;
            $resultSample->additional_result = [
                'source' => 'local_instrument_fallback',
                'raw_astm' => $raw,
                'segments' => array_keys($parsed),
                'nte' => $nte,
                'qpd' => $qpd,
                'qid' => $qid,
            ];
            $resultSample->save();

            if ($accessionNumber) {
                $teksHasil = $this->formatLocalInstrumentText($parsed, $alat, $accessionNumber, $messageDateTime);
                if ($organism !== '') {
                    $getnama    = explode('^', $organism);
                    $organism   = $getnama[1] ?? $organism;
                    $sudah = Organisms::where('name', $organism)->count();
                    if ($sudah == 0) {
                        Organisms::create([
                            'kelompok' 	=> 'biakankultur',
                            'name'		=> $organism,
                            'category'	=> $alat,
                        ]);
                    }
                    KomponenJawaban::updateOrCreate(
                        [
                            'accnumber'		=> $accessionNumber,
                            'komponen'		=> 'id_bakteri01',
                            'isidata'		=> $organism,
                        ],
                        [
                            'template'		=> 'all',
                            'created_by'	=> $alat
                        ]
                    );
                    if ($alat == 'MYLA-10.10.120.89') {
                        $status = 'Data Malditof di Terima';
                    } else {
                        $status = 'Data Genexpert di Terima';
                    }
                    $this->updatePeriksaStatusByHierarchy($accessionNumber, $status);
                }
                
                Riwayat::create([
                    'nofoto' => $accessionNumber,
                    'jawaban' => $teksHasil,
                    'inputor' => $alat,
                    'keterangan' => $messageDateTime ?: date('Y-m-d H:i:s'),
                    'verifikasi' => '',
                ]);
            }

            return true;
        } catch (\Throwable $e) {
            Log::error('Local instrument fallback parse error', [
                'alat' => $alat,
                'msg' => $e->getMessage(),
            ]);

            return false;
        }
    }
    public function processAstmMessagesgenExpert($response, $alat)
    {
        $normalizedData     = $this->normalizeAstmRecordLines($response);
        $segments           = explode("\n", $normalizedData);
        
        $patient_id         = '';
        $patient_name       = '';
        $accession_number   = '';
        $waktu_periksa      = date('d-m-Y H:i:s');
        
        $parsedResults = []; 
        $hasil_list    = [];

        foreach ($segments as $rsegmen) {
            $cekdata = explode('|', $rsegmen);
            if (empty($cekdata[0])) continue;
            
            $recordType = preg_replace("/[^a-zA-Z]/", "", $cekdata[0]);
            
            // 1. Parsing Pasien
            if ($recordType === 'P') {
                $rawPatientId = $cekdata[2] ?? ($cekdata[3] ?? '');
                $patient_id = trim(str_replace(['\R\\', '\\R\\', '\\'], '', $rawPatientId));
                
                $raw_name = !empty($cekdata[4])
                    ? trim(str_replace('^', ' ', $cekdata[4]))
                    : (isset($cekdata[5]) ? trim(str_replace('^', ' ', $cekdata[5])) : '');
                $patient_name = !empty(trim($raw_name)) ? $raw_name : $patient_id;
            }
            
            // 2. Parsing Accession Number
            if ($recordType === 'O') {
                $accession_number = !empty($cekdata[2]) ? $cekdata[2] : $accession_number;
                if (!empty($cekdata[6])) {
                    $rawTime = preg_replace('/[^0-9]/', '', $cekdata[6]);
                    if (strlen($rawTime) >= 14) {
                        $waktu_periksa = date('d-m-Y H:i:s', strtotime(substr($rawTime, 0, 14)));
                    }
                }
            }
            
            // 3. Parsing Data Result (Tahan Banting terhadap Pergeseran Index)
            if ($recordType === 'R') {
                if (isset($cekdata[2]) && isset($cekdata[3])) {
                    $test_info_raw = $cekdata[2];
                    $result_val    = trim(str_replace('^', '', $cekdata[3]));
                    
                    if ($result_val !== '') {
                        // Pecah berdasarkan delimiter ^ dan buang elemen yang kosong
                        $target_match = array_values(array_filter(explode('^', $test_info_raw), function($val) {
                            return trim($val) !== '';
                        }));
                        
                        $metric_type = 'Result';
                        $target_parts = $target_match;
                        $last_part = end($target_parts);

                        // Jika string test_info mengandung metrik, elemen terakhir adalah metrik,
                        // dan elemen sebelumnya adalah nama target.
                        if ($last_part === 'Ct') {
                            $metric_type = 'Ct';
                            array_pop($target_parts);
                        } elseif ($last_part === 'EndPt') {
                            $metric_type = 'EndPt';
                            array_pop($target_parts);
                        } elseif (in_array($last_part, ['Delta Ct', 'LOG'], true)) {
                            $metric_type = $last_part;
                            array_pop($target_parts);
                        }

                        if (!empty($target_parts) && preg_match('/^\d+$/', (string) end($target_parts))) {
                            array_pop($target_parts);
                        }

                        $target_name = count($target_parts) > 0 ? end($target_parts) : 'Unknown Target';
                        
                        $target_name = trim($target_name);

                        if ($target_name !== '') {
                            if (!isset($parsedResults[$target_name])) {
                                $parsedResults[$target_name] = [
                                    'Result' => '-',
                                    'Ct'     => '-',
                                    'EndPt'  => '-'
                                ];
                            }

                            $parsedResults[$target_name][$metric_type] = $result_val;

                            // Hanya simpan Result utama sebagai kesimpulan (abaikan baris Ct/EndPt)
                            if ($metric_type === 'Result') {
                                $hasil_list[$target_name] = "<strong>{$target_name}:</strong> {$result_val}";
                            }
                        }
                    }
                }
            }
        }

        if (empty($accession_number)) {
            Log::warning("GeneXpert ASTM: Accession number (NoReg) tidak ditemukan.", ['alat' => $alat]);
            return false;
        }

        $kesimpulan_html    = implode(" | ", array_values($hasil_list));
        $kesimpulan_db      = strip_tags($kesimpulan_html);
        $kesimpulan_safe    = substr($kesimpulan_db, 0, 100);

        // ====================================================================
        // MEMBUAT HTML REPORT & GRAFIK (CHART.JS)
        // ====================================================================
        
        $reporthtml = '<div class="genexpert-report" style="font-family: Arial, sans-serif; max-width: 900px; margin: auto; border: 1px solid #ddd; padding: 20px; border-radius: 8px;">';
        $reporthtml .= '<h3 style="text-align: center; margin-top: 0; color: #2c3e50;">Hasil Pemeriksaan GeneXpert</h3>';
        $reporthtml .= '<hr style="border: 0; border-top: 2px solid #3498db; margin-bottom: 20px;">';

        $reporthtml .= '<table style="width: 100%; margin-bottom: 20px; font-size: 14px; border: none;">';
        $reporthtml .= '<tr>';
        $reporthtml .= '<td style="width: 15%; padding: 4px 0;"><strong>No. Reg LIS</strong></td>';
        $reporthtml .= '<td style="width: 35%; padding: 4px 0;">: ' . htmlspecialchars($accession_number) . '</td>';
        $reporthtml .= '<td style="width: 15%; padding: 4px 0;"><strong>ID Pasien</strong></td>';
        $reporthtml .= '<td style="width: 35%; padding: 4px 0;">: ' . htmlspecialchars($patient_id) . '</td>';
        $reporthtml .= '</tr>';
        $reporthtml .= '<tr>';
        $reporthtml .= '<td style="padding: 4px 0;"><strong>Nama Pasien</strong></td>';
        $reporthtml .= '<td style="padding: 4px 0;">: ' . htmlspecialchars($patient_name) . '</td>';
        $reporthtml .= '<td style="padding: 4px 0;"><strong>Waktu Tes</strong></td>';
        $reporthtml .= '<td style="padding: 4px 0;">: ' . htmlspecialchars($waktu_periksa) . '</td>';
        $reporthtml .= '</tr>';
        $reporthtml .= '</table>';

        $reporthtml .= '<div style="background-color: #f8f9fa; padding: 15px; border-left: 5px solid #2ecc71; margin-bottom: 25px; border-radius: 4px;">';
        $reporthtml .= '<h4 style="margin: 0 0 10px 0; color: #2c3e50;">Kesimpulan Hasil:</h4>';
        $reporthtml .= '<p style="margin: 0; font-size: 14px; line-height: 1.6;">' . $kesimpulan_html . '</p>';
        $reporthtml .= '</div>';

        $reporthtml .= '<h4 style="margin-bottom:10px; color: #2c3e50;">Detail Target / Analit</h4>';
        $reporthtml .= '<table border="1" cellpadding="8" style="width: 100%; border-collapse: collapse; text-align: left; margin-bottom: 25px; font-size: 13px;">';
        $reporthtml .= '<tr style="background-color: #ecf0f1; color: #2c3e50;">
                            <th>Target/Analyte</th>
                            <th>Result</th>
                            <th>Ct Value</th>
                            <th>End Point</th>
                        </tr>';

        $chartLabels = [];
        $chartCtData = [];
        $chartEndPtData = [];

        foreach ($parsedResults as $target => $data) {
            $reporthtml .= "<tr>
                                <td><strong>{$target}</strong></td>
                                <td>{$data['Result']}</td>
                                <td>{$data['Ct']}</td>
                                <td>{$data['EndPt']}</td>
                            </tr>";

            if (is_numeric($data['Ct']) || is_numeric($data['EndPt'])) {
                $chartLabels[]    = $target;
                $chartCtData[]    = is_numeric($data['Ct']) ? (float)$data['Ct'] : 0;
                $chartEndPtData[] = is_numeric($data['EndPt']) ? (float)$data['EndPt'] : 0;
            }
        }
        $reporthtml .= '</table>';

        if (!empty($chartLabels)) {
            $chartId = 'gxChart_' . preg_replace('/[^a-zA-Z0-9]/', '', $accession_number);
            $labelsJson = json_encode($chartLabels);
            $ctJson     = json_encode($chartCtData);
            $endPtJson  = json_encode($chartEndPtData);

            $reporthtml .= '<h4 style="margin-bottom:10px; color: #2c3e50; text-align: center;">Grafik Amplifikasi</h4>';
            $reporthtml .= '<div style="width: 100%; max-width: 800px; margin: auto;">';
            $reporthtml .= '<canvas id="'.$chartId.'"></canvas>';
            $reporthtml .= '</div>';

            $reporthtml .= "
            <script src=\"https://cdn.jsdelivr.net/npm/chart.js\"></script>
            <script>
                document.addEventListener('DOMContentLoaded', function() {
                    var ctx = document.getElementById('{$chartId}').getContext('2d');
                    new Chart(ctx, {
                        type: 'bar',
                        data: {
                            labels: {$labelsJson},
                            datasets: [
                                {
                                    label: 'Ct Value',
                                    data: {$ctJson},
                                    backgroundColor: 'rgba(54, 162, 235, 0.6)',
                                    borderColor: 'rgba(54, 162, 235, 1)',
                                    borderWidth: 1,
                                    yAxisID: 'y'
                                },
                                {
                                    label: 'End Point',
                                    data: {$endPtJson},
                                    type: 'line',
                                    borderColor: 'rgba(255, 99, 132, 1)',
                                    backgroundColor: 'rgba(255, 99, 132, 0.2)',
                                    borderWidth: 2,
                                    tension: 0.1,
                                    yAxisID: 'y1'
                                }
                            ]
                        },
                        options: {
                            responsive: true,
                            scales: {
                                y: {
                                    type: 'linear',
                                    display: true,
                                    position: 'left',
                                    title: { display: true, text: 'Ct Value' }
                                },
                                y1: {
                                    type: 'linear',
                                    display: true,
                                    position: 'right',
                                    title: { display: true, text: 'End Point' },
                                    grid: { drawOnChartArea: false }
                                }
                            }
                        }
                    });
                });
            </script>
            ";
        }
        $reporthtml .= '</div>';

        // ====================================================================
        // SIMPAN KE DATABASE
        // ====================================================================
        
        try {
            $this->updatePeriksaStatusByHierarchy($accession_number, 'Data GeneXpert di Terima');

            Riwayat::create([
                'nofoto'        => $accession_number,
                'jawaban'       => $reporthtml,
                'inputor'       => $alat,
                'keterangan'    => date('Y-m-d H:i:s'),
                'verifikasi'    => '',
            ]);
            
            $resultSample = ResultSample::firstOrNew(['accession_number' => $accession_number]);
            $resultSample->sender_name        = $alat;
            $resultSample->patient_id         = substr($patient_id, 0, 50);
            $resultSample->patient_name_first = substr($patient_name, 0, 100);
            $resultSample->organism           = $kesimpulan_safe;
            $resultSample->additional_result  = json_encode($parsedResults); 
            $resultSample->message_datetime   = date('Y-m-d H:i:s');
            $resultSample->save();

            Log::info("GeneXpert Result Disimpan", ["NoReg" => $accession_number, "Hasil" => $kesimpulan_safe]);            
            return true;
        } catch (\Exception $e) {
            Log::error("GeneXpert DB Save Error: " . $e->getMessage());
            return false;
        }
    }
    public function processAstmResponse($response, $alat) {
        // Bersihkan data
        $astmData = $this->normalizeAstmRecordLines($this->cleanString($response));
        // Validasi awal: response tidak kosong
        if (empty($astmData)) {
            Log::error("ASTM data kosong atau tidak valid.");
        }
        if (stripos($astmData, 'GeneXpert') !== false) {
            return $this->processAstmMessagesgenExpert($astmData, $alat);
        }
        $jsonantibiotik = array(
				'Oxacillin-OX',
				'Cefoxitin-FOX',
				'Benzylpenicillin-P',
				'Ampicillin-AM',
				'Azithromycin-AZM',
				'Erythromycin-ERY',
				'Cefazolin-CZO',
				'Cefepime-FEP',
				'Cefixime-CFM',
				'Cefotaxime-CTX',
				'Cefuroxime-CXM',
				'Ceftazidime-CAZ',
				'Ceftriaxone-CRO',
				'Ceftazidime/Avibactam-CZA',
				'Piperacilin/Tazobactam-TZP',
				'Ampicillin/Sulbactam-SAM',
				'Amoxicillin/Clavulanate-AMC',
				'Cefoperazon/Sulbactam-SCF',
				'Aztreonam-ATM',
				'Ceftaroline-CPT',
				'Ciprofloxacin-CIP',
				'Levofloxacin-LEV',
				'Moxifloxacin-MFX',
				'Clindamycin-CLI',
				'Colistin-CS',
				'Tetracyclin-TCY',
				'Tigecycline-TGC',
				'Gentamicin-GM',
				'Amikacin-AN',
				'Meropenem-MEM',
				'Imipenem-IPM',
				'Doripenem-DOR',
				'Ertapenem-ETP',
				'Minocycline-MNO',
				'Doxycycline-DOX',
				'Spectinomycin-SPT',
				'Tigecycline-TGC',
				'Trimethoprim/Sulfamethoxazole-SXT',
				'Fosfomycin-FOS',
				'Vancomycin-VAN',
				'Linezolid-LNZ',
				'Fluconazole',
				'Voriconazole',
				'Caspofungin',
				'Micafungin',
				'Amphotericin B',
				'Flucytosine'
			);
        $headerData         = [];
        $patientData        = [];
        $orderData          = [];
        $resultData         = [];
        $instrumenDT        = [];
        $mltrData           = [];
        $isolate            = null;
        $accession_number   = null;
        $segments           = explode("\n", $astmData);
        foreach ($segments as $rsegmen){
            $cekdata        = explode('|', $rsegmen);
            $datapertama    = $cekdata[0];
            $cleankode      = preg_replace("/[^a-zA-Z]/", "", $datapertama);
            if ($cleankode == 'H'){
                $headerData = array_merge([$cleankode], array_slice($cekdata, 1));
            }
            if ($cleankode == 'P'){
                $patientData = array_merge([$cleankode], array_slice($cekdata, 1));
            }
            if ($cleankode == 'O'){
                $orderData = array_merge([$cleankode], array_slice($cekdata, 1));
            }
            if ($cleankode == 'R'){
                $resultData = array_merge([$cleankode], array_slice($cekdata, 1));
            }
            if ($cleankode == 'I'){
                $instrumenDT = array_merge([$cleankode], array_slice($cekdata, 1));
            }
            if ($cleankode == 'mtrsl'){
                $mltrData = array_merge([$cleankode], array_slice($cekdata, 1));
            }
        }
        if (!empty($patientData) && !empty($headerData)) {
            $resultSample                                   = new ResultSample();
            $noregister                                     = $patientData[4] ?? null;
            $resultSample->sender_name                      = $alat;
            $resultSample->version_number                   = $headerData[11] ?? $patientData[12] ?? null;
            $resultSample->message_datetime                 = $resultData[13] ?? null; // '20241130152734'
            // Patient Record (Segment P)
            $resultSample->patient_id                       = $patientData[4] ?? null; // '11607396'
            $resultSample->patient_name_last                = $patientData[6] ?? null; // 'ZAKIYATUN'
            $resultSample->patient_name_first               = $patientData[7] ?? null; // 'O'
            $resultSample->patient_name_middle              = $patientData[8] ?? null;
            $resultSample->patient_name_suffix              = $patientData[9] ?? null;
            $resultSample->patient_name_title               = $patientData[10] ?? null;
            $resultSample->patient_dob                      = $resultData[11] ?? null; // '19800101'
            $resultSample->patient_sex                      = $patientData[12] ?? null; // 'F'
            $resultSample->address_street                   = $patientData[13] ?? null; // 'Street ABC'
            $resultSample->address_city                     = $patientData[14] ?? null;
            $resultSample->address_state                    = $patientData[15] ?? null;
            $resultSample->address_zip                      = $patientData[16] ?? null;
            $resultSample->address_country                  = $patientData[17] ?? null;
            $resultSample->patient_phone                    = $patientData[18] ?? null; // '081234567890'

            // Order Record (Segment O)
            $resultSample->accession_number                 = $orderData[4] ?? null; // '12345'
            $resultSample->isolate_number                   = $orderData[5] ?? null; // '67890'
            $resultSample->organism                         = $orderData[6] ?? null; // 'E. coli'
            $resultSample->exclude_isolate_from_statistics  = $isolate; // 'false'
            $resultSample->test_id                          = $orderData[8] ?? null; // 'Test123'

            // Result Record (Segment R)
            $resultSample->result_type_code                 = $resultData[4] ?? null; // 'S'
            $resultSample->antibiotic                       = $resultData[5] ?? null; // 'Amoxicillin'
            $resultSample->antibiotic_concentration         = $resultData[6] ?? null; // '100mg'
            $resultSample->antibiotic_concentration_units   = $resultData[7] ?? null; // 'mg'
            $resultSample->test_status                      = $resultData[8] ?? null; // 'Completed'
            $resultSample->result_data                      = json_encode(array_slice($resultData, 9)); // Additional data (if any)

            $resultSample->preliminary_final_status         = $resultData[13] ?? null;
            $resultSample->test_start_datetime              = $resultData[14] ?? null;
            $resultSample->result_status_datetime           = $resultData[15] ?? null;
            $resultSample->test_complete_datetime           = $resultData[16] ?? null;
            // Periksa apakah data duplikat berdasarkan accession_number
            //if (ResultSample::where('accession_number', $resultSample->accession_number)->exists()) {
            //    return response()->json(['message' => 'Data sudah ada.'], 409);
            //}

            // Simpan ke database
            if ($noregister){
                $this->updatePeriksaStatusByHierarchy($accession_number, 'Data Vitek di Terima');
                //Log::info("Data berhasil disimpan:", $resultSample->toArray());
                $resultSample->save();
            }
            return response()->json(['message' => 'Data berhasil diproses dan disimpan.']);
            
        } else {
            if (!empty($mltrData)){
                $mulaikirim     = 0;
                $tanggalmasuk   = '';
                $tanggalkeluar  = '';
                $organism       = '';
                $parsedData     = [
                    'patient_info' => [],
                    'antibiotics' => []
                ];
                $resultSample               = new ResultSample();
                for ($i = 0; $i < count($mltrData); $i++) {
                    $field = $mltrData[$i];
                    $kodeduadigit = substr($field, 0, 2);
                                
                    if ($field == 'ra') {
                        $current_antibiotic = [];
                        for ($j = 1; $j <= 5; $j++) {
                            if (isset($mltrData[$i + $j])) {
                                $subField = $mltrData[$i + $j];
                                $code = substr($subField, 0, 2);
                                $value = substr($subField, 2);

                                switch ($code) {
                                    case 'a1':
                                        $current_antibiotic['instrument_code'] = $value; // Kode dari alat
                                        break;
                                    case 'a2':
                                        $current_antibiotic['antibiotic_name'] = $value; // Nama antibiotik
                                        break;
                                    case 'a3':
                                        $current_antibiotic['value'] = $value; // Nilai MIC
                                        break;
                                    case 'a4':
                                        $current_antibiotic['interpretation'] = $value; // S, I, atau R
                                        break;
                                    case 'an':
                                        $current_antibiotic['resistance_note'] = $value; // Catatan resistansi
                                        break;
                                }
                            }
                        }
                        $antibioticName = $current_antibiotic['antibiotic_name'] ?? null;
                        if ($antibioticName && isset($kodevitek[$antibioticName])) {
                            $current_antibiotic['lis_code'] = $kodevitek[$antibioticName];
                        } else {
                            $current_antibiotic['lis_code'] = $current_antibiotic['instrument_code'] ?? 'NOT_FOUND';
                        }
                        $parsedData['antibiotics'][] = $current_antibiotic;
                        $i += 5;
                    } else {
                        if ($kodeduadigit == 'mt'){
                            $resultSample->sender_name =  substr($field, 2);
                        }
                        if ($kodeduadigit == 'ii'){
                            $resultSample->version_number =  substr($field, 2);
                        }
                        if ($kodeduadigit == 'rr'){
                            $resultSample->isolate_number =  substr($field, 2);
                        }
                        if ($kodeduadigit == 'ci'){
                            $accession_number               = substr($field, 2);
                            $resultSample->accession_number = $accession_number;
                        }
                        if ($kodeduadigit == 'pi'){
                            $resultSample->patient_id       =  substr($field, 2);
                        }
                        if ($kodeduadigit == 'pn'){
                            $patientNames   = substr($field, 2);
                            $patientNames   = explode(',', $patientNames ?? null);
                            if (count($patientNames) > 0) {
                                $resultSample->patient_name_first = trim($patientNames[0]);
                            }
                            if (count($patientNames) > 1) {
                                $resultSample->patient_name_last = trim($patientNames[1]);
                            }
                            if (count($patientNames) > 2) {
                                $resultSample->patient_name_middle = trim($patientNames[2]);
                            }
                        }
                        
                        if ($kodeduadigit == 'pl'){
                            $resultSample->hospital_service =  substr($field, 2);
                        }
                        if ($kodeduadigit == 'p2'){
                            $resultSample->hospital_client  =  substr($field, 2);
                        }
                        if ($kodeduadigit == 'ss'){
                            $resultSample->specimen_type    =  substr($field, 2);
                        }
                        if ($kodeduadigit == 'o2'){
                            $organism                       =  substr($field, 2);
                            $resultSample->organism         =  $organism;
                        }
                        if ($kodeduadigit == 's1'){
                            $tanggalmasuk                   =  substr($field, 2);
                        }
                        if ($kodeduadigit == 's2'){
                            $tanggalmasuk                   =  $tanggalmasuk.' '.substr($field, 2);
                        }
                        if ($kodeduadigit == 's3'){
                            $tanggalkeluar                  =  substr($field, 2);
                        }
                        if ($kodeduadigit == 's4'){
                            $tanggalkeluar                  =  $tanggalkeluar.' '.substr($field, 2);
                        }
                    }
                }
                $resultSample->additional_result    = json_encode($parsedData['antibiotics']);
                if ($tanggalmasuk != ''){
                    try {
                        $resultSample->message_datetime       = Carbon::parse($tanggalmasuk)->format('Y-m-d H:i:s') ?? null;
                    }catch (Exception $e) {
                        $resultSample->message_datetime       = date('Y-m-d H:i:s');
                    }
                }
                if ($tanggalkeluar != ''){
                    try {
                        $resultSample->test_complete_datetime       = Carbon::parse($tanggalkeluar)->format('Y-m-d H:i:s') ?? null;
                    }catch (Exception $e) {
                        $resultSample->test_complete_datetime       = date('Y-m-d H:i:s');
                    }
                }
                $resultSample->save();
                if ($accession_number){
                    $accession_number   = substr($accession_number, 0, 9);
                    if ($organism !== ''){
                        $sudah 		= Organisms::where('name', $organism)->count();
                        if ($sudah == 0){
                            Organisms::create([
                                'kelompok' 	=> 'biakankultur',
                                'name'		=> $organism,
                                'category'	=> 'Vitek',
                            ]);
                        }
                        KomponenJawaban::updateOrCreate(
                            [
                                'accnumber'		=> $accession_number,
                                'komponen'		=> 'bakteri',
                                'isidata'		=> $organism,
                            ],
                            [
                                'template'		=> 'all',
                                'created_by'	=> 'Vitek'
                            ]
                        );
                    }
                    $cekdataperiksa = Periksa::where('nofoto', $accession_number)->first();
                    if (isset($cekdataperiksa->id)){
                        if (is_array($parsedData['antibiotics'])) {
                            foreach ($parsedData['antibiotics'] as $item) {
                                $glassreportname = in_array($item['antibiotic_name'], $jsonantibiotik);
                                RekapAntibiotik::updateOrCreate(
                                    [
                                        'kuman'             => $organism,
                                        'orderid'			=> $cekdataperiksa->id,
                                        'antibiotic'		=> $item['antibiotic_name'],
                                    ],
                                    [
                                        'resistance'		=> $item['resistance_note'] ?? null,
                                        'value'				=> $item['value'] ?? null,
                                        'interpretation'	=> $item['interpretation'] ?? null,
                                        'glassreportname'	=> $glassreportname,
                                        'printrow' 			=> true,
							            'printcol'			=> false,
                                        'created_at'		=> date('Y-m-d H:i:s'),
                                        'updated_at'		=> date('Y-m-d H:i:s'),
                                    ]
                                );
                            }
                        }
                    }
                    
                    $this->updatePeriksaStatusByHierarchy($accession_number, 'Data Vitek di Terima');
                }
                //Log::info("Data MTRL Berhasil di Parse dan di simpan ", $resultSample->toArray());
                return response()->json(['message' => 'Data berhasil diproses dan disimpan.']);
            } else {    
                $headerData = explode("|", $astmData);
                if (isset($headerData[3])){
                    $accnumber                  = $headerData[47] ?? null;
                    $noregister                 = $headerData[16] ?? null;
                    if (empty($accnumber)) {
                        Log::warning('ASTM BD message skipped because accession number is missing.', [
                            'header' => $headerData,
                        ]);
                        return false;
                    }

                    $resultSample = ResultSample::firstOrNew([
                        'accession_number' => $accnumber,
                    ]);
                    $nama                       = $headerData[18] ?? null;
                    $urgensi                    = $headerData[50] ?? null; //A Critical R Normal
                    $iddokter                   = $headerData[33] ?? null;
                    $test_start_datetime        = $headerData[52] ?? null;
                    $result_status_datetime     = $headerData[59] ?? null;
                    $specimen_type              = $headerData[60] ?? null;
                    $resulttype                 = $headerData[34] ?? null;
                    $resultstatus               = $headerData[63] ?? null;
                    $preliminary                = $headerData[40] ?? null; //P
                    $test_complete_datetime     = $headerData[44] ?? null;
                    $tesid                      = $headerData[62] ?? null;
                    $alamat                     = $headerData[23] ?? null;
                    $instrumen                  = $resultData[2] ?? null;
                    $body_site                  = '';
                    $tengah                     = '';
                    $depan                      = '';
                    $akhir                      = '';
                    $suffix                     = '';
                    $title                      = '';
                    $concentration_unit         = '';
                    $kode                       = '';
                    $antibiotic                 = '';
                    $city                       = '';
                    $state                      = '';
                    $zipcode                    = '';
                    $country                    = '';
                    if ($resulttype){
                        $getdataresult          = explode('^', $resulttype);
                        $kode                   = $getdataresult[3] ?? '';
                        $concentration_unit     = $getdataresult[4] ?? '';
                    }
                    if ($specimen_type){
                        $getdata                = explode('\n', $specimen_type);
                        $specimen_type          = $getdata[0];
                        $body_site              = $getdata[1] ?? '';
                    }
                    if ($tesid){
                        $gettgl                 = explode('^', $tesid);
                        $tesid                  = $gettgl[3] ?? null;
                    }
                    if ($instrumen){
                        $gettgl                 = explode('^', $instrumen);
                        $instrumen              = $gettgl[0];
                        $media_assay_type       = $gettgl[1] ?? null;
                        $protocol_length        = $gettgl[2] ?? null;
                        $instrument_number      = $gettgl[3] ?? null;
                        $instrument_location    = $gettgl[4] ?? null;
                        $protocol_name          = $gettgl[5] ?? null;
                    } else {
                        $media_assay_type       = null;
                        $protocol_length        = null;
                        $instrument_number      = null;
                        $instrument_location    = null;
                        $protocol_name          = null;
                    }
                    if ($isolate == '' OR $isolate == '0' OR is_null($isolate)){
                        $isolate = false;
                    } else { $isolate = true; }
                    if ($test_complete_datetime){
                        $test_complete_datetime     = substr($test_complete_datetime, 0, 14);
                        //$test_complete_datetime     = Carbon::parse($test_complete_datetime)->format('Y-m-d H:i:s');
                    }
                    if ($result_status_datetime){
                        $result_status_datetime     = substr($result_status_datetime, 0, 14);
                        //$result_status_datetime     = Carbon::parse($result_status_datetime)->format('Y-m-d H:i:s');
                    }
                    if ($test_start_datetime){
                        $test_start_datetime        = substr($test_start_datetime, 0, 14);
                        //$test_start_datetime        = Carbon::parse($test_start_datetime)->format('Y-m-d H:i:s');
                    }
                    if ($nama){
                        $getnama    = explode('\015', $nama);
                        $nama       = $getnama[0];
                        $getnama    = explode('\n', $nama);
                        $nama       = $getnama[0];
                        
                        $akhir      = $getnama[1] ?? '';
                        $depan      = $getnama[2] ?? '';
                        $tengah     = $getnama[3] ?? '';
                        $suffix     = $getnama[4] ?? '';
                        $title      = $getnama[5] ?? '';
                        
                        $nama       = $nama.$akhir;
                    }
                    if ($alamat){
                        $getnama    = explode('^', $alamat);
                        $alamat     = $getnama[0];
                        $city       = $getnama[1] ?? '';
                        $state      = $getnama[2] ?? '';
                        $zipcode    = $getnama[3] ?? '';
                        $country    = $getnama[4] ?? '';
                    }
                    if ($test_start_datetime == ''){ $test_start_datetime = null; }
                    if ($result_status_datetime == ''){ $result_status_datetime = null; }
                    if ($test_complete_datetime == ''){ $test_complete_datetime = null; }
        
                    $resultSample->sender_name          = $headerData[4] ?? 'Unkown';
                    $resultSample->version_number       = $headerData[12] ?? 'V0.0';
                    $resultSample->message_datetime     = $test_start_datetime;
                    // Patient Record (Segment P)
                    $resultSample->patient_id           = $noregister; // '11607396'
                    $resultSample->patient_name_last    = $nama; // 'ZAKIYATUN'
                    $resultSample->patient_name_first   = $depan; // 'O'
                    $resultSample->patient_name_middle  = $tengah;
                    $resultSample->patient_name_suffix  = $suffix;
                    $resultSample->patient_name_title   = $title;
                    $resultSample->patient_dob          = $headerData[20] ?? null;
                    $resultSample->patient_sex          = $headerData[21] ?? null;
                    $resultSample->address_street       = $alamat;
                    $resultSample->address_city         = $city;
                    $resultSample->address_state        = $state;
                    $resultSample->address_zip          = $zipcode;
                    $resultSample->address_country      = $country;
                    $resultSample->patient_phone        = $headerData[25] ?? null;
                    $resultSample->admitting_physician  = $headerData[27] ?? null;
                    $resultSample->patient_diagnosis    = $headerData[33] ?? null;
                    $resultSample->patient_therapy      = json_encode($headerData);
                    $resultSample->admit_datetime       = null;
                    $resultSample->room_number          = $headerData[46] ?? '00001';
                    $resultSample->hospital_service     = $headerData[45] ?? 'RSSA Malang';
                    $resultSample->hospital_client      = $orderData[4] ?? 'Lab Mikro';
                    
                    // Order Record (Segment O)
                    $resultSample->accession_number                 = $accnumber; // '12345'
                    $resultSample->isolate_number                   = $orderData[5] ?? null; // '67890'
                    $resultSample->organism                         = $orderData[6] ?? null; // 'E. coli'
                    $resultSample->exclude_isolate_from_statistics  = $isolate; // 'false'
                    $resultSample->specimen_type                    = $specimen_type;
                    $resultSample->body_site                        = $body_site;
                    $resultSample->test_id                          = $tesid; // 'Test123'
                    $resultSample->urgensi                          = $urgensi; //A Critical R Normal
        
                    // Result Record (Segment R)
                    $resultSample->result_type_code                 = $kode;
                    $resultSample->antibiotic                       = $antibiotic;
                    $resultSample->antibiotic_concentration         = $concentration_unit; // '100mg'
                    $resultSample->antibiotic_concentration_units   = $concentration_unit; // 'mg'
                    $resultSample->test_status                      = $resultstatus; // 'Completed'
                    $resultSample->result_data                      = json_encode($orderData); // Additional data (if any)
                    
                    $resultSample->preliminary_final_status         = $preliminary;
                    $resultSample->test_start_datetime              = $test_start_datetime;
                    $resultSample->result_status_datetime           = $result_status_datetime;
                    $resultSample->test_complete_datetime           = $test_complete_datetime;
        
                    $resultSample->instrument_type                  = $instrumen;
                    $resultSample->media_assay_type                 = $media_assay_type;
                    $resultSample->protocol_length                  = $protocol_length;
                    $resultSample->instrument_number                = $instrument_number;
                    $resultSample->instrument_location              = $instrument_location;
                    $resultSample->protocol_name                    = $protocol_name;
                    $resultSample->additional_result                = json_encode($resultData);
                    if ($noregister){
                        $resultSample->save();
                        //Log::info("Data ASTM Berhasil di Parse dan di simpan ", $resultSample->toArray());
                        return response()->json(['message' => 'Data berhasil diproses dan disimpan.']);
                    }
                } else {
                    Log::debug("Abaikan Data Berikut ". json_encode($headerData));
                }
            }
        }
    }
    public function processAstmMessagesLokal($dataListener) {
        foreach ($dataListener as $data) {
            try {
                $response = $data->rawdt;
                if ($data->alat == 'MGIT' OR $data->alat == 'COM5' OR $data->alat == 'BACTEC'){
                    $assembled = $this->reassembleAstmFrames($data->rawdt);
                    $messages = $this->splitBDAstmMessages($assembled);
                    foreach ($messages as $msg) {
                        $ok = $this->processBDAstmResponse($msg, $data);
                    }
                    DB::table('lis_phoenix')->where('id', $data->id)->update([
                        'processed' => $ok ? 1 : 9
                    ]);
                    $this->updatePeriksaStatusByHierarchy($data->no_id, 'Data BD di Terima ('.$data->organisme.')');
                    KomponenJawaban::updateOrCreate(
                        [
                            'accnumber'		=> $data->no_id,
                            'komponen'		=> 'bd_result',
                            'isidata'		=> $data->organisme,
                        ],
                        [
                            'template'		=> 'Kultur',
                            'created_by'	=> 'BD'
                        ]
                    );
                } else if ( $data->alat == 'GeneXpert-10.10.120.75' OR $data->alat == 'GeneXpert-10.10.120.74' OR $data->alat == 'GeneXpert-10.10.120.73' OR $data->alat == 'GeneXpert-10.10.120.13' OR $data->alat == '10.10.120.75' OR $data->alat == '10.10.120.74' OR $data->alat == '10.10.120.73' OR $data->alat == '10.10.120.13') {
                    $result = $this->processAstmMessagesgenExpert($data->rawdt, $data->alat);
                    if ($result) {
                        DB::table('lis_phoenix')->where('id', $data->id)->update([
                            'processed' => 1
                        ]);
                    } else {
                        Log::debug($result);
                    }
                } else if ( $data->alat == 'MYLA-10.10.120.89' ){
                    $messages = $this->splitHl7LikeMessages($data->rawdt);
                    $ok = false;

                    if (empty($messages)) {
                        $ok = $this->saveInstrumentRawResult($data->rawdt, $data->alat);
                    } else {
                        foreach ($messages as $message) {
                            $saved = $this->saveInstrumentRawResult($message, $data->alat);
                            $ok = $ok || $saved;
                        }
                    }

                    DB::table('lis_phoenix')->where('id', $data->id)->update([
                        'processed' => $ok ? 1 : 9
                    ]);
                } else {
                    $result = $this->processAstmResponse($data->rawdt, $data->alat);
                    if ($result) {
                        DB::table('lis_phoenix')->where('id', $data->id)->update([
                            'processed' => 1
                        ]);
                    } else {
                        Log::debug($result);
                    }
                }
            } catch (\Exception $e) {
                Log::critical($e->getMessage());
            }
        }
    }
    /**
     * Proses data ASTM Response
     */
    public function processAstmMessages($dataListener) {
        foreach ($dataListener as $data) {
            try {
                // Ambil pesan ASTM dari kolom 'message' atau yang relevan
                $response = $data->rawdt;
                if ($data->alat == 'BD Mikro 1'){
                    if ($data->no_id != ''){
                        $assembled = $this->reassembleAstmFrames($data->rawdt);
                        $messages = $this->splitBDAstmMessages($assembled);
                        foreach ($messages as $msg) {
                            $ok = $this->processBDAstmResponse($msg, $data);
                        }
                        DataListiner::where('urut', $data->urut)->update([
                            'processed' => $ok ? 1 : 9
                        ]);
                        $this->updatePeriksaStatusByHierarchy($data->no_id, 'Data BD di Terima ('.$data->organisme.')');
                        KomponenJawaban::updateOrCreate(
                            [
                                'accnumber'		=> $data->no_id,
                                'komponen'		=> 'bd_result',
                                'isidata'		=> $data->organisme,
                            ],
                            [
                                'template'		=> 'Kultur',
                                'created_by'	=> 'BD'
                            ]
                        );
                        
                    } else {
                        DataListiner::where('urut', $data->urut)->update([
                            'processed' => 9
                        ]);
                    }
                } else {
                    // Lakukan parsing menggunakan method/fungsi yang sudah dibuat
                    $result = $this->processAstmResponse($response, $data->alat);
                    // Jika berhasil, tandai data sudah diproses
                    if ($result) {
                        DataListiner::where('urut', $data->urut)->update([
                            'processed' => 1
                        ]);
                    } else {
                        Log::debug($result);
                    }
                }
            } catch (\Exception $e) {
                Log::critical($e->getMessage());
            }
        }
    }
    
}
