<?php

declare(strict_types=1);

namespace App\Model;


use Hyperf\Database\Model\Collection;
use Hyperf\Database\Model\Relations\BelongsTo;
use Hyperf\Database\Model\Relations\HasMany;
use Hyperf\Database\Model\Relations\HasOne;
use Hyperf\Database\Model\Relations\HasOneThrough;
use Hyperf\DbConnection\Db;
use Hyperf\Snowflake\Concern\Snowflake;
use Hyperf\Utils\Arr;

/**
 * @property int $doctor_id 主键
 * @property int $user_id 用户id
 * @property string $user_name 用户名称
 * @property string $open_id 微信open_id
 * @property string $union_id 微信开放平台唯一标识
 * @property string $wx_session_key 微信会话密钥
 * @property int $status 状态（0:禁用 1:正常 2:删除）
 * @property int $idcard_status 实名认证状态（0:未认证 1:认证通过 2:认证失败）
 * @property int $iden_auth_status 身份认证状态（0:未认证 1:认证通过 2:审核中 3:认证失败）
 * @property string $iden_auth_time 审核时间
 * @property string $iden_auth_fail_reason 身份认证失败原因
 * @property int $multi_point_status 医生多点执业认证状态（0:未认证 1:认证通过 2:审核中 3:认证失败）
 * @property string $multi_point_time 审核时间
 * @property string $multi_point_fail_reason 多点执业认证失败原因
 * @property int $is_bind_bank 是否已绑定结算银行卡（0:否 1:是）
 * @property int $is_recommend 是否首页推荐（0:否 1:是）
 * @property string $avatar 头像
 * @property int $doctor_title 医生职称（1:执业医师 2:主治医师 3:副主任医师 4:主任医师）
 * @property int $department_custom_id 科室id-自定义
 * @property string $department_custom_name 科室名称（如未自己输入，填入标准科室名称）
 * @property string $department_custom_mobile 科室电话
 * @property int $hospital_id 所属医院id
 * @property int $served_patients_num 服务患者数量
 * @property string $praise_rate 好评率（百分制。订单平均评价中超过4-5分的订单总数 / 总订单数 * 5）
 * @property string $avg_response_time 平均响应时间（分钟制）
 * @property int $number_of_fans 被关注数量
 * @property int $is_online 是否在线（0:不在线 1:在线）
 * @property int $is_img_expert_reception 是否参加专家图文接诊（0:否 1:是）
 * @property int $is_img_welfare_reception 是否参加公益图文问诊（0:否 1:是）
 * @property int $is_img_quick_reception 是否参加快速图文接诊（0:否 1:是）
 * @property int $is_platform_deep_cooperation 是否平台深度合作医生（0:否 1:是）
 * @property int $is_enterprise_deep_cooperation 是否企业深度合作医生（0:否 1:是）
 * @property string $qr_code 分享二维码
 * @property string $be_good_at 擅长
 * @property string $brief_introduction 医生简介
 * @property \Carbon\Carbon $created_at 创建时间
 * @property \Carbon\Carbon $updated_at 修改时间
 * @property-read \Hyperf\Database\Model\Collection|DoctorExpertise[] $DoctorExpertise 
 * @property-read \Hyperf\Database\Model\Collection|DoctorInquiryConfig[] $DoctorInquiryConfig 
 * @property-read Hospital $Hospital 
 * @property-read \Hyperf\Database\Model\Collection|OrderInquiry[] $OrderInquiry 
 */
class UserDoctor extends Model
{
    use Snowflake;

    /**
     * The table associated with the model.
     */
    protected ?string $table = 'user_doctor';

    /**
     * The attributes that are mass assignable.
     */
    protected array $fillable = ['doctor_id', 'user_id', 'user_name', 'open_id', 'union_id', 'wx_session_key', 'status', 'idcard_status', 'iden_auth_status', 'iden_auth_time', 'iden_auth_fail_reason', 'multi_point_status', 'multi_point_time', 'multi_point_fail_reason', 'is_bind_bank', 'is_recommend', 'avatar', 'doctor_title', 'department_custom_id', 'department_custom_name', 'department_custom_mobile', 'hospital_id', 'served_patients_num', 'praise_rate', 'avg_response_time', 'number_of_fans', 'is_online', 'is_img_expert_reception', 'is_img_welfare_reception', 'is_img_quick_reception', 'is_platform_deep_cooperation', 'is_enterprise_deep_cooperation', 'qr_code', 'be_good_at', 'brief_introduction', 'created_at', 'updated_at'];

    protected string $primaryKey = "doctor_id";

    /**
     * 关联医院表
     */
    public function Hospital(): HasOne
    {
        return $this->hasOne(Hospital::class, 'hospital_id', 'hospital_id');
    }

    /**
     * 关联问诊配置表（一对多）
     * @return HasMany
     */
    public function DoctorInquiryConfig(): HasMany
    {
        return $this->hasMany(DoctorInquiryConfig::class, "doctor_id", "doctor_id");
    }

    /**
     * 关联医生专长表
     * @return HasMany
     */
    public function DoctorExpertise(): HasMany
    {
        return $this->hasMany(DoctorExpertise::class, "doctor_id", "doctor_id");
    }

    /**
     * 关联订单-问诊表表
     * @return HasMany
     */
    public function OrderInquiry(): HasMany
    {
        return $this->hasMany(OrderInquiry::class, "doctor_id", "doctor_id");
    }

    /**
     * 获取医生信息-单条
     * @param array $params
     * @param array $fields
     * @return object|null
     */
    public static function getOne(array $params, array $fields = ['*']): object|null
    {
        return self::where($params)->first($fields);
    }

    /**
     * 新增医生-批量
     * @param array $data 新增数据
     * @return \Hyperf\Database\Model\Model|UserDoctor
     */
    public static function addUserDoctor(array $data): \Hyperf\Database\Model\Model|UserDoctor
    {
        return self::create($data);
    }

    /**
     * 修改医生-批量
     * @param array $params
     * @param array $data
     * @return int
     */
    public static function editUserDoctor(array $params = [], array $data = []): int
    {
        return self::where($params)->update($data);
    }

    /**
     * 首页推荐医生
     * 推荐规则：
     * 1：平台深度合作医生
     * 2：接诊量由高到低的医生
     * 3：好评率由高到低的医生
     * 5：在线
     * 6：5个
     * @param int $limit 数量
     * @param array $fields
     * @return array|Collection|\Hyperf\Utils\Collection
     */
    public static function getIndexRecommendDoctorLimit(int $limit = 5, array $fields = ['*']): array|Collection|\Hyperf\Utils\Collection
    {
        $params = array();
        // 状态（0:禁用 1:正常 2:删除）
        $params["status"] = 1;

        // 身份认证状态（0:未认证 1:认证通过 2:审核中 3:认证失败）
        $params["iden_auth_status"] = 1;

        // 是否在线（0:不在线 1:在线）
        $params["is_online"] = 1;

        // 是否参加专家图文接诊（0:否 1:是）
        $params["is_img_expert_reception"] = 1;

        $datas = self::with([
            'Hospital:hospital_id,hospital_name,hospital_level_name',
            'DoctorInquiryConfig',
        ])
            ->where($params)
            ->orderBy("is_platform_deep_cooperation", "desc")
            ->orderBy("served_patients_num", "desc")
            ->orderBy("praise_rate", "desc")
            ->limit($limit)
            ->get($fields);


        return $datas;
    }

    /**
     * 获取问诊医生列表
     * 专家问诊-公益问诊共用
     * @param string $keyword
     * @param array $hospital_params 医院搜索条件
     * @param array $doctor_params 医生搜索条件
     * @param array $doctor_expertise_params
     * @param string|int $sort_order
     * @param array $fields
     * @param int|null $page
     * @param int|null $per_page
     * @return array
     */
    public static function getInquiryDoctorPage(string $keyword = "", array $hospital_params = [], array $doctor_params = [], array $doctor_expertise_params = [], string|int $sort_order = 1, array $fields = ["*"], int $page = null, ?int $per_page = 10): array
    {
        $query = self::with([
            "Hospital:hospital_id,hospital_name,hospital_status,hospital_level_name,province_id,city_id",
            "DoctorExpertise" => function ($query) use ($doctor_expertise_params) {
                $query->where($doctor_expertise_params);
            },
            "DoctorExpertise.DiseaseClassExpertise:expertise_id,expertise_name",
            "DoctorInquiryConfig" => function ($query) use ($sort_order) {
                $params = array();
                $params['inquiry_mode'] = 1;// 接诊方式：图文
                $query->where($params)->whereIn('inquiry_type', [1, 3]);
                if ($sort_order == 1) {
                    // 综合
                    $query->orderBy('inquiry_price', 'asc');// 价格从低到高
                } elseif ($sort_order == 3) {
                    // 价格从低到高
                    $query->orderBy('inquiry_price', 'asc');
                } elseif ($sort_order == 4) {
                    // 价格从高到低
                    $query->orderBy('inquiry_price', 'desc');// 价格从高到低
                }

                return $query;
            },
        ])
            ->where($doctor_params)
            ->whereHas('Hospital', function ($query) use ($hospital_params) {
                $query->where($hospital_params);
            })
            ->when($keyword, function ($query, $keyword) {
                $query->where(function ($query) use ($keyword) {
                    $query->orwhere("user_name", 'like', '%' . $keyword . '%');
                    $query->orwhere("department_custom_name", 'like', '%' . $keyword . '%');
                    $query->orWhereHas('Hospital', function ($query) use ($keyword) {
                        $query->where('hospital_name', 'like', '%' . $keyword . '%');
                    });
                });
            })
            ->when($sort_order, function ($query, $sort_order) {
                if ($sort_order == 1) {
                    $query->orderBy('is_recommend', 'desc');// 是否首页推荐（0:否 1:是）
                    $query->orderBy('avg_response_time', 'desc');// 响应时间快
                    $query->orderBy('served_patients_num', 'desc');// 服务数从多到少
                    $query->orderBy(Db::raw("convert(substr(user_name,1,1) using `GBK`)"), 'asc');// 名称排名
                } elseif ($sort_order == 2) {
                    // 响应时间快
                    $query->orderBy('avg_response_time', 'desc');
                    $query->orderBy(Db::raw("convert(substr(user_name,1,1) using `GBK`)"), 'asc');// 名称排名
                } elseif ($sort_order == 3) {
                    // 响应时间快
                    $query->orderBy('avg_response_time', 'desc');
                    $query->orderBy(Db::raw("convert(substr(user_name,1,1) using `GBK`)"), 'asc');// 名称排名
                } elseif ($sort_order == 4) {
                    // 响应时间快
                    $query->orderBy('avg_response_time', 'desc');
                    $query->orderBy(Db::raw("convert(substr(user_name,1,1) using `GBK`)"), 'asc');// 名称排名
                } elseif ($sort_order == 5) {
                    // 服务数从多到少
                    $query->orderBy('served_patients_num', 'desc');
                    $query->orderBy(Db::raw("convert(substr(user_name,1,1) using `GBK`)"), 'asc');// 名称排名
                }
                return $query;
            });

        $result = $query->paginate($per_page, $fields, "page", $page);

        $data = array();
        $data['current_page'] = $result->currentPage();// 当前页码
        $data['total'] = $result->total();//数据总数
        $data['data'] = $result->items();//数据
        $data['per_page'] = $result->perPage();//每页个数
        $data['last_page'] = $result->lastPage();//最后一页

        return $data;
    }

    /**
     * 获取是否存在
     * @param array $params
     * @return bool
     */
    public static function getExists(array $params): bool
    {
        return self::where($params)->exists();
    }

    /**
     * 获取医生数据
     * 关联医院表
     * @param array $params
     * @param array $fields
     * @return object|null
     */
    public static function getWithHospitalOne(array $params,array $fields = ['*']): object|null
    {
        return self::with([
            "Hospital:hospital_id,hospital_name,hospital_level_name"
        ])
            ->where($params)
            ->first($fields);
    }

    /**
     * 获取数据单
     * @param array $params
     * @param array $not_in_params
     * @param array $fields
     * @return object|null
     */
    public static function getUserDoctorNotInOne(array $params = [], array $not_in_params = [],array $fields = ['*']): object|null
    {
        return self::where($params)->whereNotIn('doctor_id',$not_in_params)->first($fields);
    }
}
