<?php

namespace App\Models;

use App\Models\Traits\HasAuditFields;
use App\Models\Traits\HasScopes;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class RouteCardProcess extends Model
{
    use HasFactory, HasScopes, SoftDeletes, HasAuditFields;

    protected $table = 'route_card_processes';

    /**
     * Status constants
     */
    public const STATUS_PENDING = 'pending';
    public const STATUS_QC_BEFORE = 'qc_before';
    public const STATUS_IN_PROGRESS = 'in_progress';
    public const STATUS_QC_DURING = 'qc_during';
    public const STATUS_QC_AFTER = 'qc_after';
    public const STATUS_COMPLETED = 'completed';
    public const STATUS_ON_HOLD = 'on_hold';

    /**
     * Custom column mapping for HasScopes trait
     */
    protected string $dateColumn = 'start_date';

    protected $fillable = [
        'route_card_id',
        'process',
        'machine',
        'operator',
        'cycle_hours',
        'cycle_minutes',
        'source',
        'description',
        'start_date',
        'end_date',
        'previous_process_id',
        'status',
        'created_by',
        'updated_by',
    ];

    protected $casts = [
        'start_date' => 'datetime',
        'end_date' => 'datetime',
        'cycle_hours' => 'integer',
        'cycle_minutes' => 'integer',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
    ];

    // ──────────────────────────────────────────────────────────────────────────
    // RELATIONSHIPS
    // ──────────────────────────────────────────────────────────────────────────

    /**
     * Previous process in sequence
     */
    public function previousProcess()
    {
        return $this->belongsTo(RouteCardProcess::class, 'previous_process_id');
    }

    /**
     * Next process in sequence
     */
    public function nextProcess()
    {
        return $this->hasOne(RouteCardProcess::class, 'previous_process_id');
    }

    /**
     * Machine assigned to this process
     */
    public function attachedMachine()
    {
        return $this->belongsTo(Machines::class, 'machine', 'id');
    }

    /**
     * Alias for attachedMachine - used in eager loading
     */
    public function machine()
    {
        return $this->belongsTo(Machines::class, 'machine_id');
    }

    /**
     * @deprecated Use attachedMachine() instead
     */
    public function attchedMachine()
    {
        return $this->attachedMachine();
    }

    /**
     * Process master definition
     */
    public function attachedProcess()
    {
        return $this->belongsTo(Process::class, 'process', 'name');
    }

    /**
     * Alias for attachedProcess - used in eager loading
     */
    public function process()
    {
        return $this->belongsTo(Process::class, 'process_id');
    }

    /**
     * @deprecated Use attachedProcess() instead
     */
    public function attchedProcess()
    {
        return $this->attachedProcess();
    }

    /**
     * Operator assigned to this process
     */
    public function attachedOperator()
    {
        return $this->belongsTo(EmployeeDetails::class, 'operator', 'id');
    }

    /**
     * @deprecated Use attachedOperator() instead
     */
    public function attchedOperator()
    {
        return $this->attachedOperator();
    }

    /**
     * Parent route card
     */
    public function routeCard()
    {
        return $this->belongsTo(RouteCard::class, 'route_card_id');
    }

    /**
     * QC approvals for this process
     */
    public function qcApprovals()
    {
        return $this->hasMany(QcApproval::class, 'process_id');
    }

    /**
     * Alias for operator relationship
     */
    public function operatorUser()
    {
        return $this->belongsTo(EmployeeDetails::class, 'operator');
    }

    // ──────────────────────────────────────────────────────────────────────────
    // SCOPES
    // ──────────────────────────────────────────────────────────────────────────

    /**
     * Filter pending processes
     */
    public function scopePending(Builder $query): Builder
    {
        return $query->where('status', self::STATUS_PENDING);
    }

    /**
     * Filter in progress processes
     */
    public function scopeInProgress(Builder $query): Builder
    {
        return $query->where('status', self::STATUS_IN_PROGRESS);
    }

    /**
     * Filter completed processes
     */
    public function scopeCompleted(Builder $query): Builder
    {
        return $query->where('status', self::STATUS_COMPLETED);
    }

    /**
     * Filter processes awaiting QC
     */
    public function scopeAwaitingQc(Builder $query): Builder
    {
        return $query->whereIn('status', [
            self::STATUS_QC_BEFORE,
            self::STATUS_QC_DURING,
            self::STATUS_QC_AFTER,
        ]);
    }

    /**
     * Filter by machine
     */
    public function scopeForMachine(Builder $query, int $machineId): Builder
    {
        return $query->where('machine', $machineId);
    }

    /**
     * Filter by operator
     */
    public function scopeForOperator(Builder $query, int $operatorId): Builder
    {
        return $query->where('operator', $operatorId);
    }

    /**
     * Filter processes starting today
     */
    public function scopeStartingToday(Builder $query): Builder
    {
        return $query->whereDate('start_date', today());
    }

    /**
     * Filter overdue processes
     */
    public function scopeOverdue(Builder $query): Builder
    {
        return $query->where('end_date', '<', now())
                     ->where('status', '!=', self::STATUS_COMPLETED);
    }

    // ──────────────────────────────────────────────────────────────────────────
    // ACCESSORS & HELPERS
    // ──────────────────────────────────────────────────────────────────────────

    /**
     * Get all valid statuses
     */
    public static function getStatuses(): array
    {
        return [
            self::STATUS_PENDING,
            self::STATUS_QC_BEFORE,
            self::STATUS_IN_PROGRESS,
            self::STATUS_QC_DURING,
            self::STATUS_QC_AFTER,
            self::STATUS_COMPLETED,
            self::STATUS_ON_HOLD,
        ];
    }

    /**
     * Check if process is completed
     */
    public function isCompleted(): bool
    {
        return $this->status === self::STATUS_COMPLETED;
    }

    /**
     * Check if process is in QC stage
     */
    public function isInQcStage(): bool
    {
        return in_array($this->status, [
            self::STATUS_QC_BEFORE,
            self::STATUS_QC_DURING,
            self::STATUS_QC_AFTER,
        ]);
    }

    /**
     * Check if process can start
     */
    public function canStart(): bool
    {
        // Check if previous process is completed (if exists)
        if ($this->previous_process_id) {
            $previous = $this->previousProcess;
            if ($previous && !$previous->isCompleted()) {
                return false;
            }
        }

        return $this->status === self::STATUS_PENDING;
    }

    /**
     * Get total cycle time in minutes
     */
    public function getCycleTimeInMinutes(): int
    {
        return ($this->cycle_hours * 60) + $this->cycle_minutes;
    }

    /**
     * Get formatted cycle time
     */
    public function getFormattedCycleTime(): string
    {
        $hours = $this->cycle_hours ?? 0;
        $minutes = $this->cycle_minutes ?? 0;

        if ($hours > 0) {
            return "{$hours}h {$minutes}m";
        }

        return "{$minutes}m";
    }

    /**
     * Get QC approval for a specific stage
     */
    public function getQcApproval(string $stage)
    {
        return $this->qcApprovals()->where('stage', $stage)->first();
    }

    /**
     * Check if QC is approved for a stage
     */
    public function isQcApproved(string $stage): bool
    {
        $approval = $this->getQcApproval($stage);
        return $approval && $approval->status === 'approved';
    }

    /**
     * Check if process is overdue
     */
    public function isOverdue(): bool
    {
        return $this->end_date && $this->end_date->isPast() && !$this->isCompleted();
    }
}
