<?php

namespace App\Models;

use App\Repositories\EventRepository;
use App\Traits\HasFiles;
use App\Traits\Repository;
use Illuminate\Database\Eloquent\Casts\AsArrayObject;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Spatie\Permission\Traits\HasRoles;

/**
 * @property mixed form_settings
 * @property mixed publish_step
 * @property mixed contents
 * @property mixed platform_settings
 * @property mixed theme
 * @property mixed score_settings
 * @property bool published
 * @property integer id
 * @property false|mixed|string published_date
 * @property mixed slug_name
 * @property mixed event_name
 * @property array|mixed $general_settings
 * @property Session $sessions
 */
class Event extends Model
{
    use HasFactory, Repository, HasFiles;

    const FILE_SAVE_PATH = 'public/media/events/';
    const FILE_PUBLIC_PATH = 'storage/media/events/';
    const PRIVATE_FILE_SAVE_PATH = 'private/media/events/';

    protected $casts = [
        'contents' => AsArrayObject::class,
        'form_settings' => AsArrayObject::class,
        'clone_form_settings' => AsArrayObject::class,
        'score_settings' => AsArrayObject::class,
        'platform_settings' => AsArrayObject::class,
        'event_profile_data' => AsArrayObject::class,
        'theme' => AsArrayObject::class,
        'general_settings' => AsArrayObject::class,
        'published' => 'boolean',
        'developer_options' => 'boolean',
        'all_user_api_access' => 'boolean',
        'user_export_access' => 'boolean',
        'abstract_export_access' => 'boolean',
        'presentation_files_download_access' => 'boolean'
    ];

    protected $fillable = [
        'event_name',
        'slug_name',
        'edition_ids',
        'division',
        'year',
        'contents',
        'form_settings',
        'score_settings',
        'platform_settings',
        'theme',
        'general_settings',
        'status'
    ];

    public function users($role = null): BelongsToMany
    {
        $query = $this->belongsToMany(User::class, 'event_user')
            ->using(EventUser::class)
            ->withPivot(['id', 'confirmed_speaker', 'speaker_added_via', 'agreement_status', 'agreement_details'])
            ->withTimestamps();
        if ($role) {
            $query->join('model_has_roles as mhs', 'mhs.model_id', '=', 'event_user.id')
                ->where('mhs.model_type', '=', EventUser::class)
                ->join('roles as r', 'r.id', '=', 'mhs.role_id')
                ->where('r.name', '=', $role);
        }
        return $query;
    }

    public function speakers(): BelongsToMany
    {
        return $this->belongsToMany(User::class, 'event_user')
            ->using(EventUser::class)
            ->withPivot(['id', 'confirmed_speaker', 'speaker_added_via', 'agreement_status', 'agreement_details'])
            ->where('event_user.confirmed_speaker', '=', true)
            ->withTimestamps();

    }

    public function abstracts(): HasMany
    {
        return $this->hasMany(Abstracts::class);
    }

    public function presentations(): HasMany
    {
        return $this->hasMany(Presentation::class);
    }

    public function slots(): HasMany
    {
        return $this->hasMany(Slot::class);
    }

    public function sessions(): HasMany
    {
        return $this->hasMany(Session::class);
    }

    /**
     * useRepository function
     *
     * @return EventRepository
     */
    public function useRepository(): EventRepository
    {
        return new EventRepository($this->id);
    }

    public function getRolesAttribute($roles)
    {
        return explode(',', $roles);
    }

    public function eventUrl($platform = 'admin'): string
    {
        return config('app.url') . '/' . $this->slug_name . '/' . $platform . '/';
    }

}