<?php

namespace App\Modules\Inventory\Imports;

use App\Modules\Inventory\Models\Product;
use App\Modules\Inventory\Models\Inventory;
use App\Modules\Inventory\Models\Warehouse;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithValidation;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\SkipsEmptyRows;
use Maatwebsite\Excel\Imports\HeadingRowFormatter;
use Illuminate\Support\Facades\DB;

class InventoryImport implements ToModel, WithHeadingRow, WithValidation, WithMapping, SkipsEmptyRows
{
    private $warehouse;
    private $inboundDate;
    private $notes;

    public function __construct(Warehouse $warehouse, string $inboundDate, ?string $notes = null)
    {
        HeadingRowFormatter::default('none');
        $this->warehouse = $warehouse;
        $this->inboundDate = $inboundDate;
        $this->notes = $notes;
    }

    public function map($row): array
    {
        // 處理條碼或代號為字串
        if (isset($row['商品條碼'])) {
            $row['商品條碼'] = (string) $row['商品條碼'];
        }
        if (isset($row['商品代號'])) {
            $row['商品代號'] = (string) $row['商品代號'];
        }
        if (isset($row['儲位/貨道'])) {
            $row['儲位/貨道'] = (string) $row['儲位/貨道'];
        }
        return $row;
    }

    public function model(array $row)
    {
        // 查找商品
        $product = null;
        if (!empty($row['商品條碼'])) {
            $product = Product::where('barcode', $row['商品條碼'])->first();
        }
        if (!$product && !empty($row['商品代號'])) {
            $product = Product::where('code', $row['商品代號'])->first();
        }

        if (!$product) {
            return null; // 透過 Validation 攔截
        }

        $quantity = (float) $row['數量'];
        $unitCost = isset($row['入庫單價']) ? (float) $row['入庫單價'] : ($product->cost_price ?? 0);
        $location = $row['儲位/貨道'] ?? null;
        
        // 批號邏輯：若 Excel 留空則使用 NO-BATCH
        $batchNumber = !empty($row['批號']) ? $row['批號'] : 'NO-BATCH';
        $originCountry = $row['產地'] ?? 'TW';
        $expiryDate = !empty($row['效期']) ? $row['效期'] : null;

        return DB::transaction(function () use ($product, $quantity, $unitCost, $location, $batchNumber, $originCountry, $expiryDate) {
            // 使用與 InventoryController 相同的 firstOrNew 邏輯
            $inventory = $this->warehouse->inventories()->withTrashed()->firstOrNew(
                [
                    'product_id' => $product->id,
                    'batch_number' => $batchNumber,
                    'location' => $location, // 加入儲位/貨道作為區分關鍵字
                ],
                [
                    'quantity' => 0,
                    'unit_cost' => $unitCost,
                    'total_value' => 0,
                    'arrival_date' => $this->inboundDate,
                    'expiry_date' => $expiryDate,
                    'origin_country' => $originCountry,
                ]
            );

            if ($inventory->trashed()) {
                $inventory->restore();
            }

            // 更新數量
            $oldQty = $inventory->quantity;
            $inventory->quantity += $quantity;
            
            // 更新單價與總價值
            $inventory->unit_cost = $unitCost;
            $inventory->total_value = $inventory->quantity * $unitCost;
            $inventory->save();

            // 記錄交易歷史
            $inventory->transactions()->create([
                'warehouse_id' => $this->warehouse->id,
                'product_id' => $product->id,
                'batch_number' => $inventory->batch_number,
                'quantity' => $quantity,
                'unit_cost' => $unitCost,
                'type' => '手動入庫',
                'reason' => 'Excel 匯入入庫',
                'balance_before' => $oldQty,
                'balance_after' => $inventory->quantity,
                'actual_time' => $this->inboundDate,
                'notes' => $this->notes,
                'expiry_date' => $inventory->expiry_date,
            ]);

            return $inventory;
        });
    }

    public function rules(): array
    {
        return [
            '商品條碼' => ['nullable', 'string'],
            '商品代號' => ['nullable', 'string'],
            '數量' => [
                'required_with:商品條碼,商品代號', // 只有在有商品資訊時，數量才是必填
                'numeric',
                'min:0' // 允許數量為 0
            ],
            '入庫單價' => ['nullable', 'numeric', 'min:0'],
            '儲位/貨道' => ['nullable', 'string', 'max:50'],
            '批號' => ['nullable', 'string'],
            '效期' => ['nullable', 'date'],
            '產地' => ['nullable', 'string', 'max:2'],
        ];
    }
}
