<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Shipment extends Model
{
    protected $fillable = [
        'reference',
        'type',
        'origin',
        'destination',
        'vessel_or_flight',
        'departure_date',
        'eta',
        'ata',
        'status',
        'notes',
        'created_by',
    ];

    protected $casts = [
        'departure_date' => 'date',
        'eta'            => 'date',
        'ata'            => 'date',
    ];

    // ── Statuses ──────────────────────────────────────────────────

    /**
     * Statuses that are shared across all consignees in a shipment.
     * When a shipment moves to one of these, ALL consignments follow.
     */
    public const SHARED_STATUSES = [
        'received',
        'departed',
        'in_transit',
        'arrived',
        'customs_clearance',
    ];

    /**
     * Statuses that are individual per consignee.
     * These are NEVER overwritten by a shipment status update.
     * Staff sets these per-consignment when a client collects.
     */
    public const INDIVIDUAL_STATUSES = [
        'ready_for_pickup',
        'delivered',
    ];

    

    // ── Cascade logic ─────────────────────────────────────────────

    /**
     * Called after shipment status is updated.
     *
     * Only cascades SHARED statuses.
     * Consignments already at ready_for_pickup or delivered
     * are never touched — each person collects independently.
     */
    public function syncConsignmentStatuses(): void
    {
        // Only cascade if the new status is a shared/journey status
        if (! in_array($this->status, self::SHARED_STATUSES)) {
            return;
        }

        $this->consignments()
            // Skip consignments that are already at individual stages
            ->whereNotIn('status', self::INDIVIDUAL_STATUSES)
            // Skip consignments that staff manually overrode
            ->where('status_override', false)
            ->update(['status' => $this->status]);
    }

    /**
     * Mark ALL remaining consignments as ready_for_pickup.
     * Useful when a shipment arrives and staff wants to notify everyone.
     * Does NOT override consignments already marked delivered.
     */
    public function markAllReadyForPickup(): void
    {
        $this->consignments()
            ->where('status', '!=', 'delivered')
            ->update([
                'status'          => 'ready_for_pickup',
                'status_override' => true,
            ]);
    }

    // ── Relationships ─────────────────────────────────────────────

    public function consignments(): HasMany
    {
        return $this->hasMany(Consignment::class);
    }

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

    // ── Scopes ────────────────────────────────────────────────────

    public function scopeActive($query)
    {
        return $query->whereNotIn('status', ['delivered']);
    }

    public function scopeInTransit($query)
    {
        return $query->where('status', 'in_transit');
    }
}