<?php

namespace Modules\MedEmergency\Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Modules\MedEmergency\Entities\MderVisit;
use Modules\MedEmergency\Entities\MderVisitEvent;

/**
 * Demo data for the business named 'Shifa One' only (skips silently elsewhere).
 * Uses EXISTING demo patients where present — never invents ERP contacts.
 *
 * Seeds 4 ER visits spanning the board states, including one resuscitation and
 * one LWBS:
 *   1. awaiting_triage  — walk-in, untriaged
 *   2. in_progress      — resuscitation (ambulance), triaged + critical
 *   3. pending_results  — urgent
 *   4. done / LWBS      — left without being seen
 *
 * Everything is idempotent (firstOrCreate keyed on visit_no) so repair / re-runs
 * never duplicate. All ClinicCore integration is fail-soft.
 */
class MederDemoSeeder extends Seeder
{
    public function run(): void
    {
        if (! Schema::hasTable('business') || ! Schema::hasTable('mder_visits')) {
            return;
        }

        $business = DB::table('business')->where('name', 'Shifa One')->first();
        if (empty($business)) {
            return; // not the Shifa host / demo DB — skip silently
        }

        $businessId = (int) $business->id;

        // Reuse up to 3 existing patients (fail-soft when ClinicCore is absent).
        $patients = Schema::hasTable('clc_patients')
            ? DB::table('clc_patients')
                ->where('business_id', $businessId)
                ->orderBy('id')
                ->limit(3)
                ->get(['id', 'contact_id', 'patient_name'])
            : collect();

        $p = fn ($i) => $patients->get($i);

        $now = now();

        $rows = [
            [
                'name'        => optional($p(0))->patient_name ?: 'Walk-in Patient',
                'patient'     => $p(0),
                'mode'        => 'walk_in',
                'complaint'   => 'Ankle injury after a fall',
                'board'       => 'awaiting_triage',
                'triage'      => null,
                'arrival_ago' => 12,
                'disposition' => null,
            ],
            [
                'name'        => optional($p(1))->patient_name ?: 'Ambulance Patient',
                'patient'     => $p(1),
                'mode'        => 'ambulance',
                'complaint'   => 'Unresponsive, GCS 6 — resuscitation',
                'board'       => 'in_progress',
                'triage'      => 'resuscitation',
                'arrival_ago' => 40,
                'disposition' => null,
            ],
            [
                'name'        => optional($p(2))->patient_name ?: 'Chest Pain Patient',
                'patient'     => $p(2),
                'mode'        => 'walk_in',
                'complaint'   => 'Central chest pain, awaiting troponin',
                'board'       => 'pending_results',
                'triage'      => 'urgent',
                'arrival_ago' => 75,
                'disposition' => null,
            ],
            [
                'name'        => 'Impatient Visitor',
                'patient'     => null, // anonymous LWBS
                'mode'        => 'walk_in',
                'complaint'   => 'Sore throat',
                'board'       => 'done',
                'triage'      => 'non_urgent',
                'arrival_ago' => 130,
                'disposition' => 'lwbs',
            ],
        ];

        $seeded = 0;
        foreach ($rows as $r) {
            $arrivalAt = (clone $now)->subMinutes($r['arrival_ago']);
            $visitNo   = 'ER-' . $businessId . '-DEMO' . str_pad((string) ($seeded + 1), 3, '0', STR_PAD_LEFT);

            $visit = MderVisit::firstOrCreate(
                ['business_id' => $businessId, 'visit_no' => $visitNo],
                [
                    'patient_id'      => optional($r['patient'])->id,
                    'contact_id'      => optional($r['patient'])->contact_id,
                    'patient_name'    => $r['name'],
                    'arrival_at'      => $arrivalAt,
                    'arrival_mode'    => $r['mode'],
                    'chief_complaint' => $r['complaint'],
                    'triage_level'    => $r['triage'],
                    'triage_system'   => 'esi',
                    'triaged_at'      => $r['triage'] ? (clone $arrivalAt)->addMinutes(6) : null,
                    'board_status'    => $r['board'],
                    'disposition'     => $r['disposition'],
                    'disposition_at'  => $r['disposition'] ? (clone $arrivalAt)->addMinutes(20) : null,
                    'disposition_note' => $r['disposition'] === 'lwbs' ? 'Left before triage completed.' : null,
                    'created_by'      => null,
                ]
            );

            // Timeline (idempotent: only when the visit was just created / empty).
            if ($visit->wasRecentlyCreated || $visit->events()->count() === 0) {
                MderVisitEvent::log($visit->id, 'arrived', 'Arrival — ' . str_replace('_', ' ', $r['mode']));
                if ($r['triage']) {
                    MderVisitEvent::log($visit->id, 'triaged', 'Triaged ' . $r['triage'] . ' (ESI)');
                }
                if ($r['board'] === 'in_progress') {
                    MderVisitEvent::log($visit->id, 'seen', 'Seen by provider');
                }
                if ($r['disposition']) {
                    MderVisitEvent::log($visit->id, 'disposition', 'Left without being seen');
                }
            }

            $seeded++;
        }

        $this->report('MedEmergency demo: ' . $seeded . ' ER visit(s) seeded for "Shifa One" (incl. 1 resuscitation + 1 LWBS).');
    }

    private function report(string $msg): void
    {
        if ($this->command) {
            $this->command->info($msg);
        }
    }
}
