<?php

namespace App\Modules\Inventory\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Activitylog\LogOptions;


class Product extends Model
{
    use HasFactory, LogsActivity, SoftDeletes;

    protected $fillable = [
        'code',
        'barcode',
        'name',
        'external_pos_id',
        'category_id',
        'brand',
        'specification',
        'base_unit_id',
        'large_unit_id',
        'conversion_rate',
        'purchase_unit_id',
        'location',
        'cost_price',
        'price',
        'member_price',
        'wholesale_price',
        'is_active',
    ];

    protected $casts = [
        'conversion_rate' => 'decimal:4',
        'is_active' => 'boolean',
    ];

    /**
     * 取得該商品所屬的分類。
     */
    public function category(): BelongsTo
    {
        return $this->belongsTo(Category::class);
    }

    public function baseUnit(): BelongsTo
    {
        return $this->belongsTo(Unit::class, 'base_unit_id');
    }

    public function largeUnit(): BelongsTo
    {
        return $this->belongsTo(Unit::class, 'large_unit_id');
    }

    public function purchaseUnit(): BelongsTo
    {
        return $this->belongsTo(Unit::class, 'purchase_unit_id');
    }



    public function inventories(): \Illuminate\Database\Eloquent\Relations\HasMany
    {
        return $this->hasMany(Inventory::class);
    }

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

    public function getActivitylogOptions(): LogOptions
    {
        return LogOptions::defaults()
            ->logAll()
            ->logOnlyDirty()
            ->dontSubmitEmptyLogs();
    }

    public function tapActivity(\Spatie\Activitylog\Contracts\Activity $activity, string $eventName)
    {
        // 核心：轉換為陣列以避免 Indirect modification error
        $properties = $activity->properties instanceof \Illuminate\Support\Collection 
            ? $activity->properties->toArray() 
            : $activity->properties;

        $snapshot = $properties['snapshot'] ?? [];
        
        // 始終對自身名稱進行快照以便於上下文顯示（這樣日誌總是顯示 "可樂"）
        $snapshot['name'] = $this->name;

        $properties['snapshot'] = $snapshot;

        // 全域 ID 轉名稱邏輯
        $resolver = function (&$data) use (&$snapshot) {
            if (empty($data) || !is_array($data)) return;
            
            // 處理分類名稱
            if (isset($data['category_id']) && is_numeric($data['category_id'])) {
                $categoryName = Category::find($data['category_id'])?->name;
                $data['category_id'] = $categoryName;
                if (!isset($snapshot['category_name']) && $categoryName) {
                    $snapshot['category_name'] = $categoryName;
                }
            }
            
            // 處理單位名稱
            $unitFields = ['base_unit_id', 'large_unit_id', 'purchase_unit_id'];
            foreach ($unitFields as $field) {
                if (isset($data[$field]) && is_numeric($data[$field])) {
                    $unitName = Unit::find($data[$field])?->name;
                    $data[$field] = $unitName;
                    
                    $nameKey = str_replace('_id', '_name', $field);
                    if (!isset($snapshot[$nameKey]) && $unitName) {
                        $snapshot[$nameKey] = $unitName;
                    }
                }
            }
        };

        if (isset($properties['attributes'])) $resolver($properties['attributes']);
        if (isset($properties['old'])) $resolver($properties['old']);

        // 因為 resolver 內部可能更新了 snapshot，所以再覆寫一次
        $properties['snapshot'] = $snapshot;
        $activity->properties = $properties;
    }

    public function warehouses(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
    {
        return $this->belongsToMany(Warehouse::class, 'inventories')
            ->withPivot(['quantity', 'safety_stock', 'location'])
            ->withTimestamps();
    }
}
