<?php

namespace Modules\SystemCore\App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Storage;

class CustomerDocument extends Model
{
    use SoftDeletes;

    protected $table = 'customer_documents';

    protected $fillable = [
        'customer_id',
        'document_title',
        'document_number',
        'document_type',
        'file_path',
        'file_name',
        'mime_type',
        'file_size',
        'issue_date',
        'expiry_date',
        'notes',
        'is_active',
    ];

    protected function casts(): array
    {
        return [
            'issue_date' => 'date',
            'expiry_date' => 'date',
            'is_active' => 'boolean',
            'file_size' => 'integer',
        ];
    }

    /**
     * Get the customer that owns the document.
     */
    public function customer(): BelongsTo
    {
        return $this->belongsTo(CoreCustomer::class, 'customer_id');
    }

    /**
     * Check if the document is expired.
     */
    public function isExpired(): bool
    {
        return $this->expiry_date && $this->expiry_date->isPast();
    }

    /**
     * Check if the document is about to expire.
     *
     * Since expiry_date is cast to 'date' (no time component), we compare
     * against today's date at midnight to avoid off-by-one errors.
     * We use absolute value since diffInDays returns negative for future dates.
     */
    public function isAboutToExpire(int $days = 30): bool
    {
        if (! $this->expiry_date || $this->expiry_date->isPast()) {
            return false;
        }

        return abs($this->expiry_date->diffInDays(now()->startOfDay())) <= $days;
    }

    /**
     * Get the file URL attribute.
     */
    public function getFileUrlAttribute(): ?string
    {
        if (! $this->file_path) {
            return null;
        }

        return Storage::disk('public')->url($this->file_path);
    }

    /**
     * Scope a query to only include documents that are expired.
     */
    public function scopeExpired($query)
    {
        return $query->whereNotNull('expiry_date')
            ->whereDate('expiry_date', '<', now());
    }

    /**
     * Scope a query to only include documents that are about to expire.
     */
    public function scopeAboutToExpire($query, int $days = 30)
    {
        $futureDate = now()->addDays($days);

        return $query->whereNotNull('expiry_date')
            ->whereDate('expiry_date', '>', now())
            ->whereDate('expiry_date', '<=', $futureDate);
    }

    /**
     * Scope a query to only include active documents.
     */
    public function scopeActive($query)
    {
        return $query->where('is_active', true);
    }

    /**
     * Scope a query to filter by document type.
     */
    public function scopeByType($query, string $type)
    {
        return $query->where('document_type', $type);
    }

    /**
     * Get formatted file size.
     */
    public function getFormattedFileSizeAttribute(): string
    {
        if (! $this->file_size) {
            return 'N/A';
        }

        $units = ['B', 'KB', 'MB', 'GB'];
        $size = $this->file_size;
        $unitIndex = 0;

        while ($size >= 1024 && $unitIndex < count($units) - 1) {
            $size /= 1024;
            $unitIndex++;
        }

        return round($size, 2).' '.$units[$unitIndex];
    }
}
