<?php

namespace App\Models\Documents;

use App\Models\Members\User;
use App\Traits\Auditable;
use App\Traits\BelongsToTenant;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\SoftDeletes;

/**
 * 문서 모델
 *
 * @property int $id
 * @property int $tenant_id
 * @property int $template_id
 * @property string $document_no 문서번호
 * @property string $title 문서 제목
 * @property string $status 상태 (DRAFT/PENDING/APPROVED/REJECTED/CANCELLED)
 * @property string|null $linkable_type 연결 모델 타입
 * @property int|null $linkable_id 연결 모델 ID
 * @property \Carbon\Carbon|null $submitted_at 결재 요청일
 * @property \Carbon\Carbon|null $completed_at 결재 완료일
 * @property int|null $created_by
 * @property int|null $updated_by
 * @property int|null $deleted_by
 * @property \Carbon\Carbon|null $created_at
 * @property \Carbon\Carbon|null $updated_at
 * @property \Carbon\Carbon|null $deleted_at
 */
class Document extends Model
{
    use Auditable, BelongsToTenant, SoftDeletes;

    protected $table = 'documents';

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

    public const STATUS_DRAFT = 'DRAFT';

    public const STATUS_PENDING = 'PENDING';

    public const STATUS_APPROVED = 'APPROVED';

    public const STATUS_REJECTED = 'REJECTED';

    public const STATUS_CANCELLED = 'CANCELLED';

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

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

    protected $fillable = [
        'tenant_id',
        'template_id',
        'document_no',
        'title',
        'status',
        'linkable_type',
        'linkable_id',
        'submitted_at',
        'completed_at',
        'created_by',
        'updated_by',
        'deleted_by',
    ];

    protected $casts = [
        'submitted_at' => 'datetime',
        'completed_at' => 'datetime',
    ];

    protected $attributes = [
        'status' => self::STATUS_DRAFT,
    ];

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

    /**
     * 템플릿
     */
    public function template(): BelongsTo
    {
        return $this->belongsTo(DocumentTemplate::class, 'template_id');
    }

    /**
     * 결재 목록
     */
    public function approvals(): HasMany
    {
        return $this->hasMany(DocumentApproval::class)->orderBy('step');
    }

    /**
     * 문서 데이터
     */
    public function data(): HasMany
    {
        return $this->hasMany(DocumentData::class);
    }

    /**
     * 첨부파일
     */
    public function attachments(): HasMany
    {
        return $this->hasMany(DocumentAttachment::class);
    }

    /**
     * 연결된 엔티티 (다형성)
     */
    public function linkable(): MorphTo
    {
        return $this->morphTo();
    }

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

    /**
     * 수정자
     */
    public function updater(): BelongsTo
    {
        return $this->belongsTo(User::class, 'updated_by');
    }

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

    /**
     * 상태로 필터링
     */
    public function scopeStatus($query, string $status)
    {
        return $query->where('status', $status);
    }

    /**
     * 임시저장 문서
     */
    public function scopeDraft($query)
    {
        return $query->where('status', self::STATUS_DRAFT);
    }

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

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

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

    /**
     * 편집 가능 여부
     */
    public function canEdit(): bool
    {
        return $this->status === self::STATUS_DRAFT
            || $this->status === self::STATUS_REJECTED;
    }

    /**
     * 결재 요청 가능 여부
     */
    public function canSubmit(): bool
    {
        return $this->status === self::STATUS_DRAFT
            || $this->status === self::STATUS_REJECTED;
    }

    /**
     * 결재 처리 가능 여부
     */
    public function canApprove(): bool
    {
        return $this->status === self::STATUS_PENDING;
    }

    /**
     * 취소 가능 여부
     */
    public function canCancel(): bool
    {
        return in_array($this->status, [
            self::STATUS_DRAFT,
            self::STATUS_PENDING,
        ]);
    }

    /**
     * 현재 결재 단계 가져오기
     */
    public function getCurrentApprovalStep(): ?DocumentApproval
    {
        return $this->approvals()
            ->where('status', DocumentApproval::STATUS_PENDING)
            ->orderBy('step')
            ->first();
    }

    /**
     * 특정 사용자의 결재 차례 확인
     */
    public function isUserTurn(int $userId): bool
    {
        $currentStep = $this->getCurrentApprovalStep();

        return $currentStep && $currentStep->user_id === $userId;
    }
}
