<?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 $medium
 * @property string $specialist
 * @property string $specialty
 * @property bool $added_to_basket
 * @property string $updated_at
 * @property string $created_at
 *
 * @property Item|null $item
 * @property Collection $documents
 * @property Collection $participants
 *
 */
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',
        'medium',
        '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 STATUS_NOSHOW = 'no-show';

    public static $statuses = [
        self::STATUS_PENDING,
        self::STATUS_LIVE,
        self::STATUS_COMPLETE,
        self::STATUS_CANCELLED,
        self::STATUS_NOSHOW,
    ];

    const MEDIUM_VIDEO = 'video';
    const MEDIUM_IN_PERSON = 'in_person';
    const MEDIUM_PHONE = 'phone';

    public static $mediums = [
        self::MEDIUM_VIDEO => 'Online',
        self::MEDIUM_PHONE => 'Phone call',
        self::MEDIUM_IN_PERSON => 'In person',
    ];

    const int CAN_JOIN_MINUTES_PRIOR_CONSULTATION = 120;

    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;
                }

                $actions = [];
                if ($consultation->status === WisebeeConsultation::STATUS_PENDING) {
                    $actions[] = [
                        'url' => route('wisebee-book', [
                            'ocp_action' => 'update',
                            'ocp_key' => $customerParticipant->hash,
                            'ocp_id' => $consultation->wisebee_id,
                        ]),
                        'name' => 'Reschedule / Cancel',
                    ];
                    if ($consultation->paymentRequired) {
                        $actions[] = [
                            'url' => route('wisebee-book', [
                                'ocp_action' => 'pay',
                                'ocp_key' => $customerParticipant->hash,
                                'ocp_id' => $consultation->wisebee_id,
                            ]),
                            'name' => 'Pay',
                        ];
                    }
                }
                if ($consultation->canOpenVideo()) {
                    $actions[] = [
                        'url' => route('wisebee-consultation', [
                            'ocp_action' => 'video',
                            'ocp_key' => $customerParticipant->hash,
                            'ocp_id' => $consultation->wisebee_id,
                        ]),
                        'name' => 'Join video',
                    ];
                }
                $consultation->actions = $actions;

                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;
        }

        if ($this->medium !== self::MEDIUM_VIDEO) {
            return false;
        }

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