<?php

namespace App\Modules\Finance\Services;

use App\Modules\Finance\Models\AccountPayable;
use Illuminate\Support\Facades\DB;
use App\Modules\Inventory\Contracts\GoodsReceiptServiceInterface;

class AccountPayableService
{
    protected GoodsReceiptServiceInterface $goodsReceiptService;

    public function __construct(GoodsReceiptServiceInterface $goodsReceiptService)
    {
        $this->goodsReceiptService = $goodsReceiptService;
    }

    /**
     * 根據進貨單建立應付帳款
     * 
     * @param int $goodsReceiptId
     * @param int $userId 執行操作的使用者 ID
     * @return AccountPayable
     * @throws \Exception
     */
    public function createFromGoodsReceipt(int $goodsReceiptId, int $userId): AccountPayable
    {
        // 透過 Contract 取得 Inventory 模組的資料，避免直接依賴 Model
        $receiptData = $this->goodsReceiptService->getGoodsReceiptData($goodsReceiptId);

        if (!$receiptData) {
            throw new \Exception("找不到對應的進貨單資料 (ID: {$goodsReceiptId})");
        }

        // 檢查是否已經建立過（密等性）
        $existingAp = AccountPayable::where('source_document_type', 'goods_receipt')
            ->where('source_document_id', $goodsReceiptId)
            ->first();

        if ($existingAp) {
            return $existingAp;
        }

        return DB::transaction(function () use ($receiptData, $userId) {
            $ap = AccountPayable::create([
                'vendor_id' => $receiptData['vendor_id'],
                'source_document_type' => 'goods_receipt',
                'source_document_id' => $receiptData['id'],
                'document_number' => $this->generateApNumber(),
                'total_amount' => collect($receiptData['items'] ?? [])->sum('total_amount'),
                'tax_amount' => 0, // 假設後續會實作稅額計算，目前預設為 0
                'status' => AccountPayable::STATUS_PENDING,
                // 設定應付日期，預設為進貨後天數 (由系統設定決定，預設 30 天)
                'due_date' => now()->addDays(\App\Modules\Core\Models\SystemSetting::getVal('finance.ap_payment_days', 30))->toDateString(),
                'created_by' => $userId,
                'remarks' => "由進貨單 {$receiptData['code']} 自動生成",
            ]);

            return $ap;
        });
    }

    /**
     * 產生應付帳款單號
     */
    protected function generateApNumber(): string
    {
        $prefix = 'AP-' . date('Ymd') . '-';
        $lastPrefix = "{$prefix}%";
        
        $latest = AccountPayable::where('document_number', 'like', $lastPrefix)
            ->orderBy('document_number', 'desc')
            ->lockForUpdate()
            ->first();

        if (!$latest) {
            return $prefix . '01';
        }

        $parts = explode('-', $latest->document_number);
        $lastNumber = intval(end($parts));
        $newNumber = str_pad((string)($lastNumber + 1), 2, '0', STR_PAD_LEFT);
        
        return $prefix . $newNumber;
    }
}
