<?php

namespace App\Modules\Procurement\Services;

use App\Modules\Procurement\Models\ShippingOrder;
use App\Modules\Procurement\Models\ShippingOrderItem;
use App\Modules\Inventory\Contracts\InventoryServiceInterface;
use Illuminate\Support\Facades\DB;

class ShippingService
{
    protected $inventoryService;

    public function __construct(InventoryServiceInterface $inventoryService)
    {
        $this->inventoryService = $inventoryService;
    }

    public function createShippingOrder(array $data)
    {
        return DB::transaction(function () use ($data) {
            $order = ShippingOrder::create([
                'warehouse_id' => $data['warehouse_id'],
                'customer_name' => $data['customer_name'] ?? null,
                'shipping_date' => $data['shipping_date'],
                'status' => 'draft',
                'remarks' => $data['remarks'] ?? null,
                'created_by' => auth()->id(),
                'total_amount' => $data['total_amount'] ?? 0,
                'tax_amount' => $data['tax_amount'] ?? 0,
                'grand_total' => $data['grand_total'] ?? 0,
            ]);

            foreach ($data['items'] as $item) {
                $order->items()->create([
                    'product_id' => $item['product_id'],
                    'batch_number' => $item['batch_number'] ?? null,
                    'quantity' => $item['quantity'],
                    'unit_price' => $item['unit_price'] ?? 0,
                    'subtotal' => $item['subtotal'] ?? ($item['quantity'] * ($item['unit_price'] ?? 0)),
                    'remark' => $item['remark'] ?? null,
                ]);
            }

            return $order;
        });
    }

    public function updateShippingOrder(ShippingOrder $order, array $data)
    {
        return DB::transaction(function () use ($order, $data) {
            $order->update([
                'warehouse_id' => $data['warehouse_id'],
                'customer_name' => $data['customer_name'] ?? null,
                'shipping_date' => $data['shipping_date'],
                'remarks' => $data['remarks'] ?? null,
                'total_amount' => $data['total_amount'] ?? 0,
                'tax_amount' => $data['tax_amount'] ?? 0,
                'grand_total' => $data['grand_total'] ?? 0,
            ]);

            // 簡單處理：刪除舊項目並新增
            $order->items()->delete();
            foreach ($data['items'] as $item) {
                $order->items()->create([
                    'product_id' => $item['product_id'],
                    'batch_number' => $item['batch_number'] ?? null,
                    'quantity' => $item['quantity'],
                    'unit_price' => $item['unit_price'] ?? 0,
                    'subtotal' => $item['subtotal'] ?? ($item['quantity'] * ($item['unit_price'] ?? 0)),
                    'remark' => $item['remark'] ?? null,
                ]);
            }

            return $order;
        });
    }

    public function post(ShippingOrder $order)
    {
        if ($order->status !== 'draft') {
            throw new \Exception('該單據已過帳或已取消。');
        }

        return DB::transaction(function () use ($order) {
            foreach ($order->items as $item) {
                // 尋找對應的庫存紀錄
                $inventory = $this->inventoryService->findInventoryByBatch(
                    $order->warehouse_id,
                    $item->product_id,
                    $item->batch_number
                );

                if (!$inventory || $inventory->quantity < $item->quantity) {
                    $productName = $this->inventoryService->getProduct($item->product_id)?->name ?? 'Unknown';
                    throw new \Exception("商品 [{$productName}] (批號: {$item->batch_number}) 庫存不足。");
                }

                // 扣除庫存
                $this->inventoryService->decreaseInventoryQuantity(
                    $inventory->id,
                    $item->quantity,
                    "出貨扣款: 單號 [{$order->doc_no}]",
                    'ShippingOrder',
                    $order->id
                );
            }

            $order->update([
                'status' => 'completed',
                'posted_by' => auth()->id(),
                'posted_at' => now(),
            ]);

            return $order;
        });
    }
}
