<?php

namespace App\Modules\Procurement\Models;

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


class PurchaseOrder extends Model
{
    /** @use HasFactory<\Database\Factories\PurchaseOrderFactory> */
    use HasFactory;
    use \Spatie\Activitylog\Traits\LogsActivity;

    protected $fillable = [
        'code',
        'vendor_id',
        'warehouse_id',
        'user_id',
        'order_date',
        'expected_delivery_date',
        'status',
        'total_amount',
        'tax_amount',
        'grand_total',
        'remark',
        'invoice_number',
        'invoice_date',
        'invoice_amount',
    ];

    protected $casts = [
        'order_date' => 'date',
        'expected_delivery_date' => 'date',
        'total_amount' => 'decimal:2',
    ];

    public function getActivitylogOptions(): \Spatie\Activitylog\LogOptions
    {
        return \Spatie\Activitylog\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;

        // 1. Snapshot 快照
        $snapshot = $properties['snapshot'] ?? [];
        $snapshot['po_number'] = $this->code;
        $snapshot['vendor_name'] = $this->vendor?->name;
        // 倉庫名稱需透過服務取得（跨模組），若已在 snapshot 中則保留
        if (!isset($snapshot['warehouse_name']) && $this->warehouse_id) {
            $warehouse = app(\App\Modules\Inventory\Contracts\InventoryServiceInterface::class)->getWarehouse($this->warehouse_id);
            $snapshot['warehouse_name'] = $warehouse?->name ?? null;
        }
        $properties['snapshot'] = $snapshot;

        // 2. 名稱解析：自動將 attributes 與 old 中的 ID 換成人名/物名
        $resolver = function (&$data) {
            if (empty($data) || !is_array($data)) return;

            // 使用者 ID 轉換
            foreach (['user_id', 'created_by', 'updated_by'] as $f) {
                if (isset($data[$f]) && is_numeric($data[$f])) {
                    $data[$f] = \App\Modules\Core\Models\User::find($data[$f])?->name ?? $data[$f];
                }
            }
            // 廠商 ID 轉換
            if (isset($data['vendor_id']) && is_numeric($data['vendor_id'])) {
                $data['vendor_id'] = Vendor::find($data['vendor_id'])?->name ?? $data['vendor_id'];
            }
            // 倉庫 ID 轉換（跨模組，透過服務）
            if (isset($data['warehouse_id']) && is_numeric($data['warehouse_id'])) {
                $warehouse = app(\App\Modules\Inventory\Contracts\InventoryServiceInterface::class)->getWarehouse($data['warehouse_id']);
                $data['warehouse_id'] = $warehouse?->name ?? $data['warehouse_id'];
            }
        };

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

        // 3. 合併 activityProperties (手動傳入的 items_diff 等)
        if (!empty($this->activityProperties)) {
            $properties = array_merge($properties, $this->activityProperties);
        }

        $activity->properties = $properties;
    }

    public function vendor(): \Illuminate\Database\Eloquent\Relations\BelongsTo
    {
        return $this->belongsTo(Vendor::class);
    }

    public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo
    {
        return $this->belongsTo(\App\Modules\Core\Models\User::class);
    }





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

    /**
     * 檢查是否可以轉移至新狀態，並驗證權限。
     */
    public function canTransitionTo(string $newStatus, $user = null): bool
    {
        $user = $user ?? auth()->user();
        if (!$user) return false;
        if ($user->hasRole('super-admin')) return true;

        $currentStatus = $this->status;

        // 定義合法的狀態轉移路徑與所需權限
        $transitions = [
            'draft' => [
                'pending' => 'purchase_orders.view', // 基本檢視者即可送審
                'cancelled' => 'purchase_orders.cancel',
            ],
            'pending' => [
                'approved' => 'purchase_orders.approve',
                'draft' => 'purchase_orders.approve', // 退回草稿
                'cancelled' => 'purchase_orders.cancel',
            ],
            'approved' => [
                'cancelled' => 'purchase_orders.cancel',
                'partial' => null, // 系統自動轉移，不需手動權限點
            ],
            'partial' => [
                'completed' => null, // 系統自動轉移
                'closed' => 'purchase_orders.approve', // 手動結案通常需要核准權限
                'cancelled' => 'purchase_orders.cancel',
            ],
        ];

        if (!isset($transitions[$currentStatus])) {
            return false;
        }

        if (!array_key_exists($newStatus, $transitions[$currentStatus])) {
            return false;
        }

        $requiredPermission = $transitions[$currentStatus][$newStatus];
        
        return $requiredPermission ? $user->can($requiredPermission) : true;
    }
}
