<?php

declare(strict_types=1);

namespace App\Models;

use App\Dictionary\Patient\Sex;
use App\Utils\Traits\UniversalEncryption;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

/**
 * @method where(string $string, string $open_id)
 * @method create(array $data)
 */
class Patient extends Model
{
    use HasFactory;
    use UniversalEncryption;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'union_id',
        'open_id',
        'patient_id',
        'patient_number',
        'card_type',
        'card_no',
        'name',
        'sex',
        'birthday',
        'mobile_phone',
        'address',
        'qr_code_text',
        'health_card_id',
        'health_card_status',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'id' => 'integer',
        'card_type' => 'integer',
        'sex' => 'integer',
        'health_card_status' => 'integer',
    ];

    /**
     * Relationships Order.
     */
    public function order(): HasMany
    {
        return $this->hasMany(Order::class, 'patient_id');
    }

    /**
     * Relationships RegistrationRecord.
     */
    public function registrationRecord(): HasMany
    {
        return $this->hasMany(Order::class, 'relate_patient_id');
    }

    /**
     * Relationships outpatientPaymentRecord.
     */
    public function outpatientPaymentRecord(): HasMany
    {
        return $this->hasMany(Order::class, 'relate_patient_id');
    }

    /**
     * 获取绑定患者数量
     * @param string $open_id
     * @return mixed
     */
    public function getBindPatientCount(string $open_id): mixed
    {
        return $this->where('open_id', $open_id)->count();
    }

    /**
     * 获取患者列表
     * @param string $open_id
     * @return mixed
     */
    public function getBindPatientLists(string $open_id): mixed
    {
        return $this->where('open_id', $open_id)->orderByDesc('def_status')->get();
    }

    /**
     * 获取默认患者数据
     * @param string $open_id
     * @return mixed
     */
    public function getBindDefaultPatientInfo(string $open_id): mixed
    {
        return $this->where('open_id', $open_id)->orderByDesc('def_status')->first();
    }

    /**
     * 获取绑定患者信息
     * @param string $open_id
     * @param string $patient_id
     * @return mixed
     */
    public function getBindPatientInfo(string $open_id, string $patient_id): mixed
    {
        return $this->where('open_id', $open_id)->where('patient_id', $patient_id)->first();
    }

    /**
     * 获取绑定患者信息By Id
     * @param string $open_id
     * @param string $patient_id
     * @return mixed
     */
    public function getBindPatientInfoByPatientId(string $open_id, string $patient_id): mixed
    {
        return $this->where('open_id', $open_id)->where('patient_id', $patient_id)->first();
    }

    /**
     * 获取绑定患者信息By number
     * @param string $open_id
     * @param string $patient_number
     * @return mixed
     */
    public function getBindPatientInfoByPatientNumber(string $open_id, string $patient_number): mixed
    {
        return $this->where('open_id', $open_id)->where('patient_number', $patient_number)->first();
    }

    /**
     * 获取绑定患者信息By Patient Id
     * @param string $patient_id
     * @return mixed
     */
    public function getPatientInfoByPatientId(string $patient_id): mixed
    {
        return $this->where('patient_id', $patient_id)->first();
    }


    /**
     * 建档
     * @param string $union_id
     * @param string $open_id
     * @param string $patient_id
     * @param string $patient_number
     * @param string $name
     * @param Sex $gender
     * @return mixed
     */
    public function createPatient(string $union_id, string $open_id, string $patient_id, string $patient_number, string $name, Sex $gender): mixed
    {
        $data = [
            'union_id'       => $union_id,
            'open_id'        => $open_id,
            'patient_id'     => $patient_id,
            'patient_number' => $patient_number,
            'card_type'      => 0,
            'card_no'        => '',
            'name'           => $name,
            'sex'            => $gender->value,
            'birthday'       => '',
            'mobile_phone'   => '',
            'address'        => '',
            'def_status'     => 0
        ];

        $count = $this->where('open_id', $open_id)->where('def_status', 1)->count();
        if (!$count) {
            $data['def_status'] = 1;
        }

        return $this->create($data);
    }

    /**
     * 设置默认
     * @param string $open_id
     * @param string $patient_id
     * @return bool
     */
    public function setDefaultPatient(string $open_id, string $patient_id): bool
    {
        $this->where('open_id', $open_id)->update(['def_status' => 0]);
        $res = $this->where('open_id', $open_id)->where('patient_id', $patient_id)->update(['def_status' => 1]);

        return !!$res;
    }

    /**
     * 删卡
     * @param string $open_id
     * @param string $patient_id
     * @return integer
     */
    public function deletePatient(string $open_id, string $patient_id): int
    {
        return $this->where('open_id', $open_id)->where('patient_id', $patient_id)->delete();
    }
}