<?php

namespace App\Traits\Order;

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

trait WithUpdateStock
{
    public function increaseOutletStock($outlet, $item): void
    {
        $quantity = $item->quantity;

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

        $existing = $outlet->{$relation}()
            ->withPivot('stock')
            ->where("{$relation}.id", $item->orderable_id)
            ->lockForUpdate()
            ->first();

        if ($existing) {
            $currentStock = $existing->pivot->stock ?? 0;
            $outlet->{$relation}()->updateExistingPivot($item->orderable_id, [
                'stock' => $currentStock + $quantity,
            ]);
        } else {
            $currentStock = 0;
            $outlet->{$relation}()->attach($item->orderable_id, [
                'stock' => $quantity,
            ]);
        }
        $newStock = $currentStock + $quantity;

        StockActivityLogService::logOutlet(
            logName: StockActivityLogService::LOG_SALE,
            event: 'increase',
            description: 'Stok '.$item->orderable->name.' di '.$outlet->name.' bertambah '.formatCurrencyNumber($quantity).' (Pembatalan/Edit Order)',
            performedOn: $item->orderable,
            outlet: $outlet,
            quantityChange: abs($quantity),
            previousStock: $currentStock,
            newStock: $newStock,
            extraProperties: [
                'orderable_id' => $item->orderable_id,
                'orderable_type' => $item->orderable_type,
                'order_id' => $item->order_id ?? null,
            ]
        );
    }

    public function decreaseOutletStock($outlet, $item)
    {
        $quantity = $item->quantity;

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

        $existing = $outlet->{$relation}()
            ->withPivot('stock')
            ->where("{$relation}.id", $item->orderable_id)
            ->lockForUpdate()
            ->first();

        if (! $existing) {
            return ['status' => false, 'message' => "Produk {$item->orderable->name} tidak ditemukan di {$outlet->name}."];
        }

        $currentStock = $existing->pivot->stock ?? 0;

        if ($currentStock < $quantity) {
            return ['status' => false, 'message' => "Stok produk {$item->orderable->name} tidak mencukupi. Tersisa {$currentStock}, diminta {$quantity}. Silakan hubungi Administrator."];
        }

        $newStock = $currentStock - $quantity;

        $outlet->{$relation}()->updateExistingPivot($item->orderable_id, [
            'stock' => $newStock,
        ]);

        $order = $item->order ?? \App\Models\Order::find($item->order_id);

        if ($order) {
            StockActivityLogService::sale(
                order: $order,
                product: $item->orderable,
                quantity: $quantity,
                previousStock: $currentStock,
                newStock: $newStock
            );
        } else {
            StockActivityLogService::logOutlet(
                logName: StockActivityLogService::LOG_SALE,
                event: 'decrease',
                description: 'Stok '.$item->orderable->name.' di '.$outlet->name.' berkurang '.formatCurrencyNumber($quantity),
                performedOn: $item->orderable,
                outlet: $outlet,
                quantityChange: -1 * abs($quantity),
                previousStock: $currentStock,
                newStock: $newStock,
                extraProperties: [
                    'orderable_id' => $item->orderable_id,
                    'orderable_type' => $item->orderable_type,
                    'order_id' => $item->order_id ?? null,
                ]
            );
        }

        return ['status' => true];
    }
}
