<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Traits\Auditable;

class Product extends Model
{
    use HasFactory, Auditable;

    protected $fillable = [
        'product_code', 'sku', 'name', 'description', 'unit',
        'purchase_price', 'sales_price',
        'current_stock', 'minimum_stock', 'user_id',
        'payment_method', 'bank_account_id', 'digital_payment_id',
        'total_purchase_price'
    ];

    protected $casts = [
        'purchase_price' => 'decimal:2',
        'sales_price' => 'decimal:2',
        'current_stock' => 'integer',
        'minimum_stock' => 'integer',
        'total_purchase_price' => 'decimal:2'
    ];

    protected static function boot()
    {
        parent::boot();

        static::creating(function ($product) {
            if (empty($product->product_code)) {
                $product->product_code = 'PRD-' . strtoupper(uniqid());
            }
            $product->total_purchase_price = $product->current_stock * $product->purchase_price;

            // Deduct from payment method
            $product->deductFromPaymentMethod($product->total_purchase_price);
        });

        static::updating(function ($product) {
            $oldPrice = $product->getOriginal('total_purchase_price') ?? 0;
            $newPrice = $product->current_stock * $product->purchase_price;
            $product->total_purchase_price = $newPrice;

            // Handle price difference
            $priceDifference = $newPrice - $oldPrice;
            if ($priceDifference != 0) {
                $product->deductFromPaymentMethod($priceDifference);
            }
        });

        static::deleted(function ($product) {
            // Refund to payment method when product is deleted
            $product->refundToPaymentMethod($product->total_purchase_price);
        });
    }

    private function deductFromPaymentMethod($amount)
    {
        if ($amount <= 0) return;

        if ($this->payment_method === 'bank' && $this->bank_account_id) {
            $bankAccount = BankAccount::find($this->bank_account_id);
            if ($bankAccount) {
                $bankAccount->decrement('balance', $amount);
            }
        } elseif ($this->payment_method === 'digital' && $this->digital_payment_id) {
            $digitalPayment = DigitalPayment::find($this->digital_payment_id);
            if ($digitalPayment) {
                $digitalPayment->decrement('balance', $amount);
            }
        }
    }

    private function refundToPaymentMethod($amount)
    {
        if ($amount <= 0) return;

        if ($this->payment_method === 'bank' && $this->bank_account_id) {
            $bankAccount = BankAccount::find($this->bank_account_id);
            if ($bankAccount) {
                $bankAccount->increment('balance', $amount);
            }
        } elseif ($this->payment_method === 'digital' && $this->digital_payment_id) {
            $digitalPayment = DigitalPayment::find($this->digital_payment_id);
            if ($digitalPayment) {
                $digitalPayment->increment('balance', $amount);
            }
        }
    }

    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function stockMovements()
    {
        return $this->hasMany(StockMovement::class);
    }

    public function invoiceItems()
    {
        return $this->hasMany(InvoiceItem::class);
    }

    public function bankAccount()
    {
        return $this->belongsTo(BankAccount::class);
    }

    public function digitalPayment()
    {
        return $this->belongsTo(DigitalPayment::class);
    }
}
