<?php

namespace App\Models\Production;

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

/**
 * 작업실적 모델
 *
 * 생산 작업의 실적을 기록하고 추적하는 엔티티
 */
class WorkResult extends Model
{
    use Auditable, BelongsToTenant, ModelTrait, SoftDeletes;

    protected $table = 'work_results';

    protected $fillable = [
        'tenant_id',
        'work_order_id',
        'work_order_item_id',
        'lot_no',
        'work_date',
        'process_type',
        'product_name',
        'specification',
        'production_qty',
        'good_qty',
        'defect_qty',
        'defect_rate',
        'is_inspected',
        'is_packaged',
        'worker_id',
        'memo',
        'created_by',
        'updated_by',
    ];

    protected $casts = [
        'work_date' => 'date',
        'production_qty' => 'integer',
        'good_qty' => 'integer',
        'defect_qty' => 'integer',
        'defect_rate' => 'decimal:2',
        'is_inspected' => 'boolean',
        'is_packaged' => 'boolean',
    ];

    protected $hidden = [
        'deleted_at',
    ];

    // ──────────────────────────────────────────────────────────────
    // 상수
    // ──────────────────────────────────────────────────────────────

    /**
     * 공정 유형 (WorkOrder와 동일)
     */
    public const PROCESS_SCREEN = 'screen';

    public const PROCESS_SLAT = 'slat';

    public const PROCESS_BENDING = 'bending';

    public const PROCESS_TYPES = [
        self::PROCESS_SCREEN,
        self::PROCESS_SLAT,
        self::PROCESS_BENDING,
    ];

    // ──────────────────────────────────────────────────────────────
    // 관계
    // ──────────────────────────────────────────────────────────────

    /**
     * 작업지시
     */
    public function workOrder(): BelongsTo
    {
        return $this->belongsTo(WorkOrder::class);
    }

    /**
     * 작업지시 품목
     */
    public function workOrderItem(): BelongsTo
    {
        return $this->belongsTo(WorkOrderItem::class);
    }

    /**
     * 작업자
     */
    public function worker(): BelongsTo
    {
        return $this->belongsTo(User::class, 'worker_id');
    }

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

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

    // ──────────────────────────────────────────────────────────────
    // 스코프
    // ──────────────────────────────────────────────────────────────

    /**
     * 공정유형별 필터
     */
    public function scopeProcessType($query, string $type)
    {
        return $query->where('process_type', $type);
    }

    /**
     * 작업일 범위 필터
     */
    public function scopeWorkDateBetween($query, $from, $to)
    {
        return $query->whereBetween('work_date', [$from, $to]);
    }

    /**
     * 작업지시별 필터
     */
    public function scopeWorkOrder($query, int $workOrderId)
    {
        return $query->where('work_order_id', $workOrderId);
    }

    /**
     * 작업자별 필터
     */
    public function scopeWorker($query, int $workerId)
    {
        return $query->where('worker_id', $workerId);
    }

    /**
     * 검사 완료 필터
     */
    public function scopeInspected($query)
    {
        return $query->where('is_inspected', true);
    }

    /**
     * 포장 완료 필터
     */
    public function scopePackaged($query)
    {
        return $query->where('is_packaged', true);
    }

    /**
     * 불량 있음
     */
    public function scopeHasDefects($query)
    {
        return $query->where('defect_qty', '>', 0);
    }

    // ──────────────────────────────────────────────────────────────
    // 헬퍼 메서드
    // ──────────────────────────────────────────────────────────────

    /**
     * 불량률 계산
     */
    public function calculateDefectRate(): float
    {
        if ($this->production_qty <= 0) {
            return 0;
        }

        return round(($this->defect_qty / $this->production_qty) * 100, 2);
    }

    /**
     * 불량률 업데이트
     */
    public function updateDefectRate(): void
    {
        $this->defect_rate = $this->calculateDefectRate();
    }

    /**
     * 양품수량 자동 계산 및 설정
     */
    public function calculateGoodQty(): int
    {
        return max(0, $this->production_qty - $this->defect_qty);
    }

    /**
     * 불량이 있는지 확인
     */
    public function hasDefects(): bool
    {
        return $this->defect_qty > 0;
    }

    /**
     * 검사 및 포장 모두 완료인지 확인
     */
    public function isFullyProcessed(): bool
    {
        return $this->is_inspected && $this->is_packaged;
    }

    // ──────────────────────────────────────────────────────────────
    // 부팅
    // ──────────────────────────────────────────────────────────────

    protected static function boot()
    {
        parent::boot();

        // 저장 전 불량률 자동 계산
        static::saving(function (WorkResult $model) {
            $model->updateDefectRate();
        });
    }
}
