<?php

namespace App\Models\Warehouse;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class IncomingOperationItem extends Model
{
    use HasFactory;

    protected $fillable = [
        'incoming_operation_id',
        'item_id',
        'outgoing_item_id', // For site returns - links to the original outgoing item
        'direct_delivery_item_id', // For direct delivery returns - links to the original direct delivery item
        'material_transfer_item_id', // For material transfer returns - links to the original material transfer item
        'supplier_delivery_item_id', // For supplier delivery returns - links to the original supplier delivery item
        'outgoing_fulfillment_id', // For FOC returns - links to the original outgoing fulfillment
        'site_transfer_allocation_id', // For site transfer returns - links to specific allocation for division/FOC tracking

        // Quantity Information
        'quantity_ordered',
        'quantity_delivered',
        'quantity_accepted',
        'quantity_rejected',
        'unit_of_measure',

        // Pricing in original currency
        'unit_price',
        'total_price',
        'currency',

        // Pricing in AED (base currency)
        'unit_price_aed',
        'total_price_aed',

        // Quality & Batch Information
        'batch_number',
        'serial_number',
        'production_date',
        'expiry_date',
        'manufacturer',
        'country_of_origin',

        // Quality Control
        'quality_status',
        'quality_notes',
        'quality_checklist',
        'rejection_reason',

        // Storage & Location
        'storage_location',
        'storage_conditions',
        'hazardous_material',
        'hazard_classifications',

        // Warranty & Maintenance
        'warranty_period_months',
        'warranty_expiry',
        'requires_maintenance',
        'maintenance_interval_days',

        // Project Allocation
        'allocated_project_id',
        'project_phase',
        'work_area'
    ];

    protected $casts = [
        'quantity_ordered' => 'decimal:2',
        'quantity_delivered' => 'decimal:2',
        'quantity_accepted' => 'decimal:2',
        'quantity_rejected' => 'decimal:2',
        'unit_price' => 'decimal:2',
        'total_price' => 'decimal:2',
        'unit_price_aed' => 'decimal:2',
        'total_price_aed' => 'decimal:2',
        'production_date' => 'date',
        'manufacturing_date' => 'date',
        'expiry_date' => 'date',
        'warranty_expiry' => 'date',
        'hazardous_material' => 'boolean',
        'requires_maintenance' => 'boolean',
        'quality_checklist' => 'array',
        'hazard_classifications' => 'array',
        'created_at' => 'datetime',
        'updated_at' => 'datetime'
    ];

    /**
     * Boot the model
     */
    protected static function boot()
    {
        parent::boot();

        static::saving(function ($item) {
            // Auto-calculate total prices
            $item->total_price = $item->quantity_delivered * $item->unit_price;
            $item->total_price_aed = $item->quantity_delivered * $item->unit_price_aed;

            // Calculate warranty expiry if warranty period is set
            if ($item->warranty_period_months && $item->manufacturing_date) {
                $item->warranty_expiry = $item->manufacturing_date->addMonths($item->warranty_period_months);
            }

            // Set accepted quantity to delivered if not manually set
            if ($item->quantity_accepted == 0 && $item->quality_status === 'passed') {
                $item->quantity_accepted = $item->quantity_delivered;
            }

            // Set rejected quantity if quality failed
            if ($item->quality_status === 'failed') {
                $item->quantity_rejected = $item->quantity_delivered;
                $item->quantity_accepted = 0;
            }
        });
    }

    /**
     * Get the operation
     */
    public function operation(): BelongsTo
    {
        return $this->belongsTo(IncomingOperation::class, 'incoming_operation_id');
    }

    /**
     * Get the item details
     */
    public function item(): BelongsTo
    {
        return $this->belongsTo(Item::class);
    }

    /**
     * Get the allocated project
     */
    public function allocatedProject(): BelongsTo
    {
        return $this->belongsTo(Project::class, 'allocated_project_id');
    }

    /**
     * Get the associated direct delivery item (for site returns)
     */
    public function directDeliveryItem(): BelongsTo
    {
        return $this->belongsTo(\App\Models\DirectDeliveryItem::class, 'direct_delivery_item_id');
    }

    /**
     * Check if item is expired
     */
    public function getIsExpiredAttribute()
    {
        return $this->expiry_date && $this->expiry_date < now();
    }

    /**
     * Get days until expiry
     */
    public function getDaysUntilExpiryAttribute()
    {
        if (!$this->expiry_date) {
            return null;
        }

        return now()->diffInDays($this->expiry_date, false);
    }

    /**
     * Check if item is under warranty
     */
    public function getIsUnderWarrantyAttribute()
    {
        return $this->warranty_expiry && $this->warranty_expiry > now();
    }

    /**
     * Get days until warranty expiry
     */
    public function getDaysUntilWarrantyExpiryAttribute()
    {
        if (!$this->warranty_expiry) {
            return null;
        }

        return now()->diffInDays($this->warranty_expiry, false);
    }

    /**
     * Get quality status badge class
     */
    public function getQualityStatusBadgeClassAttribute()
    {
        return match($this->quality_status) {
            'pending' => 'badge-warning',
            'passed' => 'badge-success',
            'failed' => 'badge-danger',
            'conditional' => 'badge-info',
            default => 'badge-secondary'
        };
    }

    /**
     * Get formatted batch number
     */
    public function getFormattedBatchNumberAttribute()
    {
        return $this->batch_number ?: 'N/A';
    }

    /**
     * Get formatted serial number
     */
    public function getFormattedSerialNumberAttribute()
    {
        return $this->serial_number ?: 'N/A';
    }

    /**
     * Get formatted unit price
     */
    public function getFormattedUnitPriceAttribute()
    {
        return $this->currency . ' ' . number_format($this->unit_price, 2);
    }

    /**
     * Get formatted total price
     */
    public function getFormattedTotalPriceAttribute()
    {
        return $this->currency . ' ' . number_format($this->total_price, 2);
    }

    /**
     * Get formatted unit price in AED
     */
    public function getFormattedUnitPriceAedAttribute()
    {
        return 'AED ' . number_format($this->unit_price_aed, 2);
    }

    /**
     * Get formatted total price in AED
     */
    public function getFormattedTotalPriceAedAttribute()
    {
        return 'AED ' . number_format($this->total_price_aed, 2);
    }

    /**
     * Check if item is hazardous
     */
    public function isHazardous()
    {
        return $this->hazardous_material;
    }

    /**
     * Check if item requires quality inspection
     */
    public function requiresInspection()
    {
        return $this->operation->requires_inspection;
    }

    /**
     * Check if item passed quality control
     */
    public function passedQualityControl()
    {
        return $this->quality_status === 'passed';
    }

    /**
     * Check if item failed quality control
     */
    public function failedQualityControl()
    {
        return $this->quality_status === 'failed';
    }

    /**
     * Get acceptance rate
     */
    public function getAcceptanceRateAttribute()
    {
        if ($this->quantity_delivered == 0) {
            return 0;
        }

        return ($this->quantity_accepted / $this->quantity_delivered) * 100;
    }

    /**
     * Get rejection rate
     */
    public function getRejectionRateAttribute()
    {
        if ($this->quantity_delivered == 0) {
            return 0;
        }

        return ($this->quantity_rejected / $this->quantity_delivered) * 100;
    }
}