<?php

namespace Kylin\Pet\Services;

use App\Models\Product;
use App\Models\Purchase;
use App\Models\PurchaseItem;
use Illuminate\Support\Facades\DB;

/**
 * 库存服务 - 进销存管理
 */
class InventoryService
{
    /**
     * 创建采购单并自动入库
     */
    public function createPurchase(array $data): Purchase
    {
        return DB::transaction(function () use ($data) {
            // 生成采购单号
            $data['purchase_no'] = 'PO' . now()->format('Ymd') . str_pad(
                Purchase::whereDate('created_at', today())->count() + 1, 4, '0', STR_PAD_LEFT
            );
            $data['status'] = 'pending';

            $items = $data['items'] ?? [];
            unset($data['items']);

            $totalAmount = 0;
            $purchase = Purchase::create($data);

            foreach ($items as $item) {
                $subtotal = $item['quantity'] * $item['unit_price'];
                $totalAmount += $subtotal;

                $purchase->items()->create([
                    'product_id' => $item['product_id'],
                    'quantity' => $item['quantity'],
                    'unit_price' => $item['unit_price'],
                    'subtotal' => $subtotal,
                ]);
            }

            $purchase->update(['total_amount' => $totalAmount]);

            $this->audit('purchase_created', $purchase, [
                'purchase_no' => $purchase->purchase_no,
                'total_amount' => $totalAmount,
            ]);

            return $purchase->fresh();
        });
    }

    /**
     * 审批采购单并入库
     */
    public function approvePurchase(Purchase $purchase): Purchase
    {
        return DB::transaction(function () use ($purchase) {
            $purchase->update(['status' => 'approved']);

            // 入库：增加商品库存
            foreach ($purchase->items as $item) {
                Product::where('id', $item->product_id)->increment('stock', $item->quantity);
            }

            $this->audit('purchase_approved', $purchase, [
                'purchase_no' => $purchase->purchase_no,
            ]);

            return $purchase->fresh();
        });
    }

    /**
     * 库存出库（订单发货）
     */
    public function deductStock(int $productId, int $quantity): bool
    {
        $product = Product::findOrFail($productId);

        if ($product->stock < $quantity) {
            throw new \InvalidArgumentException("商品 {$product->name} 库存不足");
        }

        $result = Product::where('id', $productId)
            ->where('stock', '>=', $quantity)
            ->decrement('stock', $quantity) > 0;

        if ($result) {
            $this->audit('stock_deducted', null, [
                'product_id' => $productId,
                'quantity' => $quantity,
            ]);
        }

        return $result;
    }

    /**
     * 记录库存审计日志
     *
     * 依据《电子商务法》和《消费者权益保护法》，
     * 采购、入库、出库等操作需记录审计日志，便于库存追溯。
     */
    private function audit(string $event, ?Purchase $purchase, array $extra = []): void
    {
        if (! class_exists(\Kylin\AuditLog\Models\AuditLog::class)) {
            return;
        }

        try {
            \Kylin\AuditLog\Models\AuditLog::create([
                'event' => $event,
                'model_type' => Purchase::class,
                'model_id' => $purchase?->id ?? 0,
                'new_values' => $extra,
                'old_values' => null,
                'user_id' => auth()->id(),
                'ip' => request()?->ip(),
                'url' => request()?->fullUrl(),
                'tag' => 'pet-inventory',
            ]);
        } catch (\Throwable $e) {
            logger()->warning('库存审计日志写入失败', [
                'error' => $e->getMessage(),
                'purchase_id' => $purchase?->id,
                'event' => $event,
            ]);
        }
    }
}
