<?php

namespace App\Models\Boards;

use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Storage;

/**
 * 파일 모델 (Polymorphic)
 *
 * @property int $id
 * @property int|null $tenant_id
 * @property int|null $folder_id
 * @property bool $is_temp
 * @property string $file_path
 * @property string|null $display_name
 * @property string|null $stored_name
 * @property string|null $original_name
 * @property int $file_size
 * @property string|null $mime_type
 * @property string|null $file_type
 * @property int|null $fileable_id
 * @property string|null $fileable_type
 * @property int|null $uploaded_by
 */
class File extends Model
{
    use SoftDeletes;

    protected $table = 'files';

    protected $fillable = [
        'tenant_id',
        'folder_id',
        'is_temp',
        'file_path',
        'display_name',
        'stored_name',
        'original_name',
        'file_name',
        'file_size',
        'mime_type',
        'file_type',
        // New fields (API 방식)
        'document_id',
        'document_type',
        // Legacy fields (하위 호환)
        'fileable_id',
        'fileable_type',
        'description',
        'uploaded_by',
        'deleted_by',
        'created_by',
        'updated_by',
        // GCS fields
        'gcs_object_name',
        'gcs_uri',
    ];

    protected $casts = [
        'is_temp' => 'boolean',
        'file_size' => 'integer',
    ];

    // =========================================================================
    // Relationships
    // =========================================================================

    /**
     * Polymorphic 관계 - 연결된 모델 (Post, Product 등)
     */
    public function fileable(): MorphTo
    {
        return $this->morphTo();
    }

    /**
     * 업로더
     */
    public function uploader(): BelongsTo
    {
        return $this->belongsTo(User::class, 'uploaded_by');
    }

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

    // =========================================================================
    // Helper Methods
    // =========================================================================

    /**
     * 스토리지 전체 경로
     */
    public function getStoragePath(): string
    {
        return Storage::disk('tenant')->path($this->file_path);
    }

    /**
     * 파일 존재 여부
     */
    public function existsInStorage(): bool
    {
        return Storage::disk('tenant')->exists($this->file_path);
    }

    /**
     * 다운로드 응답
     */
    public function download()
    {
        if (! $this->existsInStorage()) {
            abort(404, '파일을 찾을 수 없습니다.');
        }

        $fileName = $this->display_name ?? $this->original_name ?? $this->file_name;

        return response()->download($this->getStoragePath(), $fileName);
    }

    /**
     * 파일 URL (public 접근용)
     */
    public function getUrl(): ?string
    {
        if (! $this->existsInStorage()) {
            return null;
        }

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

    /**
     * 파일 크기 포맷팅
     */
    public function getFormattedSize(): string
    {
        $bytes = $this->file_size;

        if ($bytes >= 1073741824) {
            return number_format($bytes / 1073741824, 2).' GB';
        } elseif ($bytes >= 1048576) {
            return number_format($bytes / 1048576, 2).' MB';
        } elseif ($bytes >= 1024) {
            return number_format($bytes / 1024, 2).' KB';
        }

        return $bytes.' bytes';
    }

    /**
     * 파일 확장자
     */
    public function getExtension(): string
    {
        $fileName = $this->stored_name ?? $this->file_name ?? $this->original_name;

        return pathinfo($fileName, PATHINFO_EXTENSION);
    }

    /**
     * 이미지 여부
     */
    public function isImage(): bool
    {
        return str_starts_with($this->mime_type ?? '', 'image/');
    }

    /**
     * Soft Delete with user tracking
     */
    public function softDeleteFile(int $userId): void
    {
        $this->deleted_by = $userId;
        $this->save();
        $this->delete();
    }

    /**
     * 완전 삭제 (물리 파일 포함)
     */
    public function permanentDelete(): void
    {
        if ($this->existsInStorage()) {
            Storage::disk('tenant')->delete($this->file_path);
        }

        $this->forceDelete();
    }

    // =========================================================================
    // Scopes
    // =========================================================================

    /**
     * 특정 모델의 파일들
     */
    public function scopeForModel($query, string $type, int $id)
    {
        return $query->where('fileable_type', $type)
            ->where('fileable_id', $id);
    }

    /**
     * 임시 파일만
     */
    public function scopeTemp($query)
    {
        return $query->where('is_temp', true);
    }

    /**
     * 임시 파일 제외
     */
    public function scopeNonTemp($query)
    {
        return $query->where('is_temp', false);
    }

    /**
     * 특정 문서의 파일들
     */
    public function scopeForDocument($query, int $documentId, string $documentType)
    {
        return $query->where('document_id', $documentId)
            ->where('document_type', $documentType);
    }
}
