<?php

namespace Mtc\Plugins\Clinic\Src\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Mtc\Core\AdminUser;
use Mtc\Modules\Members\Models\Member;
use Mtc\Plugins\Clinic\Src\BMI;
use Mtc\Plugins\Clinic\Src\Clinic;
use Mtc\Plugins\Clinic\Src\Logger;
use Mtc\Shop\Assessment\Assessment;
use Mtc\Shop\Assessment\Question;

/**
 * Accessors
 *
 * @property int $id
 * @property int $member_id
 * @property int $user_id
 * @property int $review_id
 * @property int $height
 * @property int $weight
 * @property float $bmi
 * @property string $date_provided
 *
 * @property Carbon $created_at
 * @property Carbon $updated_at
 *
 * @property Member $member
 * @property Review $review
 * @property AdminUser $user
 */
class WeightTrack extends Model
{
    protected $table = 'patient_weight_track';

    protected $fillable = [
        'member_id',
        'user_id',
        'review_id',
        'height',
        'weight',
        'bmi',
        'date_provided',
    ];

    /**
     * @return BelongsTo
     */
    public function member(): BelongsTo
    {
        return $this->belongsTo(Member::class, 'member_id');
    }

    /**
     * @return BelongsTo
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(AdminUser::class, 'item_id');
    }

    /**
     * @return BelongsTo
     */
    public function review(): BelongsTo
    {
        return $this->belongsTo(Review::class, 'review_id');
    }

    /**
     * Simple validator
     *
     * @param array $input
     * @return array
     */
    public static function validate(array $input): array
    {
        $required = [
            'height',
            'weight',
            'bmi',
        ];

        $errors = [];

        foreach ($required as $field) {
            if (empty($input[$field])) {
                $errors[$field] = 'This field is required';
            }
        }

        return $errors;
    }

    /**
     * Checks if the assessment has BMI answer and store it to weight track
     *
     * @param Assessment $assessment
     * @return void
     */
    public static function checkAndStoreFromAssessment(Assessment $assessment): void
    {
        if (empty($assessment->member_id)) {
            // No member to store BP readings against
            return;
        }
        $assessment->refresh();
        $bmiAnswer = $assessment
            ->answers()
            ->with('question')
            ->whereHas('question', function (Builder $query): void {
                $query->where('question_type', Question::TYPE_BMI);
            })
            ->first();

        if (empty($bmiAnswer)) {
            return;
        }

        $bmiValues = json_decode($bmiAnswer->answer)->bmi;
        if (empty($bmiValues->type)) {
            return;
        }

        if (strtolower($bmiValues->type) === 'metric') {
            $metric = $bmiValues->metric;
            $height = $metric->height_cm;
            $weight = $metric->weight_kg;
        } else {
            $imperial = $bmiValues->imperial;
            $height = BMI::convertHeightToMetric($imperial->height_feet, $imperial->height_inches);
            $weight = BMI::convertWeightToMetric($imperial->weight_stone, $imperial->weight_pounds);
        }

        $weightTrack = WeightTrack::query()
            ->create([
                'member_id' => $assessment->member_id,
                'review_id' => $assessment->review_id,
                'ethnicity_id' => $bmiValues->ethnicity->id,
                'weight' => $weight,
                'height' => $height,
                'bmi' => $bmiValues->value,
                'date_provided' => $assessment->created_at->format('Y-m-d'),
            ]);

        new Logger($weightTrack, Clinic::getActor(), $assessment->member_id)
            ->log(Logger::WEIGHT_TRACK, Logger::ACTION_CREATED, $weightTrack->toArray());

        //Update height on member
        Member::query()
            ->where('id', $assessment->member_id)
            ->update([
                'height' => $height,
            ]);
    }
}
