<?php

namespace App\Models\Documents;

use App\Models\Members\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

/**
 * 문서 결재 모델
 *
 * @property int $id
 * @property int $document_id
 * @property int $user_id
 * @property int $step 결재 순서
 * @property string $role 역할 (작성/검토/승인)
 * @property string $status 상태 (PENDING/APPROVED/REJECTED)
 * @property string|null $comment 결재 의견
 * @property \Carbon\Carbon|null $acted_at 결재 처리일
 * @property int|null $created_by
 * @property int|null $updated_by
 * @property \Carbon\Carbon|null $created_at
 * @property \Carbon\Carbon|null $updated_at
 */
class DocumentApproval extends Model
{
    protected $table = 'document_approvals';

    // =========================================================================
    // 상태 상수
    // =========================================================================

    public const STATUS_PENDING = 'PENDING';

    public const STATUS_APPROVED = 'APPROVED';

    public const STATUS_REJECTED = 'REJECTED';

    public const STATUSES = [
        self::STATUS_PENDING,
        self::STATUS_APPROVED,
        self::STATUS_REJECTED,
    ];

    // =========================================================================
    // 역할 상수
    // =========================================================================

    public const ROLE_WRITER = '작성';

    public const ROLE_REVIEWER = '검토';

    public const ROLE_APPROVER = '승인';

    // =========================================================================
    // Fillable & Casts
    // =========================================================================

    protected $fillable = [
        'document_id',
        'user_id',
        'step',
        'role',
        'status',
        'comment',
        'acted_at',
        'created_by',
        'updated_by',
    ];

    protected $casts = [
        'step' => 'integer',
        'acted_at' => 'datetime',
    ];

    protected $attributes = [
        'step' => 1,
        'status' => self::STATUS_PENDING,
    ];

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

    /**
     * 문서
     */
    public function document(): BelongsTo
    {
        return $this->belongsTo(Document::class);
    }

    /**
     * 결재자
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

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

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

    /**
     * 대기 중인 결재
     */
    public function scopePending($query)
    {
        return $query->where('status', self::STATUS_PENDING);
    }

    /**
     * 승인된 결재
     */
    public function scopeApproved($query)
    {
        return $query->where('status', self::STATUS_APPROVED);
    }

    /**
     * 반려된 결재
     */
    public function scopeRejected($query)
    {
        return $query->where('status', self::STATUS_REJECTED);
    }

    /**
     * 특정 사용자의 결재
     */
    public function scopeForUser($query, int $userId)
    {
        return $query->where('user_id', $userId);
    }

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

    /**
     * 대기 상태 여부
     */
    public function isPending(): bool
    {
        return $this->status === self::STATUS_PENDING;
    }

    /**
     * 승인 상태 여부
     */
    public function isApproved(): bool
    {
        return $this->status === self::STATUS_APPROVED;
    }

    /**
     * 반려 상태 여부
     */
    public function isRejected(): bool
    {
        return $this->status === self::STATUS_REJECTED;
    }

    /**
     * 결재 처리 완료 여부
     */
    public function isProcessed(): bool
    {
        return ! $this->isPending();
    }
}
