<?php

namespace App\Models;

use App\Models\Subscription;
use App\Models\CalendarInstance;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;

class Calendar extends Model
{
    protected $table = 'calendars'; // Sabre table
    public $timestamps = false;     // no created_at/updated_at

    /* add mass-assignment for these cols */
    protected $fillable = [
        'synctoken',
        'components',
    ];

    /* all event components (VEVENT, VTODO, …) */
    public function events(): HasMany
    {
        return $this->hasMany(Event::class, 'calendarid'); // FK in calendarobjects
    }

    /* ui-specific metadata (color, sharing flags, json settings) */
    public function meta(): HasOne
    {
        return $this->hasOne(CalendarMeta::class, 'calendar_id');
    }

    /* get instances */
    public function instances()
    {
        return $this->hasMany(CalendarInstance::class, 'calendarid');
    }

    /* get the primary? instance for a user */
    public function instanceForUser(?User $user = null): CalendarInstance
    {
        $user = $user ?? auth()->user();

        return $this->instances()
            ->where('principaluri', $user->principal_uri)
            ->first();
    }

    /**
     *
     * build all calendar data for calendar display
     */
    public function scopeDashboardForPrincipal(Builder $q, string $principal): Builder
    {
        return $q->select(
                'calendars.id',
                'ci.displayname',
                'ci.calendarcolor',
                'ci.uri as slug',
                'ci.timezone as timezone',
                'meta.color as meta_color',
                'meta.color_fg as meta_color_fg',
                DB::raw('COALESCE(meta.is_remote, 0) as is_remote')
            )
            ->join('calendarinstances as ci', 'ci.calendarid', '=', 'calendars.id')
            ->leftJoin('calendar_meta as meta', 'meta.calendar_id', '=', 'calendars.id')
            ->where('ci.principaluri', $principal)
            ->orderBy('ci.displayname');
    }

    /**
     *
     * inbound urls
     * convert "/calendar/{slug}" into the correct calendar instance (uri column)
     *
     * @param  mixed  $value  The URI segment (instance UUID).
     * @param  string|null  $field  Ignored in our override.
     */
    public function resolveRouteBinding($value, $field = null): mixed
    {
        $user = Auth::user();

        return $this->newQuery()
            ->whereHas('instances', function (Builder $q) use ($value, $user) {
                $q->where('uri', $value)
                  ->where('principaluri', $user->principal_uri);
            })
            ->with(['instances' => function ($q) use ($user) {
                $q->where('principaluri', $user->principal_uri);
            }])
            ->firstOrFail();
    }
    /**
     * outbound urls
     */
    public function getRouteKey(): string
    {
        // use the per-user instance slug for URLs; fall back to id if not available
        $instance = $this->instances()
            ->where('principaluri', Auth::user()->principal_uri)
            ->first();

        return $instance->uri ?? (string) $this->getKey();
    }
}
