<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class OrderItem extends Model
{
    use HasFactory;

    public $timestamps = false;

    protected $fillable = [
        'order_id',
        'product_id',
        'allocated_location_id',
        'name',
        'sku',
        'qty',
        'reserved_qty',
        'fulfilled_qty',
        'price',
        'discount_percentage',
        'line_total',
        'tax_amount',
        'purchase_price',
        'allocated_discount',
        'allocated_shipping',
        'allocated_extra_costs',
    ];

    protected function casts(): array
    {
        return [
            'qty' => 'integer',
            'reserved_qty' => 'integer',
            'fulfilled_qty' => 'integer',
            'price' => 'decimal:2',
            'discount_percentage' => 'decimal:2',
            'line_total' => 'decimal:2',
            'tax_amount' => 'decimal:2',
            'purchase_price' => 'decimal:2',
            'allocated_discount' => 'decimal:2',
            'allocated_shipping' => 'decimal:2',
            'allocated_extra_costs' => 'decimal:2',
        ];
    }

    public function order()
    {
        return $this->belongsTo(Order::class);
    }

    public function product()
    {
        return $this->belongsTo(Product::class);
    }

    public function allocatedLocation()
    {
        return $this->belongsTo(Location::class, 'allocated_location_id');
    }

    /**
     * Calculate unit profit for this order item
     * UnitProfit = (unit_sale_price - unit_discount_allocation) - purchase_price - unit_allocated_extra_costs
     *
     * @return float
     */
    public function getUnitProfitAttribute(): float
    {
        if (is_null($this->purchase_price)) {
            return 0;
        }

        $unitSalePrice = $this->price;
        $unitDiscountAllocation = $this->allocated_discount / max($this->qty, 1);
        $unitAllocatedExtraCosts = $this->allocated_extra_costs / max($this->qty, 1);

        return round(
            ($unitSalePrice - $unitDiscountAllocation) -
            $this->purchase_price -
            $unitAllocatedExtraCosts,
            2
        );
    }

    /**
     * Calculate total profit for this order item (unit profit * quantity)
     *
     * @return float
     */
    public function getTotalProfitAttribute(): float
    {
        return round($this->unit_profit * $this->qty, 2);
    }

    /**
     * Calculate profit margin percentage for this order item
     *
     * @return float|null
     */
    public function getProfitMarginAttribute(): ?float
    {
        $revenue = ($this->price * $this->qty) - $this->allocated_discount;
        
        if ($revenue <= 0) {
            return null;
        }

        return round(($this->total_profit / $revenue) * 100, 2);
    }

    /**
     * Calculate total revenue for this order item (after discounts)
     *
     * @return float
     */
    public function getRevenueAttribute(): float
    {
        return round(($this->price * $this->qty) - $this->allocated_discount, 2);
    }

    /**
     * Calculate total COGS (Cost of Goods Sold) for this order item
     *
     * @return float
     */
    public function getTotalCogsAttribute(): float
    {
        if (is_null($this->purchase_price)) {
            return 0;
        }

        return round(
            ($this->purchase_price * $this->qty) +
            $this->allocated_extra_costs,
            2
        );
    }

    /**
     * Check if this order item has purchase price data for profit calculation
     *
     * @return bool
     */
    public function hasProfitData(): bool
    {
        return !is_null($this->purchase_price);
    }
}
