<?php

namespace App\Models\Tenants;

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

/**
 * 결재 단계 모델
 *
 * @property int $id
 * @property int $approval_id
 * @property int $step_order
 * @property string $step_type
 * @property int $approver_id
 * @property string $status
 * @property string|null $comment
 * @property \Carbon\Carbon|null $acted_at
 * @property bool $is_read
 * @property \Carbon\Carbon|null $read_at
 */
class ApprovalStep extends Model
{
    use Auditable;
    protected $table = 'approval_steps';

    protected $casts = [
        'step_order' => 'integer',
        'acted_at' => 'datetime',
        'is_read' => 'boolean',
        'read_at' => 'datetime',
    ];

    protected $fillable = [
        'approval_id',
        'step_order',
        'step_type',
        'approver_id',
        'status',
        'comment',
        'acted_at',
        'is_read',
        'read_at',
    ];

    protected $attributes = [
        'status' => 'pending',
        'is_read' => false,
    ];

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

    public const STATUS_PENDING = 'pending';     // 대기

    public const STATUS_APPROVED = 'approved';   // 승인

    public const STATUS_REJECTED = 'rejected';   // 반려

    public const STATUS_SKIPPED = 'skipped';     // 건너뜀

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

    // =========================================================================
    // 관계 정의
    // =========================================================================

    /**
     * 결재 문서
     */
    public function approval(): BelongsTo
    {
        return $this->belongsTo(Approval::class, 'approval_id');
    }

    /**
     * 결재자/참조자
     */
    public function approver(): BelongsTo
    {
        return $this->belongsTo(User::class, 'approver_id');
    }

    // =========================================================================
    // 스코프
    // =========================================================================

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

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

    /**
     * 특정 결재자
     */
    public function scopeByApprover($query, int $userId)
    {
        return $query->where('approver_id', $userId);
    }

    /**
     * 결재 단계만 (참조 제외)
     */
    public function scopeApprovalOnly($query)
    {
        return $query->whereIn('step_type', [ApprovalLine::STEP_TYPE_APPROVAL, ApprovalLine::STEP_TYPE_AGREEMENT]);
    }

    /**
     * 참조만
     */
    public function scopeReferenceOnly($query)
    {
        return $query->where('step_type', ApprovalLine::STEP_TYPE_REFERENCE);
    }

    // =========================================================================
    // 헬퍼 메서드
    // =========================================================================

    /**
     * 결재 가능 여부
     */
    public function isActionable(): bool
    {
        return $this->status === self::STATUS_PENDING
            && in_array($this->step_type, [ApprovalLine::STEP_TYPE_APPROVAL, ApprovalLine::STEP_TYPE_AGREEMENT]);
    }

    /**
     * 참조인지 확인
     */
    public function isReference(): bool
    {
        return $this->step_type === ApprovalLine::STEP_TYPE_REFERENCE;
    }

    /**
     * 상태 라벨
     */
    public function getStatusLabelAttribute(): string
    {
        return match ($this->status) {
            self::STATUS_PENDING => '대기',
            self::STATUS_APPROVED => '승인',
            self::STATUS_REJECTED => '반려',
            self::STATUS_SKIPPED => '건너뜀',
            default => $this->status,
        };
    }

    /**
     * 단계 유형 라벨
     */
    public function getStepTypeLabelAttribute(): string
    {
        return match ($this->step_type) {
            ApprovalLine::STEP_TYPE_APPROVAL => '결재',
            ApprovalLine::STEP_TYPE_AGREEMENT => '합의',
            ApprovalLine::STEP_TYPE_REFERENCE => '참조',
            default => $this->step_type,
        };
    }
}
