<?php

namespace App\Models;

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

class QcApproval extends Model
{
    use SoftDeletes, HasAuditFields;

    protected $table = 'qc_approvals';

    /**
     * Status constants
     */
    public const STATUS_PENDING = 'pending';
    public const STATUS_APPROVED = 'approved';
    public const STATUS_REJECTED = 'rejected';

    /**
     * Stage constants (QC workflow stages)
     */
    public const STAGE_BEFORE = 'before';
    public const STAGE_DURING = 'during';
    public const STAGE_AFTER = 'after';

    /**
     * Approval level constants
     */
    public const LEVEL_OPERATOR = 1;
    public const LEVEL_SUPERVISOR = 2;
    public const LEVEL_MANAGER = 3;

    protected $fillable = [
        'process_id',
        'level',
        'status',
        'approved_by',
        'approved_at',
        'remarks',
        'stage',
        'parameters',
        'rejection_reason',
        'created_by',
        'updated_by',
    ];

    protected $casts = [
        'parameters' => 'array',
        'approved_at' => 'datetime',
        'level' => 'integer',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
    ];

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

    /**
     * Get the process this approval belongs to.
     */
    public function process()
    {
        return $this->belongsTo(RouteCardProcess::class, 'process_id');
    }

    /**
     * Get the route card through process.
     */
    public function routeCard()
    {
        return $this->hasOneThrough(
            RouteCard::class,
            RouteCardProcess::class,
            'id',
            'id',
            'process_id',
            'route_card_id'
        );
    }

    /**
     * Get the user who approved this QC.
     */
    public function approver()
    {
        return $this->belongsTo(User::class, 'approved_by');
    }

    /**
     * Get the user who created this approval request.
     */
    public function creator()
    {
        return $this->belongsTo(User::class, 'created_by');
    }

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

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

    /**
     * Filter by approved status
     */
    public function scopeApproved(Builder $query): Builder
    {
        return $query->where('status', self::STATUS_APPROVED);
    }

    /**
     * Filter by rejected status
     */
    public function scopeRejected(Builder $query): Builder
    {
        return $query->where('status', self::STATUS_REJECTED);
    }

    /**
     * Filter by before stage
     */
    public function scopeStageBefore(Builder $query): Builder
    {
        return $query->where('stage', self::STAGE_BEFORE);
    }

    /**
     * Filter by during stage
     */
    public function scopeStageDuring(Builder $query): Builder
    {
        return $query->where('stage', self::STAGE_DURING);
    }

    /**
     * Filter by after stage
     */
    public function scopeStageAfter(Builder $query): Builder
    {
        return $query->where('stage', self::STAGE_AFTER);
    }

    /**
     * Filter by process
     */
    public function scopeForProcess(Builder $query, int $processId): Builder
    {
        return $query->where('process_id', $processId);
    }

    /**
     * Filter by approval level
     */
    public function scopeForLevel(Builder $query, int $level): Builder
    {
        return $query->where('level', $level);
    }

    /**
     * Filter awaiting action (pending)
     */
    public function scopeAwaitingAction(Builder $query): Builder
    {
        return $query->where('status', self::STATUS_PENDING)
                     ->orderBy('created_at', 'asc');
    }

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

    /**
     * Get all valid statuses
     */
    public static function getStatuses(): array
    {
        return [
            self::STATUS_PENDING,
            self::STATUS_APPROVED,
            self::STATUS_REJECTED,
        ];
    }

    /**
     * Get all valid stages
     */
    public static function getStages(): array
    {
        return [
            self::STAGE_BEFORE,
            self::STAGE_DURING,
            self::STAGE_AFTER,
        ];
    }

    /**
     * Get all approval levels
     */
    public static function getLevels(): array
    {
        return [
            self::LEVEL_OPERATOR => 'Operator',
            self::LEVEL_SUPERVISOR => 'Supervisor',
            self::LEVEL_MANAGER => 'Manager',
        ];
    }

    /**
     * Check if approval is pending
     */
    public function isPending(): bool
    {
        return $this->status === self::STATUS_PENDING;
    }

    /**
     * Check if approval is approved
     */
    public function isApproved(): bool
    {
        return $this->status === self::STATUS_APPROVED;
    }

    /**
     * Check if approval is rejected
     */
    public function isRejected(): bool
    {
        return $this->status === self::STATUS_REJECTED;
    }

    /**
     * Check if this is before-production QC
     */
    public function isBeforeStage(): bool
    {
        return $this->stage === self::STAGE_BEFORE;
    }

    /**
     * Check if this is during-production QC
     */
    public function isDuringStage(): bool
    {
        return $this->stage === self::STAGE_DURING;
    }

    /**
     * Check if this is after-production QC
     */
    public function isAfterStage(): bool
    {
        return $this->stage === self::STAGE_AFTER;
    }

    /**
     * Approve this QC
     */
    public function approve(int $userId, ?string $remarks = null): bool
    {
        $this->status = self::STATUS_APPROVED;
        $this->approved_by = $userId;
        $this->approved_at = now();
        if ($remarks) {
            $this->remarks = $remarks;
        }
        return $this->save();
    }

    /**
     * Reject this QC
     */
    public function reject(int $userId, string $reason, ?string $remarks = null): bool
    {
        $this->status = self::STATUS_REJECTED;
        $this->approved_by = $userId;
        $this->approved_at = now();
        $this->rejection_reason = $reason;
        if ($remarks) {
            $this->remarks = $remarks;
        }
        return $this->save();
    }

    /**
     * Get stage display name
     */
    public function getStageName(): string
    {
        return match($this->stage) {
            self::STAGE_BEFORE => 'Before Production',
            self::STAGE_DURING => 'During Production',
            self::STAGE_AFTER => 'After Production',
            default => ucfirst($this->stage ?? 'Unknown'),
        };
    }

    /**
     * Get level display name
     */
    public function getLevelName(): string
    {
        return self::getLevels()[$this->level] ?? "Level {$this->level}";
    }
}
