<?php

namespace App\Modules\Inventory\Services;

use App\Modules\Inventory\Models\StoreRequisition;
use App\Modules\Inventory\Models\StoreRequisitionItem;
use App\Modules\Inventory\Models\InventoryTransferOrder;
use App\Modules\Inventory\Models\InventoryTransferItem;
use App\Modules\Inventory\Notifications\StoreRequisitionNotification;
use App\Modules\Core\Models\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;

class StoreRequisitionService
{
    protected TransferService $transferService;

    public function __construct(TransferService $transferService)
    {
        $this->transferService = $transferService;
    }

    /**
     * 建立叫貨單（含明細）
     */
    public function create(array $data, array $items, int $userId): StoreRequisition
    {
        return DB::transaction(function () use ($data, $items, $userId) {
            $requisition = StoreRequisition::create([
                'store_warehouse_id' => $data['store_warehouse_id'],
                'status' => 'draft',
                'remark' => $data['remark'] ?? null,
                'created_by' => $userId,
            ]);

            foreach ($items as $item) {
                $requisition->items()->create([
                    'product_id' => $item['product_id'],
                    'requested_qty' => $item['requested_qty'],
                    'remark' => $item['remark'] ?? null,
                ]);
            }

            return $requisition->load('items');
        });
    }

    /**
     * 更新叫貨單（僅限 draft / rejected 狀態）
     */
    public function update(StoreRequisition $requisition, array $data, array $items): StoreRequisition
    {
        if (!in_array($requisition->status, ['draft', 'rejected'])) {
            throw ValidationException::withMessages([
                'status' => '僅能編輯草稿或被駁回的叫貨單',
            ]);
        }

        return DB::transaction(function () use ($requisition, $data, $items) {
            $requisition->update([
                'store_warehouse_id' => $data['store_warehouse_id'],
                'remark' => $data['remark'] ?? null,
                'reject_reason' => null, // 清除駁回原因
            ]);

            // 重建明細
            $requisition->items()->delete();
            foreach ($items as $item) {
                $requisition->items()->create([
                    'product_id' => $item['product_id'],
                    'requested_qty' => $item['requested_qty'],
                    'remark' => $item['remark'] ?? null,
                ]);
            }

            return $requisition->load('items');
        });
    }

    /**
     * 提交審核（draft → pending）
     */
    public function submit(StoreRequisition $requisition, int $userId): StoreRequisition
    {
        if ($requisition->status !== 'draft' && $requisition->status !== 'rejected') {
            throw ValidationException::withMessages([
                'status' => '僅能提交草稿或被駁回的叫貨單',
            ]);
        }

        if ($requisition->items()->count() === 0) {
            throw ValidationException::withMessages([
                'items' => '叫貨單必須至少有一項商品',
            ]);
        }

        $requisition->update([
            'status' => 'pending',
            'submitted_at' => now(),
            'reject_reason' => null,
        ]);

        // 通知有審核權限的使用者
        $this->notifyApprovers($requisition, 'submitted', $userId);

        return $requisition;
    }

    /**
     * 核准叫貨單（pending → approved），選擇供貨倉庫並自動產生調撥單
     */
    public function approve(StoreRequisition $requisition, array $data, int $userId): StoreRequisition
    {
        if ($requisition->status !== 'pending') {
            throw ValidationException::withMessages([
                'status' => '僅能核准待審核的叫貨單',
            ]);
        }

        return DB::transaction(function () use ($requisition, $data, $userId) {
            // 更新核准數量
            if (isset($data['items'])) {
                foreach ($data['items'] as $itemData) {
                    StoreRequisitionItem::where('id', $itemData['id'])
                        ->where('store_requisition_id', $requisition->id)
                        ->update(['approved_qty' => $itemData['approved_qty']]);
                }
            }

            // 查詢供貨倉庫是否有預設在途倉
            $supplyWarehouse = \App\Modules\Inventory\Models\Warehouse::find($data['supply_warehouse_id']);
            $defaultTransitId = $supplyWarehouse?->default_transit_warehouse_id;

            // 產生調撥單（供貨倉庫 → 門市倉庫）
            $transferOrder = $this->transferService->createOrder(
                fromWarehouseId: $data['supply_warehouse_id'],
                toWarehouseId: $requisition->store_warehouse_id,
                remarks: "由叫貨單 {$requisition->doc_no} 自動產生",
                userId: $userId,
                transitWarehouseId: $defaultTransitId,
            );

            // 將核准的明細寫入調撥單
            $requisition->load('items');
            $transferItems = [];
            foreach ($requisition->items as $item) {
                $qty = $item->approved_qty ?? $item->requested_qty;
                if ($qty > 0) {
                    $transferItems[] = [
                        'product_id' => $item->product_id,
                        'quantity' => $qty,
                    ];
                }
            }

            if (!empty($transferItems)) {
                $this->transferService->updateItems($transferOrder, $transferItems);
            }

            // 更新叫貨單狀態
            $requisition->update([
                'status' => 'approved',
                'supply_warehouse_id' => $data['supply_warehouse_id'],
                'approved_by' => $userId,
                'approved_at' => now(),
                'transfer_order_id' => $transferOrder->id,
            ]);

            // 通知申請人
            $this->notifyCreator($requisition, 'approved', $userId);

            return $requisition->load(['items', 'transferOrder']);
        });
    }

    /**
     * 駁回叫貨單（pending → rejected）
     */
    public function reject(StoreRequisition $requisition, string $reason, int $userId): StoreRequisition
    {
        if ($requisition->status !== 'pending') {
            throw ValidationException::withMessages([
                'status' => '僅能駁回待審核的叫貨單',
            ]);
        }

        $requisition->update([
            'status' => 'rejected',
            'reject_reason' => $reason,
            'approved_by' => $userId,
            'approved_at' => now(),
        ]);

        // 通知申請人
        $this->notifyCreator($requisition, 'rejected', $userId);

        return $requisition;
    }

    /**
     * 取消叫貨單
     */
    public function cancel(StoreRequisition $requisition): StoreRequisition
    {
        if (!in_array($requisition->status, ['draft', 'pending'])) {
            throw ValidationException::withMessages([
                'status' => '僅能取消草稿或待審核的叫貨單',
            ]);
        }

        $requisition->update(['status' => 'cancelled']);

        return $requisition;
    }

    /**
     * 通知有審核權限的使用者
     */
    protected function notifyApprovers(StoreRequisition $requisition, string $action, int $actorId): void
    {
        $actor = User::find($actorId);
        $actorName = $actor?->name ?? 'System';

        // 找出有 store_requisitions.approve 權限的使用者
        $approvers = User::permission('store_requisitions.approve')->get();

        foreach ($approvers as $approver) {
            if ($approver->id !== $actorId) {
                $approver->notify(new StoreRequisitionNotification($requisition, $action, $actorName));
            }
        }
    }

    /**
     * 通知叫貨單申請人
     */
    protected function notifyCreator(StoreRequisition $requisition, string $action, int $actorId): void
    {
        $actor = User::find($actorId);
        $actorName = $actor?->name ?? 'System';

        $creator = User::find($requisition->created_by);
        if ($creator && $creator->id !== $actorId) {
            $creator->notify(new StoreRequisitionNotification($requisition, $action, $actorName));
        }
    }
}
