<?php
declare(strict_types = 1);

namespace App\Models;

use App\Casts\AmountCast;
use App\Enumerations\EatingHabit;
use App\Enumerations\ParticipationFeeType;
use App\RelationModels\EventParticipationFee;
use App\RelationModels\EventPaymentMethods;
use App\Scopes\InstancedModel;
use DateTime;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;

/**
 * @property string $tenant
 * @property int $cost_unit_id
 * @property string $name
 * @property string $location
 * @property string $postal_code
 * @property string $email
 * @property DateTime $start_date
 * @property DateTime $end_date
 * @property DateTime $early_bird_end
 * @property DateTime $registration_final_end
 * @property int $early_bird_end_amount_increase
 * @property int $registration_final_end_amount_increase
 * @property string $account_owner
 * @property string $account_iban
 * @property boolean $registration_allowed
 * @property string $participation_fee_type
 * @property float $total_max_amount
 * @property string $registration_link
 * @property boolean $pay_per_day
 * @property boolean $pay_direct
 * @property boolean $sibling_reduction
 * @property boolean $send_weekly_report
 * @property int $participation_fee_1
 * @property int $participation_fee_2
 * @property int $participation_fee_3
 * @property int $participation_fee_4
 * @property float $support_per_person
 * @property float $support_flat
 * @property int $alcoholics_age
 * @property boolean $archived
 */
class Event extends InstancedModel
{
    protected $table = 'events';

    protected $fillable = [
        'tenant',
        'cost_unit_id',
        'name',
        'identifier',
        'location',
        'postal_code',
        'email',
        'start_date',
        'end_date',
        'early_bird_end',
        'registration_final_end',
        'early_bird_end_amount_increase',
        'registration_final_end_amount_increase',
        'account_owner',
        'account_iban',
        'registration_allowed',
        'participation_fee_type',
        'total_max_amount',
        'registration_link',
        'pay_per_day',
        'pay_direct',
        'sibling_reduction',
        'send_weekly_report',
        'participation_fee_1',
        'participation_fee_2',
        'participation_fee_3',
        'participation_fee_4',
        'support_per_person',
        'support_flat',
        'alcoholics_age',
        'archived',
        'tax_liable',
        'vat_rate',
        'vat_pricing_mode',
        'tax_exemption_reason',
        'tax_exemption_note',
        'participation_options',
        'addons',

    ];

    protected $casts = [
        'start_date' => 'datetime',
        'end_date' => 'datetime',
        'early_bird_end' => 'datetime',
        'registration_final_end' => 'datetime',

        'early_bird_end_amount_increase' => 'integer',
        'registration_final_end_amount_increase' => 'integer',
        'alcoholics_age' => 'integer',

        'registration_allowed' => 'boolean',
        'pay_per_day' => 'boolean',
        'pay_direct' => 'boolean',
        'send_weekly_report' => 'boolean',
        'archived' => 'boolean',

        'support_per_person' => AmountCast::class,
        'support_flat' => AmountCast::class,
        'total_max_amount' => AmountCast::class,

        'sibling_reduction' => 'boolean',

        'tax_liable' => 'boolean',
        'vat_rate' => 'integer',

        'participation_options' => 'array',
        'addons' => 'array',
    ];

    public function tenant(): BelongsTo
    {
        return $this->belongsTo(Tenant::class, 'tenant', 'slug');
    }

    public function costUnit(): BelongsTo
    {
        return $this->belongsTo(CostUnit::class);
    }

    public function participationFeeType(): BelongsTo
    {
        return $this->belongsTo(ParticipationFeeType::class, 'participation_fee_type', 'slug');
    }

    public function participationFee1(): BelongsTo
    {
        return $this->belongsTo(EventParticipationFee::class, 'participation_fee_1');
    }

    public function participationFee2(): BelongsTo
    {
        return $this->belongsTo(EventParticipationFee::class, 'participation_fee_2');
    }

    public function participationFee3(): BelongsTo
    {
        return $this->belongsTo(EventParticipationFee::class, 'participation_fee_3');
    }

    public function participationFee4(): BelongsTo
    {
        return $this->belongsTo(EventParticipationFee::class, 'participation_fee_4');
    }

    public function localGroups()  : BelongsToMany{
        return $this->belongsToMany(Tenant::class, 'event_local_groups', 'event_id', 'local_group_id');
    }

    public function eatingHabits()  : BelongsToMany{
        return $this->belongsToMany(EatingHabit::class, 'event_allowed_eating_habits', 'event_id', 'eating_habit_id');
    }

    public function paymentMethods() : BelongsToMany {
        // Pivot verknüpft über den Slug (payment_methods.slug), nicht über die numerische id
        // von available_payment_methods -- die tenant-spezifische Instanz wird dadurch implizit
        // über den globalen SiteScope von AvailablePaymentMethod (gefiltert auf app('tenant')) aufgelöst.
        return $this->belongsToMany(AvailablePaymentMethod::class, 'event_payment_methods', 'event_id', 'slug', 'id', 'slug')
            ->using(EventPaymentMethods::class)
            ->withPivot('configuration')
            ->withTimestamps();
    }

    public function resetContributingLocalGroups() {
        $this->localGroups()->detach();
        $this->save();
    }

    public function resetAllowedEatingHabits() {
        $this->eatingHabits()->detach();
        $this->save();
    }

    public function resetPaymentMethods() {
        $this->paymentMethods()->detach();
        $this->save();
    }

    public function resetMangers() {
        $this->eventManagers()->detach();
        $this->save();
    }

    public function eventManagers() : BelongsToMany {
        return $this->belongsToMany(User::class, 'event_managers', 'event_id', 'user_id')
            ->withTimestamps();
    }

    public function participants() : HasMany {
        return $this->hasMany(EventParticipant::class);
    }

}
