<?php

namespace App\Modules\Inventory\Services;

use App\Modules\Inventory\Models\Inventory;
use App\Modules\Inventory\Models\InventoryCountDoc;
use App\Modules\Inventory\Models\InventoryCountItem;
use App\Modules\Inventory\Models\Warehouse;
use App\Modules\Inventory\Models\Product;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

class CountService
{
    /**
     * 建立新的盤點單並執行快照
     */
    public function createDoc(string $warehouseId, string $remarks = null, int $userId): InventoryCountDoc
    {
        return DB::transaction(function () use ($warehouseId, $remarks, $userId) {
            $doc = InventoryCountDoc::create([
                'warehouse_id' => $warehouseId,
                'status' => 'counting',
                'snapshot_date' => now(),
                'remarks' => $remarks,
                'created_by' => $userId,
            ]);

            return $doc;
        });
    }

    /**
     * 執行快照：鎖定當前庫存量
     */
    public function snapshot(InventoryCountDoc $doc, bool $updateDoc = true): void
    {
        DB::transaction(function () use ($doc, $updateDoc) {
            // 清除舊的 items (如果有)
            $doc->items()->delete();

            // 取得該倉庫所有庫存 (包含 quantity = 0 但未軟刪除的)
            // 這裡可以根據需求決定是否要過濾掉 0 庫存，通常盤點單會希望能看到所有 "帳上有紀錄" 的東西
            $inventories = Inventory::where('warehouse_id', $doc->warehouse_id)
                ->whereNull('deleted_at') 
                ->get();

            $items = [];
            foreach ($inventories as $inv) {
                $items[] = [
                    'count_doc_id' => $doc->id,
                    'product_id' => $inv->product_id,
                    'batch_number' => $inv->batch_number,
                    'system_qty' => $inv->quantity,
                    'counted_qty' => null, // 預設未盤點
                    'diff_qty' => 0,
                    'created_at' => now(),
                    'updated_at' => now(),
                ];
            }

            if (!empty($items)) {
                InventoryCountItem::insert($items);
            }

            if ($updateDoc) {
                $doc->update([
                    'status' => 'counting',
                    'snapshot_date' => now(),
                ]);
            }
        });
    }

    /**
     * 完成盤點：過帳差異
     */
    public function complete(InventoryCountDoc $doc, int $userId): void
    {
        DB::transaction(function () use ($doc, $userId) {
            // 僅更新單據狀態為「已完成」，不執行庫存入庫/調整
            // 盤點單僅作為記錄，後續調整由盤調單 (AdjustDoc) 執行
            $doc->update([
                'status' => 'completed',
                'completed_at' => now(),
                'completed_by' => $userId,
            ]);
        });
    }

    /**
     * 更新盤點數量
     */
    public function updateCount(InventoryCountDoc $doc, array $itemsData): void
    {
        DB::transaction(function () use ($doc, $itemsData) {
            $updatedItems = [];
            $hasChanges = false;
            $oldDocAttributes = [
                'status' => $doc->status,
                'completed_at' => $doc->completed_at ? $doc->completed_at->format('Y-m-d H:i:s') : null,
                'completed_by' => $doc->completed_by,
            ];

            foreach ($itemsData as $data) {
                $item = $doc->items()->with('product')->find($data['id']);
                if ($item) {
                    $oldQty = $item->counted_qty;
                    $newQty = $data['counted_qty'];
                    $oldNotes = $item->notes;
                    $newNotes = $data['notes'] ?? $item->notes;
                    
                    $isQtyChanged = $oldQty != $newQty;
                    $isNotesChanged = $oldNotes !== $newNotes;

                    if ($isQtyChanged || $isNotesChanged) {
                        $updatedItems[] = [
                            'product_name' => $item->product->name,
                            'old' => [
                                'counted_qty' => $oldQty,
                                'notes' => $oldNotes,
                            ],
                            'new' => [
                                'counted_qty' => $newQty,
                                'notes' => $newNotes,
                            ]
                        ];

                        $countedQty = $data['counted_qty'];
                        $diff = is_numeric($countedQty) ? ($countedQty - $item->system_qty) : 0;
                        
                        $item->update([
                            'counted_qty' => $countedQty,
                            'diff_qty' => $diff,
                            'notes' => $newNotes,
                        ]);
                        $hasChanges = true;
                    }
                }
            }

            // 檢查是否完成
            $doc->refresh();
            $isAllCounted = $doc->items()->whereNull('counted_qty')->count() === 0;
            $newDocAttributesLog = [];

            if ($isAllCounted) {
                // 檢查是否有任何差異
                $hasDiff = $doc->items()->where('diff_qty', '!=', 0)->exists();
                $targetStatus = $hasDiff ? 'completed' : 'no_adjust';

                if ($doc->status !== $targetStatus) {
                    $doc->status = $targetStatus;
                    $doc->completed_at = now();
                    $doc->completed_by = auth()->id();
                    $doc->saveQuietly();
                    
                    $doc->refresh();
                    
                    $newDocAttributesLog = [
                        'status' => $targetStatus,
                        'completed_at' => $doc->completed_at->format('Y-m-d H:i:s'),
                        'completed_by' => $doc->completed_by,
                    ];
                    $hasChanges = true;
                }
            } else {
                if ($doc->status === 'completed') {
                    $doc->status = 'counting';
                    $doc->completed_at = null;
                    $doc->completed_by = null;
                    $doc->saveQuietly();

                    $newDocAttributesLog = [
                        'status' => 'counting',
                        'completed_at' => null,
                        'completed_by' => null,
                    ];
                    $hasChanges = true;
                }
            }

            // 記錄操作日誌
            if ($hasChanges) {
                $properties = [
                    'items_diff' => [
                        'added' => [],
                        'removed' => [],
                        'updated' => $updatedItems,
                    ],
                ];

                // 如果有文件層級的屬性變更 (狀態)，併入 log
                if (!empty($newDocAttributesLog)) {
                    $properties['attributes'] = $newDocAttributesLog;
                    $properties['old'] = array_intersect_key($oldDocAttributes, $newDocAttributesLog);
                }

                activity()
                    ->performedOn($doc)
                    ->causedBy(auth()->user())
                    ->event('updated')
                    ->withProperties($properties)
                    ->log('updated');
            }
        });
    }
}
