<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

/**
 * cll_specimens — specimen tracking / chain of custody around lab_worklist.
 *
 * A specimen wraps a LabCore worklist order (or a manual / outreach order) with
 * a printable barcode (specimen_no = SPX-{biz}-{seq}) and a full status chain:
 * awaiting_collection → collected → in_transit → received → processing →
 * resulted (or rejected / disposed). It links back to the ClinicCore order item
 * (clc_order_item_id) so a rejection can be pushed to the ordering context.
 */
return new class extends Migration {
    public function up(): void
    {
        if (Schema::hasTable('cll_specimens')) {
            return;
        }

        Schema::create('cll_specimens', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('business_id')->index();
            $table->string('specimen_no', 40)->comment('SPX-{biz}-{seq} — barcode value');
            $table->unsignedInteger('worklist_id')->nullable()->index()->comment('lab_worklist.id');
            $table->unsignedInteger('clc_order_item_id')->nullable()->index()->comment('clc_order_items.id (Wave C)');
            $table->unsignedInteger('patient_id')->nullable()->index()->comment('clc_patients.id');
            $table->unsignedInteger('contact_id')->nullable()->index();
            $table->unsignedInteger('catalog_id')->nullable()->index()->comment('cll_test_catalog.id');
            $table->enum('specimen_type', [
                'blood', 'serum', 'plasma', 'urine', 'stool', 'swab', 'csf', 'tissue', 'other',
            ])->default('blood');
            $table->timestamp('collected_at')->nullable();
            $table->unsignedBigInteger('collected_by')->nullable();
            $table->timestamp('received_at')->nullable();
            $table->unsignedBigInteger('received_by')->nullable();
            $table->enum('status', [
                'awaiting_collection', 'collected', 'in_transit', 'received',
                'processing', 'resulted', 'rejected', 'disposed',
            ])->default('awaiting_collection');
            $table->enum('rejected_reason', [
                'hemolyzed', 'clotted', 'insufficient_volume', 'wrong_container',
                'mislabeled', 'expired', 'other',
            ])->nullable();
            $table->string('rejection_notes', 255)->nullable();
            $table->timestamps();

            $table->unique(['business_id', 'specimen_no'], 'cll_specimen_biz_no_unique');
            $table->index(['business_id', 'status']);
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('cll_specimens');
    }
};
