<?php

namespace App\Http\Controllers;
use App\Enums\RecordStatusEnum;
use App\Helpers\Helpers;
use App\Http\Controllers\Helper\GlobalController;
use App\Http\Requests\PatientCreateRequest;
use App\Http\Requests\PatientUpdateRequest;
use App\Models\BaseModel;
use App\Models\Laboratory;
use App\Models\Patient;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;

class PatientController extends Controller
{

    protected $model;
    protected $baseLabId;
    protected $base;
    protected $departments;

    public function __construct(Patient $patientModel){
        $this->model = $patientModel;
        $this->baseLabId = Session::get('base_lab_id');
        $this->base = Session::get('base_lab');

    }

    function province(){
        return parent::province();
    }

    public function index(Request $request){
        if(!GlobalController::user_can(Auth::user()->role_id, ['view_patient'])) return redirect(url('my-profile'));
        $provinces = $this->province();
        $patients = $this->model::with(['samples'])->where(BaseModel::RECORD_STATUS_FIELD, RecordStatusEnum::ACTIVE)
            ->where('lab_id', $this->baseLabId)
            ->when(!empty(trim($request->kword)), function ($patients) use($request){
                $patients->whereRaw(
                    "(replace(name_en, ' ', '') LIKE ? OR replace(phone_number, ' ', '') LIKE ? OR replace(patient_uuid, ' ', '') LIKE ? OR replace(khid_number, ' ', '') LIKE ?) and lab_id = ?",
                    [
                        '%' . str_replace(' ', '', $request->kword) . '%',
                        '%' . str_replace(' ', '', $request->kword) . '%',
                        '%' . str_replace(' ', '', $request->kword) . '%',
                        '%' . str_replace(' ', '', $request->kword) . '%',
                        $this->baseLabId
                    ]
                );
            })->orderBy(BaseModel::CREATED_AT_FIELD,'desc')->paginate(config('labis.pagination.perpage', 10));
        return view('patient', ['provinces' => $provinces, 'patients' => $patients, 'labSettings' => (object) $this->base]);
    }

    public function save(PatientCreateRequest $patientCreateRequest){
        DB::beginTransaction();
        try{
            if(!GlobalController::user_can(Auth::user()->role_id, ['create_patient'])) return false;
            $dob = $patientCreateRequest->dob;
            $datePart = explode("-",$dob);
            if($datePart[1]>12){
            	$dob =  $datePart[1].'-'.$datePart[0].'-'.$datePart[2];
            }
            $requests = collect($patientCreateRequest)->merge([
                'lab_id' => $this->baseLabId,
                BaseModel::CREATED_AT_FIELD => date('Y-m-d H:i:s'),
                BaseModel::CREATED_BY_FIELD => Auth::id(),
                BaseModel::UPDATED_AT_FIELD => NULL,
                BaseModel::UPDATED_BY_FIELD => NULL,
                BaseModel::RECORD_STATUS_FIELD => BaseModel::RECORD_STATUS_ACTIVE
            ])->replace(
                [
                    'dob' => date('Y-m-d', strtotime($dob)),
                    'phone_number' => $patientCreateRequest->phone_number // preg_replace('/ /i', '', trim($patientCreateRequest->phone_number))
                ]);

            if(empty($patientCreateRequest->patient_uuid)) {
                $patientNumber = $this->generateAutoId(date('Y-m-d'));
                $requests = $requests->merge(['patient_uuid' => $patientNumber]);
            }

            $patient = $this->model::query()->create($requests->all());
            DB::commit();
            return response()->json(['success'=> true , 'message' => __('patient.create_success') , 'data' => $patient]);
        } catch (\Exception $e){
            DB::rollBack();
            Log::error($e);
            return response()->json(['success'=> false , 'message' => __('patient.create_fail') , 'errors' => $e->getMessage()]);
        }
    }

    public function update(PatientUpdateRequest $patientUpdateRequest){
        DB::beginTransaction();
        try{
            if(!GlobalController::user_can(Auth::user()->role_id, ['update_patient'])) return false;
            $dob = $patientUpdateRequest->dob;
            $datePart = explode("-",$dob);
            if($datePart[1]>12){
            	$dob =  $datePart[1].'-'.$datePart[0].'-'.$datePart[2];
            }

            $requests = collect($patientUpdateRequest)->merge([
                BaseModel::UPDATED_AT_FIELD => date('Y-m-d H:i:s'),
                BaseModel::UPDATED_BY_FIELD => Auth::id()
            ])->replace([
                        'dob' => date('Y-m-d', strtotime($dob)),
                        'phone_number' => $patientUpdateRequest->phone_number // preg_replace('/ /i', '', trim($patientUpdateRequest->phone_number))
                    ])->except(['patient_uuid','uid']);
            $patient = $this->model::query()->find($patientUpdateRequest->uid)->update($requests->all());
            DB::commit();
            return response()->json(['success'=> true , 'message' => __('patient.update_success'), 'data' => array('id' => $patientUpdateRequest->uid) ]);
        } catch (\Exception $e){
            DB::rollBack();
            Log::error($e);
            return response()->json(['success'=> false , 'message' => __('patient.update_fail'), 'errors' => [$e->getMessage()]]);
        }
    }

    public function get(Request $request){
        try{
            $patient = $this->model::query()->find($request->uid);
            return response()->json(['success'=> true , 'message' => __('patient.get_success') , 'data' => $patient]);
        }
        catch (\Exception $e){
            return response()->json(['success'=> false , __('patient.get_fail'), 'errors' => $e->getMessage()]);
        }

    }

    public function delete(Request $request){
        try{
            if(!GlobalController::user_can(Auth::user()->role_id, ['delete_patient'])) return false;
            $patient = $this->model::query()->find($request->uid);
            $patient->update(array(BaseModel::RECORD_STATUS_FIELD => RecordStatusEnum::DELETE));
            return response()->json(['success'=> true, 'message' => __('patient.delete_success'), 'data' => $patient]);
        }
        catch (\Exception $e){
            return response()->json(['success'=> false, 'message' => __('patient.delete_fail'), 'errors' => $e->getMessage()]);
        }
    }

    public function restore(Request $request){
        try{
            $patient = $this->model::query()->find($request->uid);
            $patient->update(array(BaseModel::RECORD_STATUS_FIELD => RecordStatusEnum::ACTIVE));
            return response()->json(['success'=> true, 'message' => __('patient.restore_success'), 'data' => $patient]);
        }
        catch (\Exception $e){
            return response()->json(['success'=> false, 'message' => __('patient.restore_success'), 'errors' => $e->getMessage()]);
        }
    }

    public function search(Request $request)
    {
        try{
            $patients = $this->model::query()->where([BaseModel::RECORD_STATUS_FIELD => RecordStatusEnum::ACTIVE, 'lab_id' => $this->baseLabId])
                ->when($request->kword!='', function($patients) use ($request) {
                    $patients->whereRaw(
                    "(replace(name_en, ' ', '') LIKE ? OR replace(phone_number, ' ', '') LIKE ? OR replace(patient_uuid, ' ', '') LIKE ? OR replace(khid_number, ' ', '') LIKE ?) and lab_id = ?",
                    [
                        '%' . str_replace(' ', '', $request->kword) . '%',
                        '%' . str_replace(' ', '', $request->kword) . '%',
                        '%' . str_replace(' ', '', $request->kword) . '%',
                        '%' . str_replace(' ', '', $request->kword) . '%',
                        $this->baseLabId
                    ]
                );
                })->orderBy('name_en','asc')->limit(config('labis.pagination.perpage', 10))->get();
		return response()->json(['success'=> true, __('patient.get_success'), 'data' => $patients]);
        }
        catch (\Exception $e){
            return response()->json(['success'=> false, __('patient.get_fail'), 'errors' => [$e->getMessage()]]);
        }
    }

    public function patientSearchAjax(Request $request)
    {
        try{
            $provinces = $this->province();
            $patients = $this->model::query()->where([BaseModel::RECORD_STATUS_FIELD => RecordStatusEnum::ACTIVE, 'lab_id' => $this->baseLabId])
                ->when($request->kword!='', function($patients) use ($request) {
                    $patients->whereRaw(
                    "(replace(name_en, ' ', '') LIKE ? OR replace(phone_number, ' ', '') LIKE ? OR replace(patient_uuid, ' ', '') LIKE ? OR replace(khid_number, ' ', '') LIKE ?) and lab_id = ?",
                    [
                        '%' . str_replace(' ', '', $request->kword) . '%',
                        '%' . str_replace(' ', '', $request->kword) . '%',
                        '%' . str_replace(' ', '', $request->kword) . '%',
                        '%' . str_replace(' ', '', $request->kword) . '%',
                        $this->baseLabId
                    ]
                );
                })->orderBy('name_en','asc')->paginate(config('labis.pagination.perpage', 10));
            return view('partials.patient_list', ['provinces' => $provinces, 'patients' => $patients, 'labSettings' => (object) $this->base]);
        }
        catch (\Exception $e){
            return response()->json(['success'=> false, __('patient.get_fail'), 'errors' => [$e->getMessage()]]);
        }
    }

    public function generateAutoId($admissionDate){
        $prefix = date('y',strtotime($admissionDate));
        $patientCount = $this->model::query()->where('lab_id', $this->baseLabId)->whereRaw('year(created_at) ="'. date('Y',strtotime($admissionDate)).'"')->count();
        if($this->baseLabId==34) $patientCount = $patientCount+5; // solve problem when delete patient
        return 'P-'.$this->base['short_name'].'-'.$prefix.'-'.(str_pad(($patientCount+1),5,'0',STR_PAD_LEFT));
    }


    public function searchPatientToSelect2(Request $request){
        $patients = [];
        if(!empty(trim($request->term))){
        $patients = $this->model::query()
            ->where([BaseModel::RECORD_STATUS_FIELD => RecordStatusEnum::ACTIVE, 'lab_id' => $this->baseLabId])
            ->when(!empty(trim($request->term)), function ($patients) use($request){
                $patients->whereRaw(
                    "(replace(name_en, ' ', '') LIKE ? OR replace(phone_number, ' ', '') LIKE ? OR replace(patient_uuid, ' ', '') LIKE ? OR replace(khid_number, ' ', '') LIKE ?) and lab_id = ?",
                    [
                        '%' . str_replace(' ', '', $request->term) . '%',
                        '%' . str_replace(' ', '', $request->term) . '%',
                        '%' . str_replace(' ', '', $request->term) . '%',
                        '%' . str_replace(' ', '', $request->term) . '%',
                        $this->baseLabId
                    ]
                );
            })->limit(20)->orderBy('name_en', 'asc')->get();
        }
        $items = [];
        if(!empty($patients)){
            $items = $patients->map(function ($item){
                return array('id'=>$item->id, 'text' => $item->patient_uuid . ' - '.$item->name_en . ((!empty($item->phone_number) ? ' - '.$item->phone_number: '')));
            });
        }
        return response()->json(['results' => $items]);
    }



}
