<?php

namespace Modules\MedSurgery\Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Modules\MedSurgery\Entities\MedsxCase;
use Modules\MedSurgery\Entities\MedsxCount;
use Modules\MedSurgery\Services\ChecklistService;

/**
 * Demo data for the business named 'Shifa One' only (skips silently elsewhere).
 * Uses EXISTING ClinicCore/MedOrganization demo data — never invents patients or
 * departments. Idempotent (firstOrCreate keyed on natural columns).
 *
 * Seeds:
 *   - 1 OR room via org_rooms (room_type=operating) IF MedOrganization is
 *     installed AND an existing clc_department is available (else skipped — the
 *     module never creates a parallel rooms table).
 *   - Case 1: scheduled elective, consent PENDING (consent_id null) — its three
 *     WHO checklist phases are seeded so the consent/time-out gate is demoable.
 *   - Case 2: completed appendectomy with correct sponge/instrument/needle counts,
 *     no implants.
 *
 * All cross-module integration is fail-soft.
 */
class MedsxDemoSeeder extends Seeder
{
    public function run(): void
    {
        if (! Schema::hasTable('business') || ! Schema::hasTable('medsx_cases')) {
            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;

        if (! Schema::hasTable('clc_patients')) {
            $this->report('MedSurgery demo: ClinicCore absent — nothing to seed.');

            return;
        }

        // ── Ensure 1 OR room (org_rooms) when possible ─────────────────────
        $orRoomId = $this->ensureOperatingRoom($businessId);

        // ── Two existing patients ──────────────────────────────────────────
        $patients = DB::table('clc_patients')
            ->where('business_id', $businessId)
            ->orderBy('id')
            ->limit(2)
            ->get(['id', 'contact_id']);

        if ($patients->isEmpty()) {
            $this->report('MedSurgery demo: no patients — no cases seeded.');

            return;
        }

        $surgeonId = Schema::hasTable('clc_doctors')
            ? DB::table('clc_doctors')->where('business_id', $businessId)->where('status', 'active')->orderBy('id')->value('id')
            : null;

        $checklists = app(ChecklistService::class);

        // ── Case 1: scheduled elective, consent pending ────────────────────
        $p1 = $patients->first();
        $case1 = MedsxCase::firstOrCreate(
            ['business_id' => $businessId, 'case_no' => 'SX-' . $businessId . '-DEMO01'],
            [
                'patient_id'         => $p1->id,
                'contact_id'         => $p1->contact_id,
                'primary_surgeon_id' => $surgeonId ? (int) $surgeonId : null,
                'procedures'         => [
                    ['name' => 'Laparoscopic cholecystectomy', 'cpt_code' => '47562', 'laterality' => 'na'],
                ],
                'diagnosis'          => 'Symptomatic cholelithiasis',
                'asa_class'          => 2,
                'priority'           => 'elective',
                'anesthesia_type'    => 'general',
                'or_room_id'         => $orRoomId,
                'scheduled_date'     => now()->addDay()->toDateString(),
                'scheduled_start'    => now()->addDay()->setTime(9, 0),
                'scheduled_end'      => now()->addDay()->setTime(10, 30),
                'consent_id'         => null, // PENDING — demonstrates the consent gate
                'status'             => 'scheduled',
            ]
        );
        $checklists->seedForCase($case1);

        // ── Case 2: completed appendectomy, counts correct, no implants ────
        $p2 = $patients->count() > 1 ? $patients[1] : $patients->first();
        $case2 = MedsxCase::firstOrCreate(
            ['business_id' => $businessId, 'case_no' => 'SX-' . $businessId . '-DEMO02'],
            [
                'patient_id'         => $p2->id,
                'contact_id'         => $p2->contact_id,
                'primary_surgeon_id' => $surgeonId ? (int) $surgeonId : null,
                'procedures'         => [
                    ['name' => 'Open appendectomy', 'cpt_code' => '44950', 'laterality' => 'na'],
                ],
                'diagnosis'          => 'Acute appendicitis',
                'asa_class'          => 2,
                'priority'           => 'urgent',
                'anesthesia_type'    => 'general',
                'or_room_id'         => $orRoomId,
                'scheduled_date'     => now()->subDays(2)->toDateString(),
                'scheduled_start'    => now()->subDays(2)->setTime(14, 0),
                'scheduled_end'      => now()->subDays(2)->setTime(15, 0),
                'actual_start'       => now()->subDays(2)->setTime(14, 5),
                'actual_end'         => now()->subDays(2)->setTime(15, 10),
                'findings'           => 'Inflamed appendix, no perforation.',
                'blood_loss'         => 'minimal',
                'implants'           => [], // implant-free
                'status'             => 'completed',
            ]
        );
        $checklists->seedForCase($case2);

        // Correct counts (pre == close == final → no discrepancy).
        foreach ([['sponge', 10], ['instrument', 25], ['needle', 6]] as [$type, $n]) {
            $count = MedsxCount::firstOrNew(['case_id' => $case2->id, 'count_type' => $type]);
            $count->fill([
                'business_id' => $businessId,
                'pre_count'   => $n,
                'close_count' => $n,
                'final_count' => $n,
                'counted_at'  => now()->subDays(2)->setTime(15, 5),
            ])->save();
        }

        $this->report('MedSurgery demo: ' . ($orRoomId ? '1 OR room, ' : 'no OR room, ') . '2 cases seeded for "Shifa One".');
    }

    /**
     * Ensure exactly one operating room exists in org_rooms for the business.
     * Requires MedOrganization (org_rooms) AND an existing clc_department. Returns
     * the room id, or null when a room could not be ensured (module absent / no
     * department) — the module never creates a parallel rooms table.
     */
    private function ensureOperatingRoom(int $businessId): ?int
    {
        if (! Schema::hasTable('org_rooms') || ! Schema::hasTable('clc_departments')) {
            return null;
        }

        $roomType = config('medsurgery.or_room_type', 'operating');

        $existing = DB::table('org_rooms')
            ->where('business_id', $businessId)
            ->where('room_type', $roomType)
            ->orderBy('id')
            ->value('id');
        if ($existing) {
            return (int) $existing;
        }

        $departmentId = DB::table('clc_departments')
            ->where('business_id', $businessId)
            ->orderBy('id')
            ->value('id');
        if (! $departmentId) {
            return null; // no department to anchor the room — skip (do not invent core data)
        }

        $id = DB::table('org_rooms')->insertGetId([
            'business_id'        => $businessId,
            'department_id'      => (int) $departmentId,
            'name'               => 'Operating Theatre 1',
            'code'               => 'OR-1',
            'room_type'          => $roomType,
            'status'             => 'available',
            'scheduling_enabled' => true,
            'created_at'         => now(),
            'updated_at'         => now(),
        ]);

        return (int) $id;
    }

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