<?php

namespace App\Modules\Procurement\Services;

use App\Modules\Procurement\Models\PurchaseReturn;
use App\Modules\Procurement\Models\PurchaseReturnItem;
use App\Modules\Inventory\Contracts\InventoryServiceInterface;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Exception;

class PurchaseReturnService
{
    protected $inventoryService;

    public function __construct(InventoryServiceInterface $inventoryService)
    {
        // 依賴反轉，透過介面呼叫 Inventory
        $this->inventoryService = $inventoryService;
    }

    /**
     * 建立退貨單 (草稿)
     */
    public function store(array $data)
    {
        return DB::transaction(function () use ($data) {
            $data['code'] = $this->generateCode($data['return_date']);
            $data['user_id'] = auth()->id();
            $data['status'] = PurchaseReturn::STATUS_DRAFT;

            $totalAmount = 0;
            
            $purchaseReturn = PurchaseReturn::create($data);

            $itemsToInsert = [];
            foreach ($data['items'] as $itemData) {
                $amount = $itemData['quantity_returned'] * $itemData['unit_price'];
                $totalAmount += $amount;
                
                $itemsToInsert[] = [
                    'purchase_return_id' => $purchaseReturn->id,
                    'product_id' => $itemData['product_id'],
                    'quantity_returned' => $itemData['quantity_returned'],
                    'unit_price' => $itemData['unit_price'],
                    'total_amount' => $amount,
                    'batch_number' => $itemData['batch_number'] ?? null,
                    'created_at' => now(),
                    'updated_at' => now(),
                ];
            }
            PurchaseReturnItem::insert($itemsToInsert);

            // 更新總計 (這裡假定不含額外稅金邏輯，或是由前端帶入 tax_amount)
            $taxAmount = $data['tax_amount'] ?? 0;
            $purchaseReturn->update([
                'total_amount' => $totalAmount,
                'tax_amount' => $taxAmount,
                'grand_total' => $totalAmount + $taxAmount,
            ]);

            return $purchaseReturn;
        });
    }

    /**
     * 更新退貨單 (限草稿)
     */
    public function update(PurchaseReturn $purchaseReturn, array $data)
    {
        if ($purchaseReturn->status !== PurchaseReturn::STATUS_DRAFT) {
            throw new Exception('只有草稿狀態的退回單可以修改。');
        }

        return DB::transaction(function () use ($purchaseReturn, $data) {
            $updateData = [
                'vendor_id' => $data['vendor_id'] ?? $purchaseReturn->vendor_id,
                'warehouse_id' => $data['warehouse_id'] ?? $purchaseReturn->warehouse_id,
                'return_date' => $data['return_date'] ?? $purchaseReturn->return_date,
                'remarks' => $data['remarks'] ?? $purchaseReturn->remarks,
            ];
            
            if (isset($data['tax_amount'])) {
                $updateData['tax_amount'] = $data['tax_amount'];
            }
            
            $purchaseReturn->update($updateData);

            if (isset($data['items'])) {
                $purchaseReturn->items()->delete();
                $totalAmount = 0;

                $itemsToInsert = [];
                foreach ($data['items'] as $itemData) {
                    $amount = $itemData['quantity_returned'] * $itemData['unit_price'];
                    $totalAmount += $amount;
                    
                    $itemsToInsert[] = [
                        'purchase_return_id' => $purchaseReturn->id,
                        'product_id' => $itemData['product_id'],
                        'quantity_returned' => $itemData['quantity_returned'],
                        'unit_price' => $itemData['unit_price'],
                        'total_amount' => $amount,
                        'batch_number' => $itemData['batch_number'] ?? null,
                        'created_at' => now(),
                        'updated_at' => now(),
                    ];
                }
                PurchaseReturnItem::insert($itemsToInsert);
                
                $taxAmount = $purchaseReturn->tax_amount;
                $purchaseReturn->update([
                    'total_amount' => $totalAmount,
                    'grand_total' => $totalAmount + $taxAmount,
                ]);
            }

            return $purchaseReturn->fresh('items');
        });
    }

    /**
     * 送出審核 / 確認退貨 (扣減倉庫庫存)
     */
    public function submit(PurchaseReturn $purchaseReturn)
    {
        return DB::transaction(function () use ($purchaseReturn) {
            // 加上 lockForUpdate() 防止併發提交
            $purchaseReturn = PurchaseReturn::lockForUpdate()->find($purchaseReturn->id);

            if ($purchaseReturn->status !== PurchaseReturn::STATUS_DRAFT) {
                throw new Exception('只有草稿狀態的退回單可以提交。');
            }

            // 1. 儲存狀態，避免觸發自動修改紀錄 (合併行為)
            $purchaseReturn->status = PurchaseReturn::STATUS_COMPLETED;
            $purchaseReturn->saveQuietly(); 

            // 2. 扣減庫存
            $updatedItems = [];
            foreach ($purchaseReturn->items as $prItem) {
                // 調用 Inventory Service 的 FIFO 扣庫存邏輯
                $this->inventoryService->decreaseStock(
                    $prItem->product_id,
                    $purchaseReturn->warehouse_id,
                    $prItem->quantity_returned,
                    '採購退回 (' . $purchaseReturn->code . ')'
                );
                
                $updatedItems[] = [
                    'product_id' => $prItem->product_id,
                    'quantity_returned' => $prItem->quantity_returned,
                ];
            }

            // 3. 手動觸發合併的操作紀錄
            activity()
                ->performedOn($purchaseReturn)
                ->withProperties([
                    'items_diff' => ['returned' => $updatedItems],
                    'attributes' => ['status' => PurchaseReturn::STATUS_COMPLETED],
                    'old' => ['status' => PurchaseReturn::STATUS_DRAFT],
                    'snapshot' => [
                        'return_no' => $purchaseReturn->code,
                        'vendor_id' => $purchaseReturn->vendor_id, 
                    ] // Service 層若無法拿到 warehouse 名稱，依賴 Model tapActivity 解析
                ])
                ->log('submitted');

            return $purchaseReturn;
        });
    }

    /**
     * 取消退貨單
     */
    public function cancel(PurchaseReturn $purchaseReturn)
    {
        if ($purchaseReturn->status === PurchaseReturn::STATUS_COMPLETED) {
            throw new Exception('已完成扣庫的退貨單無法直接取消，需進行逆向調整。');
        }

        $purchaseReturn->update(['status' => PurchaseReturn::STATUS_CANCELLED]);
        return $purchaseReturn;
    }

    /**
     * 刪除退貨單
     */
    public function delete(PurchaseReturn $purchaseReturn)
    {
        if ($purchaseReturn->status === PurchaseReturn::STATUS_COMPLETED) {
            throw new Exception('已完成的退貨單無法刪除。');
        }
        
        return DB::transaction(function () use ($purchaseReturn) {
            $purchaseReturn->items()->delete();
            $purchaseReturn->delete();
        });
    }

    private function generateCode(string $date)
    {
        // 格式: PR-YYYYMMDD-NN
        $prefix = 'PR-' . date('Ymd', strtotime($date)) . '-';
        
        $last = PurchaseReturn::where('code', 'like', $prefix . '%')
            ->orderBy('id', 'desc')
            ->lockForUpdate()
            ->first();

        if ($last) {
            $seq = intval(substr($last->code, -2)) + 1;
        } else {
            $seq = 1;
        }

        return $prefix . str_pad($seq, 2, '0', STR_PAD_LEFT);
    }
}
