<?php

namespace Mtc\Plugins\Wisebee\Classes\Models;

use App\Casts\OptionalEncrypted;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Mtc\Shop\Item;

/**
 * Accessors
 *
 * @property int $id
 * @property int $wisebee_id
 * @property int $wisebee_user_id
 * @property int $wisebee_created_by_id
 * @property int $wisebee_rate_id
 * @property int $wisebee_specialty_id
 * @property int $wisebee_location_id
 * @property int $item_id
 * @property string $status
 * @property string $public_key
 * @property string $comments
 * @property string $consultation_date
 * @property string $time_from
 * @property string $time_to
 * @property float $cost
 * @property int $length
 * @property int $cooldown
 * @property string $specialist
 * @property string $specialty
 * @property bool $added_to_basket
 * @property string $updated_at
 * @property string $created_at
 *
 * @property Item $item
 * @property Collection $documents
 *
 */
class WisebeeConsultation extends Model
{
    protected $table = 'wisebee_consultations';

    protected $fillable = [
        'wisebee_id',
        'wisebee_user_id',
        'wisebee_created_by_id',
        'wisebee_rate_id',
        'wisebee_specialty_id',
        'wisebee_location_id',
        'item_id',
        'status',
        'public_key',
        'comments',
        'consultation_date',
        'time_from',
        'time_to',
        'cost',
        'length',
        'cooldown',
        'specialist',
        'specialty',
        'added_to_basket',
    ];

    protected $casts = [
        'added_to_basket' => 'boolean',
        'comments' => OptionalEncrypted::class,
    ];

    const STATUS_TEMPORARY = 'temporary';
    const STATUS_PENDING = 'pending';
    const STATUS_LIVE = 'live';
    const STATUS_COOLDOWN = 'cooldown';
    const STATUS_COMPLETE = 'complete';
    const STATUS_CANCELLED = 'cancelled';

    const CAN_JOIN_MINUTES_PRIOR_CONSULTATION = 30;

    public function documents(): HasMany
    {
        return $this->hasMany(WisebeeDocument::class, 'consultation_id');
    }

    public function participants(): HasMany
    {
        return $this->hasMany(WisebeeParticipant::class, 'wisebee_consultation_id', 'wisebee_id');
    }

    public function item(): BelongsTo
    {
        return $this->belongsTo(Item::class, 'item_id');
    }

    /**
     * Get a collection of member's consultations
     *
     * @param $memberID
     * @return \Illuminate\Support\Collection
     */
    public static function getMemberConsultations($memberID): \Illuminate\Support\Collection
    {
        return self::query()
            ->where('status', '!=', self::STATUS_TEMPORARY)
            ->whereHas('participants', function (Builder $query) use ($memberID) {
                $query->where('type', WisebeeParticipant::TYPE_CUSTOMER)
                    ->whereHas('customer', function (Builder $query) use ($memberID) {
                        $query->where('member_id', $memberID);
                    });
            })
            ->orderByDesc('time_from')
            ->get()
            ->map(function (WisebeeConsultation $consultation) {
                $consultation->date = Carbon::parse($consultation->consultation_date)
                    ->format('d/m/Y');
                $consultation->time = Carbon::parse($consultation->time_from)->format('H:i') . ' - ' .
                    Carbon::parse($consultation->time_to)->format('H:i');

                $consultation->user = null;
                $specialistParticipant = $consultation->participants
                    ->where('type', WisebeeParticipant::TYPE_SPECIALIST)
                    ->first();
                if (!empty($specialistParticipant)) {
                    $consultation->user = $specialistParticipant->firstname . ' ' . $specialistParticipant->lastname;
                }
                $customerParticipant = $consultation->participants
                    ->where('type', WisebeeParticipant::TYPE_CUSTOMER)
                    ->first();

                $consultation->paymentRequired = false;
                if (
                    $customerParticipant->status === WisebeeParticipant::STATUS_PENDING &&
                    $consultation->cost > 0
                ) {
                    $consultation->paymentRequired = true;
                }

                $consultation->url = $consultation->paymentRequired ?
                    route('wisebee-book', [
                        'ocp_action' => 'pay',
                        'ocp_key' => $customerParticipant->hash,
                        'ocp_id' => $consultation->wisebee_id,
                    ]) :
                    route('wisebee-consultation', [
                        'ocp_action' => 'video',
                        'ocp_key' => $customerParticipant->hash,
                        'ocp_id' => $consultation->wisebee_id,
                    ]);
                $consultation->showButton = $consultation->canOpenVideo() || $consultation->paymentRequired;
                return $consultation;
            });
    }


    /**
     * Whether the customer can join the video
     *
     * @return bool
     */
    public function canOpenVideo(): bool
    {
        if (!in_array($this->status, [
            WisebeeConsultation::STATUS_PENDING,
            WisebeeConsultation::STATUS_LIVE,
        ])) {
            return false;
        }

        return Carbon::now()->diffInMinutes(Carbon::parse($this->time_from), false) < self::CAN_JOIN_MINUTES_PRIOR_CONSULTATION;
    }
}