<?php

namespace App\Models;

use App\Enums\ServiceType;
use App\Enums\SubscriptionStatus;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Str;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Traits\LogsActivity;

class Subscription extends Model
{
    use HasFactory, SoftDeletes, LogsActivity;

    protected $fillable = [
        'reference_no', 'dealer_id', 'company_id', 'package_id',
        'customer_name', 'tc_no', 'id_document_path', 'phone', 'email', 'address',
        'il', 'ilce', 'service_type', 'contract_months', 'total_price', 'notes', 'status', 'cancel_reason',
        'approved_at', 'completed_at', 'cancelled_at', 'created_by', 'updated_by',
    ];

    protected function casts(): array
    {
        return [
            'service_type' => ServiceType::class,
            'status' => SubscriptionStatus::class,
            'contract_months' => 'integer',
            'total_price' => 'decimal:2',
            'approved_at' => 'datetime',
            'completed_at' => 'datetime',
            'cancelled_at' => 'datetime',
        ];
    }

    protected static function booted(): void
    {
        static::creating(function (Subscription $subscription) {
            if (empty($subscription->reference_no)) {
                $subscription->reference_no = 'SUB-'.now()->format('Y').'-'.str_pad(
                    (string) (static::withTrashed()->max('id') + 1),
                    6,
                    '0',
                    STR_PAD_LEFT
                );
            }

            // Toplam satis tutari: aylik ucret x kac aylik sozlesme yapildigi.
            // Anlik goruntu (snapshot) olarak saklanir, paket fiyati sonradan degisse bile bu abonelik icin sabit kalir.
            if (empty($subscription->total_price) && $subscription->package_id) {
                $monthlyFee = (float) (Package::find($subscription->package_id)?->monthly_fee ?? 0);
                $subscription->total_price = round($monthlyFee * max(1, (int) $subscription->contract_months), 2);
            }
        });

        static::updating(function (Subscription $subscription) {
            // Aylik ucret veya sozlesme suresi degistiyse toplam tutari yeniden hesapla.
            if ($subscription->isDirty(['package_id', 'contract_months'])) {
                $monthlyFee = (float) ($subscription->package?->monthly_fee ?? 0);
                $subscription->total_price = round($monthlyFee * max(1, (int) $subscription->contract_months), 2);
            }
        });
    }

    public function getActivitylogOptions(): LogOptions
    {
        return LogOptions::defaults()
            ->logOnly(['status', 'dealer_id', 'package_id'])
            ->logOnlyDirty()
            ->useLogName('subscriptions');
    }

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

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

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

    public function creator(): BelongsTo
    {
        return $this->belongsTo(User::class, 'created_by');
    }

    public function updater(): BelongsTo
    {
        return $this->belongsTo(User::class, 'updated_by');
    }

    public function earning(): HasOne
    {
        return $this->hasOne(Earning::class);
    }

    public function application(): HasOne
    {
        return $this->hasOne(Application::class);
    }

    public function scopeStatus($query, string|SubscriptionStatus $status)
    {
        return $query->where('status', $status instanceof SubscriptionStatus ? $status->value : $status);
    }
}
