<?php

namespace App\Models;

use App\Models\Commons\File;
use App\Models\Tenants\Tenant;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class FileShareLink extends Model
{
    use \App\Traits\BelongsToTenant;

    public $timestamps = false; // created_at만 사용

    protected $fillable = [
        'file_id',
        'tenant_id',
        'token',
        'expires_at',
        'download_count',
        'max_downloads',
        'last_downloaded_at',
        'last_downloaded_ip',
        'created_by',
        'created_at',
    ];

    protected $casts = [
        'expires_at' => 'datetime',
        'last_downloaded_at' => 'datetime',
        'created_at' => 'datetime',
        'download_count' => 'integer',
        'max_downloads' => 'integer',
    ];

    /**
     * Boot method: Auto-generate token
     */
    protected static function boot()
    {
        parent::boot();

        static::creating(function ($model) {
            if (empty($model->token)) {
                $model->token = self::generateToken();
            }
        });
    }

    /**
     * Generate a unique 64-character token
     */
    public static function generateToken(): string
    {
        return bin2hex(random_bytes(32)); // 64 chars
    }

    /**
     * Get the file associated with this share link
     */
    public function file(): BelongsTo
    {
        return $this->belongsTo(File::class);
    }

    /**
     * Get the tenant that owns the share link
     */
    public function tenant(): BelongsTo
    {
        return $this->belongsTo(Tenant::class);
    }

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

    /**
     * Check if download limit reached
     */
    public function isDownloadLimitReached(): bool
    {
        return $this->max_downloads && $this->download_count >= $this->max_downloads;
    }

    /**
     * Check if the link is still valid
     */
    public function isValid(): bool
    {
        return ! $this->isExpired() && ! $this->isDownloadLimitReached();
    }

    /**
     * Increment download count
     */
    public function incrementDownloadCount(string $ip): void
    {
        $this->increment('download_count');
        $this->update([
            'last_downloaded_at' => now(),
            'last_downloaded_ip' => $ip,
        ]);
    }

    /**
     * Scope: Non-expired links
     */
    public function scopeValid($query)
    {
        return $query->where('expires_at', '>', now())
            ->where(function ($q) {
                $q->whereNull('max_downloads')
                    ->orWhereRaw('download_count < max_downloads');
            });
    }
}
