<?php

namespace App\Models;
use App\Enums\RecordStatusEnum;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;

class Sample extends BaseModel
{
    public $timestamps = false;
    use HasFactory;
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'samples';

    protected $fillable = ['patient_id','admission_date','sample_number','sample_source_id','physician_id',
        'sample_condition','reject_comment_id','collected_date','received_date','diagnosis','is_urgent', 'is_printed', 'printed_by','printed_at',
        'approved_by','approved_date', 'requested_date','is_accept_request','lab_id', BaseModel::CREATED_AT_FIELD, BaseModel::CREATED_BY_FIELD,
        BaseModel::UPDATED_AT_FIELD, BaseModel::UPDATED_BY_FIELD, BaseModel::RECORD_STATUS_FIELD,
        'result_template_id'
    ];

    //protected $appendsv = ['state'];
    protected $append = ['state','progress'];

    public static function boot()
    {
        parent::boot();
    }

    public function lab(){
        return $this->belongsTo(Laboratory::class, 'lab_id','id');
    }

    public function patient(){
        return $this->belongsTo(Patient::class, 'patient_id','id');
    }

    public function sample_source(){
        return $this->belongsTo(SampleSource::class, 'sample_source_id','id');
    }

    public function sample_details(){
        return $this->hasMany(SampleDetail::class, 'sample_id', 'id')
            ->where([BaseModel::RECORD_STATUS_FIELD => RecordStatusEnum::ACTIVE, 'lab_id' => Session::get('base_lab_id')]);
    }

    public function sample_tests(){
        return $this->hasMany(TestResult::class, 'sample_id', 'id')
            ->where([BaseModel::RECORD_STATUS_FIELD => RecordStatusEnum::ACTIVE, 'lab_id' => Session::get('base_lab_id')]);
    }

    public function entryBy(){
        return $this->belongsTo(User::class, 'created_by', 'id');
    }

    public function modifiedBy(){
        return $this->belongsTo(User::class, 'updated_by', 'id');
    }

    public function physician(){
        return $this->belongsTo(Physician::class, 'physician_id', 'id');
    }

    public function invoice(){
        return $this->belongsTo(Invoice::class, 'id', 'sample_id')->where([BaseModel::RECORD_STATUS_FIELD => RecordStatusEnum::ACTIVE, 'lab_id' => Session::get('base_lab_id')]);
    }

    function getStateAttribute(){
        $state = '#FF0000';
        $sampleCondition = $this->sample_condition;
        $samplePrinted = $this->is_printed;
        $sampleId = $this->id;

        $resultItemsData = DB::select('
                                    SELECT
                                        s.id,
                                        s.`sample_number`,
                                        SUM(IF(ts.`field_type`>0, 1,0)) AS non_heading_tests,
                                        SUM(IF(ts.`field_type` IN(1,4) AND tr.test_result IS NOT NULL, 1, 0)) AS done_numeric_tests,
                                        SUM(IF(ts.`field_type` IN(2,3) AND org_result.total_org_result>0, 1, 0)) AS done_org_test
                                    FROM samples s
                                    LEFT JOIN test_results tr
                                    ON tr.`sample_id` = s.`id`
                                    AND s.`lab_id` = tr.`lab_id`
                                    LEFT JOIN test_samples ts
                                    ON ts.id = tr.`test_sample_id`
                                    AND ts.lab_id = tr.lab_id
                                    LEFT JOIN sample_types st
                                    ON st.id = ts.`sample_type_id`
                                    LEFT JOIN(
                                        SELECT
                                            tr.`id`,
                                            COUNT(*) AS total_org_result
                                        FROM samples s
                                        INNER JOIN test_results tr
                                        ON tr.`sample_id` = s.`id`
                                        AND s.`lab_id` = tr.`lab_id`
                                        INNER JOIN organism_results orgr
                                        ON orgr.`test_result_id` = tr.`id`
                                        WHERE s.id = '.$sampleId.'
                                        AND tr.`record_status_id` = 1
                                        AND orgr.`record_status_id` = 1
                                        group by tr.id
                                    ) AS org_result
                                    ON org_result.id = tr.`id`
                                    WHERE s.`id` = '.$sampleId.'
                                    AND (tr.`record_status_id` = 1 OR tr.`record_status_id` IS NULL)
	                                AND (st.`record_status_id` = 1 OR st.`record_status_id` IS NULL)
                                    GROUP BY s.`sample_number`, s.id');

        $non_heading_tests = 0;
        $done_numeric_tests = 0;
        $done_org_test = 0;
        foreach ($resultItemsData as $v){
            $non_heading_tests = $v->non_heading_tests;
            $done_numeric_tests = $v->done_numeric_tests;
            $done_org_test = $v->done_org_test;
        }

        if(!is_null($sampleCondition) && $sampleCondition==0) $state = '#FFA500'; // orange for rejected
        elseif(($sampleCondition!=0 || is_null($sampleCondition)) && $samplePrinted) $state = '#3b86d1'; // blue for printed
        else {
            if($non_heading_tests==0) $state = '#FF0000';
            else if($non_heading_tests>0 && $non_heading_tests == ($done_numeric_tests+$done_org_test)){
                $state = '#008000'; // Green for fully completed
            }
            elseif($non_heading_tests>0 && ($done_numeric_tests+$done_org_test)==0){
                $state = '#FF0000'; // Red for No result at all
            }
            elseif(($done_numeric_tests+$done_org_test)>0 && $non_heading_tests >($done_numeric_tests+$done_org_test)){
                $state = '#FFFF00'; // Yellow for complete some
            }
            else $state = '#FF0000'; //Silver for known state
        }
        return $state;
    }

    function getProgressAttribute(){
        $state = '#FF0000';
        $sampleCondition = $this->sample_condition;
        $samplePrinted = $this->is_printed;
        $sampleId = $this->id;

        $resultItemsData = DB::select('
                                    SELECT
                                        s.id,
                                        s.`sample_number`,
                                        SUM(IF(ts.`field_type`>0, 1,0)) AS non_heading_tests,
                                        SUM(IF(ts.`field_type` IN(1,4) AND tr.test_result IS NOT NULL, 1, 0)) AS done_numeric_tests,
                                        SUM(IF(ts.`field_type` IN(2,3) AND org_result.total_org_result>0, 1, 0)) AS done_org_test
                                    FROM samples s
                                    LEFT JOIN test_results tr
                                    ON tr.`sample_id` = s.`id`
                                    AND s.`lab_id` = tr.`lab_id`
                                    LEFT JOIN test_samples ts
                                    ON ts.id = tr.`test_sample_id`
                                    AND ts.lab_id = tr.lab_id
                                    LEFT JOIN sample_types st
                                    ON st.id = ts.`sample_type_id`
                                    LEFT JOIN(
                                        SELECT
                                            tr.`id`,
                                            COUNT(*) AS total_org_result
                                        FROM samples s
                                        INNER JOIN test_results tr
                                        ON tr.`sample_id` = s.`id`
                                        AND s.`lab_id` = tr.`lab_id`
                                        INNER JOIN organism_results orgr
                                        ON orgr.`test_result_id` = tr.`id`
                                        WHERE s.id = '.$sampleId.'
                                        AND tr.`record_status_id` = 1
                                        AND orgr.`record_status_id` = 1
                                        group by tr.id
                                    ) AS org_result
                                    ON org_result.id = tr.`id`
                                    WHERE s.`id` = '.$sampleId.'
                                    AND (tr.`record_status_id` = 1 OR tr.`record_status_id` IS NULL)
	                                AND (st.`record_status_id` = 1 OR st.`record_status_id` IS NULL)
                                    GROUP BY s.`sample_number`, s.id');

        $non_heading_tests = 0;
        $done_numeric_tests = 0;
        $done_org_test = 0;
        foreach ($resultItemsData as $v){
            $non_heading_tests = $v->non_heading_tests;
            $done_numeric_tests = $v->done_numeric_tests;
            $done_org_test = $v->done_org_test;
        }

        if(!is_null($sampleCondition) && $sampleCondition==0) $state = __('sample.filter_rejected'); // '#FFA500'; // orange for rejected
        elseif(($sampleCondition!=0 || is_null($sampleCondition)) && $samplePrinted) $state = __('sample.filter_printed'); // '#3b86d1'; // blue for printed
        else {
            if($non_heading_tests==0) $state = __('sample.filter_pending');
            else if($non_heading_tests>0 && $non_heading_tests == ($done_numeric_tests+$done_org_test)){
                $state = __('sample.filter_completed'); // '#008000'; // Green for fully completed
            }
            elseif($non_heading_tests>0 && ($done_numeric_tests+$done_org_test)==0){
                $state = __('sample.filter_pending'); //'#FF0000'; // Red for No result at all
            }
            elseif(($done_numeric_tests+$done_org_test)>0 && $non_heading_tests >($done_numeric_tests+$done_org_test)){
                $state = __('sample.filter_processing'); // '#FFFF00'; // Yellow for complete some
            }
            else $state =  __('sample.filter_pending'); //Silver for known state
        }
        return $state;
    }


}
