<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;

class CheckoutSession extends Model
{
    use HasFactory;
    use HasUuids;
    use SoftDeletes;

    public const STATUS_DRAFT = 'draft';

    public const STATUS_AWAITING_METHOD = 'awaiting_payment_method';

    public const STATUS_REQUIRES_CUSTOMER_ACTION = 'requires_customer_action';

    public const STATUS_PROCESSING = 'processing';

    public const STATUS_COMPLETED = 'completed';

    public const STATUS_FAILED = 'failed';

    public const STATUS_CANCELLED = 'cancelled';

    public const PROVIDER_NONE = 'none';

    public const PROVIDER_PADDLE = 'paddle';

    public const PROVIDER_FREE = 'free';

    /**
     * The attributes that aren't mass assignable.
     */
    protected $guarded = [];

    /**
     * Indicates if the IDs are auto-incrementing.
     */
    public $incrementing = false;

    /**
     * The data type of the primary key.
     */
    protected $keyType = 'string';

    /**
     * The attributes that should be cast.
     */
    protected $casts = [
        'package_snapshot' => 'array',
        'status_history' => 'array',
        'provider_metadata' => 'array',
        'coupon_snapshot' => 'array',
        'discount_breakdown' => 'array',
        'expires_at' => 'datetime',
        'completed_at' => 'datetime',
        'accepted_terms_at' => 'datetime',
        'accepted_privacy_at' => 'datetime',
        'accepted_withdrawal_notice_at' => 'datetime',
        'digital_content_waiver_at' => 'datetime',
        'amount_subtotal' => 'decimal:2',
        'amount_total' => 'decimal:2',
        'amount_discount' => 'decimal:2',
    ];

    /**
     * Default attributes.
     */
    protected $attributes = [
        'status_history' => '[]',
        'package_snapshot' => '[]',
        'provider_metadata' => '[]',
        'coupon_snapshot' => '[]',
        'discount_breakdown' => '[]',
    ];

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

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

    public function package(): BelongsTo
    {
        return $this->belongsTo(Package::class)->withTrashed();
    }

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

    public function scopeActive($query)
    {
        return $query->whereNotIn('status', [
            self::STATUS_COMPLETED,
            self::STATUS_CANCELLED,
        ])->where(function ($inner) {
            $inner->whereNull('expires_at')->orWhere('expires_at', '>', now());
        });
    }

    public function scopeByProviderId($query, string $providerField, string $value)
    {
        return $query->where($providerField, $value);
    }

    public function isExpired(): bool
    {
        return (bool) $this->expires_at && $this->expires_at->isPast();
    }

    public function requiresCustomerAction(): bool
    {
        return $this->status === self::STATUS_REQUIRES_CUSTOMER_ACTION;
    }
}
