<?php

namespace Modules\VetClinic\Services;

use Modules\VetClinic\Entities\VcAppointment;
use Modules\VetClinic\Entities\VcMedicalReport;

/**
 * Two-way sync between an appointment's lab/investigation results
 * (vc_appointments.exam_results JSON) and the Medical Reports module
 * (vc_medical_reports). Synced reports carry source = 'appointment_lab'
 * and an exam_key matching the source JSON entry.
 */
class MedicalReportSyncService
{
    /** Stable key for an exam_results entry (falls back to a label/kind hash). */
    public static function entryKey(array $entry, int $index): string
    {
        if (!empty($entry['key'])) {
            return (string) $entry['key'];
        }
        return 'auto_' . md5(($entry['kind'] ?? '') . '|' . ($entry['label'] ?? '') . '|' . $index);
    }

    /**
     * Push an appointment's completed lab/exam results into linked Medical Reports.
     * Reports for entries that are no longer present or no longer "done" are removed.
     */
    public function syncFromAppointment(VcAppointment $appointment): void
    {
        $exams    = is_array($appointment->exam_results) ? $appointment->exam_results : [];
        $keptKeys = [];

        foreach ($exams as $i => $x) {
            if (!is_array($x)) continue;
            $kind = $x['kind'] ?? '';
            if (!in_array($kind, ['lab', 'exam'], true)) continue;
            if (($x['status'] ?? '') !== 'done') continue;

            $key        = self::entryKey($x, $i);
            $keptKeys[] = $key;

            VcMedicalReport::updateOrCreate(
                [
                    'appointment_id' => $appointment->id,
                    'exam_key'       => $key,
                    'source'         => 'appointment_lab',
                ],
                [
                    'business_id'  => $appointment->business_id,
                    'pet_id'       => $appointment->pet_id,
                    'contact_id'   => $appointment->contact_id,
                    'doctor_id'    => $appointment->doctor_id,
                    'report_type'  => $kind === 'lab' ? 'lab' : 'other',
                    'report_title' => $x['label'] ?? ($kind === 'lab' ? 'Lab Test' : 'Investigation'),
                    'findings'     => $x['result_text'] ?? null,
                    'attachments'  => !empty($x['document_id']) ? ['document_id' => $x['document_id']] : null,
                ]
            );
        }

        // Drop synced reports whose source entry vanished or is no longer "done".
        VcMedicalReport::where('appointment_id', $appointment->id)
            ->where('source', 'appointment_lab')
            ->whereNotIn('exam_key', $keptKeys)
            ->delete();
    }

    /**
     * Write an edited synced Medical Report back into its appointment's
     * exam_results JSON entry. No-op for manually created reports.
     */
    public function syncToAppointment(VcMedicalReport $report): void
    {
        if ($report->source !== 'appointment_lab' || !$report->appointment_id || !$report->exam_key) {
            return;
        }

        $appointment = VcAppointment::find($report->appointment_id);
        if (!$appointment) return;

        $exams   = is_array($appointment->exam_results) ? $appointment->exam_results : [];
        $changed = false;

        foreach ($exams as $i => $x) {
            if (!is_array($x)) continue;
            if (self::entryKey($x, $i) === (string) $report->exam_key) {
                $exams[$i]['result_text'] = $report->findings;
                $exams[$i]['label']       = $report->report_title;
                $changed = true;
                break;
            }
        }

        if ($changed) {
            $appointment->exam_results = $exams;
            $appointment->save();
        }
    }
}
