<?php

namespace App\Models\Approvals;

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

class ApprovalStep extends Model
{
    protected $table = 'approval_steps';

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

    protected $fillable = [
        'approval_id',
        'step_order',
        'step_type',
        'parallel_group',
        'approver_id',
        'acted_by',
        'approver_name',
        'approver_department',
        'approver_position',
        'status',
        'approval_type',
        '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 STATUS_ON_HOLD = 'on_hold';

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

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

    public function approval(): BelongsTo
    {
        return $this->belongsTo(Approval::class, 'approval_id');
    }

    public function approver(): BelongsTo
    {
        return $this->belongsTo(User::class, 'approver_id');
    }

    public function actedBy(): BelongsTo
    {
        return $this->belongsTo(User::class, 'acted_by');
    }

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

    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 => '건너뜀',
            self::STATUS_ON_HOLD => '보류',
            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,
        };
    }
}
