<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;

class Event extends Model
{
    /** table and key */
    protected $table      = 'calendarobjects'; // Sabre table
    protected $primaryKey = 'id';
    public    $timestamps = false;             // no created_at / updated_at

    /** mass assignment */
    protected $fillable = [
        'calendarid',
        'uid',
        'uri',
        'lastmodified',
        'etag',
        'size',
        'componenttype',
        'calendardata',
        'firstoccurence',
        'lastoccurence',
    ];

    /** column casting */
    protected $casts = [
        'lastmodified'   => 'integer',
        'firstoccurence' => 'integer',
        'lastoccurence'  => 'integer',
        'size'           => 'integer',
    ];

    /**
     * relationships
     **/
    public function calendar(): BelongsTo
    {
        return $this->belongsTo(Calendar::class, 'calendarid');
    }

    public function meta(): HasOne
    {
        return $this->hasOne(EventMeta::class, 'event_id');
    }

    public function attendees(): HasMany
    {
        return $this->hasMany(EventAttendee::class, 'event_id');
    }

    /**
     * scopes and helpers
     **/
    public function scopeInRange($query, $start, $end)
    {
        return $query->where(function ($q) use ($start, $end) {
            $q->whereHas('meta', function ($meta) use ($start, $end) {
                $meta->where(function ($range) use ($start, $end) {
                    $range->where('start_at', '<=', $end)
                          ->where(function ($bounds) use ($start) {
                              $bounds->where('end_at', '>=', $start)
                                     ->orWhereNull('end_at');
                          });
                })
                ->orWhereNotNull('extra->rrule');
            })
            ->orWhere(function ($ical) {
                $ical->where('calendardata', 'like', '%RRULE%')
                     ->orWhere('calendardata', 'like', '%RDATE%')
                     ->orWhere('calendardata', 'like', '%EXDATE%');
            });
        });
    }

    public static function forCalendarsInRange($calendarIds, $start, $end)
    {
        return static::query()
            ->with('meta')
            ->whereIn('calendarid', $calendarIds)
            ->inRange($start, $end)
            ->get();
    }
}
