<?php

namespace App\Traits\Restock;

use App\Models\Bottle;
use App\Models\Perfume;
use App\Models\Product;
use App\Models\Restock;
use App\Services\StockActivityLogService;

trait WithRestockStock
{
    public function transferStockFromWarehouseToOutlet($warehouse, $outlet, $item): void
    {
        $quantity = $item->quantity;

        switch ($item->restockable_type) {
            case Perfume::class:
                $relation = 'perfumes';
                break;
            case Product::class:
                $relation = 'products';
                break;
            case Bottle::class:
                $relation = 'bottles';
                break;
            default:
                return;
        }

        // Decrease warehouse stock
        $warehouseItem = $warehouse->{$relation}()
            ->where("{$relation}.id", $item->restockable_id)
            ->lockForUpdate()
            ->withPivot('stock')
            ->first();

        $warehousePreviousStock = 0;

        if ($warehouseItem) {
            $warehousePreviousStock = $warehouseItem->pivot->stock ?? 0;
        }

        if ($warehousePreviousStock < $quantity) {
            throw new \Exception("Stok {$item->restockable->name} di gudang tidak mencukupi. Tersisa {$warehousePreviousStock}, diminta {$quantity}.");
        }

        $warehouseNewStock = $warehousePreviousStock - $quantity;

        $warehouse->{$relation}()->updateExistingPivot($item->restockable_id, [
            'stock' => $warehouseNewStock,
        ]);

        // Increase outlet stock
        $outletItem = $outlet->{$relation}()
            ->where("{$relation}.id", $item->restockable_id)
            ->lockForUpdate()
            ->withPivot('stock')
            ->first();

        if ($outletItem) {
            $outletPreviousStock = $outletItem->pivot->stock ?? 0;
            $outlet->{$relation}()->updateExistingPivot($item->restockable_id, [
                'stock' => $outletPreviousStock + $quantity,
            ]);
        } else {
            $outletPreviousStock = 0;
            $outlet->{$relation}()->attach($item->restockable_id, [
                'stock' => $quantity,
            ]);
        }
        $outletNewStock = $outletPreviousStock + $quantity;

        $restock = $item->restock ?? Restock::find($item->restock_id);

        if ($restock) {
            StockActivityLogService::distribution(
                restock: $restock,
                product: $item->restockable,
                quantity: $quantity,
                warehousePreviousStock: $warehousePreviousStock,
                warehouseNewStock: $warehouseNewStock,
                outletPreviousStock: $outletPreviousStock,
                outletNewStock: $outletNewStock
            );
        }
    }

    public function reverseStockTransfer($warehouse, $outlet, $item): void
    {
        $quantity = $item->quantity;

        switch ($item->restockable_type) {
            case Perfume::class:
                $relation = 'perfumes';
                break;
            case Product::class:
                $relation = 'products';
                break;
            case Bottle::class:
                $relation = 'bottles';
                break;
            default:
                return;
        }

        // Return items to Warehouse
        $warehousePivot = $warehouse->{$relation}()
            ->where("{$relation}.id", $item->restockable_id)
            ->first();

        $currentWarehouseStock = $warehousePivot?->pivot?->stock ?? 0;
        $newWarehouseStock = $currentWarehouseStock + $quantity;

        if ($warehousePivot) {
            $warehouse->{$relation}()->updateExistingPivot($item->restockable_id, [
                'stock' => $newWarehouseStock,
            ]);
        } else {
            $warehouse->{$relation}()->attach($item->restockable_id, [
                'stock' => $quantity,
            ]);
        }

        $restock = $item->restock ?? Restock::find($item->restock_id);

        if ($restock) {
            StockActivityLogService::logWarehouse(
                logName: StockActivityLogService::LOG_DISTRIBUTION,
                event: 'increase',
                description: "Restock #{$restock->hash_id} Deleted: Returned {$quantity} stock to Warehouse.",
                performedOn: $item->restockable,
                warehouse: $warehouse,
                quantityChange: $quantity,
                previousStock: $currentWarehouseStock,
                newStock: $newWarehouseStock,
                extraProperties: ['restock_id' => $restock->id]
            );
        }

        // Remove items from Outlet
        $outletPivot = $outlet->{$relation}()
            ->where("{$relation}.id", $item->restockable_id)
            ->first();

        $currentOutletStock = $outletPivot?->pivot?->stock ?? 0;
        $newOutletStock = max(0, $currentOutletStock - $quantity);

        if ($outletPivot) {
            $outlet->{$relation}()->updateExistingPivot($item->restockable_id, [
                'stock' => $newOutletStock,
            ]);
        }

        if ($restock) {
            StockActivityLogService::logOutlet(
                logName: StockActivityLogService::LOG_DISTRIBUTION,
                event: 'decrease',
                description: "Restock #{$restock->hash_id} Deleted: Removed {$quantity} stock from Outlet.",
                performedOn: $item->restockable,
                outlet: $outlet,
                quantityChange: -1 * abs($quantity),
                previousStock: $currentOutletStock,
                newStock: $newOutletStock,
                extraProperties: ['restock_id' => $restock->id]
            );
        }
    }
}
