<?php

namespace App\Services;

use App\Models\InventoryTransaction;
use App\Models\Inventory;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class InventoryTransactionService
{
    /**
     * Create an "In" transaction
     */
    public static function createInTransaction($inventory, $quantity, $data = [])
    {
        return InventoryTransaction::create([
            'inventory_id' => $inventory->id ?? $inventory,
            'type' => 'in',
            'quantity' => $quantity,
            'unit_price' => $data['unit_price'] ?? ($inventory->unit_price ?? 0),
            'reference_type' => $data['reference_type'] ?? 'addition',
            'reference_id' => $data['reference_id'] ?? null,
            'batch_id' => $data['batch_id'] ?? null,
            'branch_id' => $data['branch_id'] ?? ($inventory->branch_id ?? null),
            'restaurant_id' => $data['restaurant_id'] ?? ($inventory->restaurant_id ?? null),
            'notes' => $data['notes'] ?? null,
            'created_by' => $data['created_by'] ?? auth()->id(),
        ]);
    }

    /**
     * Create an "Out" transaction
     */
    public static function createOutTransaction($inventory, $quantity, $data = [])
    {
        return InventoryTransaction::create([
            'inventory_id' => $inventory->id ?? $inventory,
            'type' => 'out',
            'quantity' => $quantity,
            'unit_price' => $data['unit_price'] ?? ($inventory->unit_price ?? 0),
            'reference_type' => $data['reference_type'] ?? 'transfer',
            'reference_id' => $data['reference_id'] ?? null,
            'batch_id' => $data['batch_id'] ?? null,
            'branch_id' => $data['branch_id'] ?? ($inventory->branch_id ?? null),
            'restaurant_id' => $data['restaurant_id'] ?? ($inventory->restaurant_id ?? null),
            'notes' => $data['notes'] ?? null,
            'created_by' => $data['created_by'] ?? auth()->id(),
        ]);
    }

    /**
     * Record inventory addition (when new inventory is added)
     */
    public static function recordInventoryAddition($inventory, $quantity, $user = null, $notes = null)
    {
        try {
            $transaction = self::createInTransaction($inventory, $quantity, [
                'reference_type' => 'addition',
                'reference_id' => $inventory->id,
                'batch_id' => $inventory->batch_id ?? null,
                'branch_id' => $inventory->branch_id,
                'restaurant_id' => $inventory->restaurant_id,
                'unit_price' => $inventory->unit_price,
                'notes' => $notes ?? "Inventory addition for {$inventory->item_name}",
                'created_by' => $user ? $user->id : auth()->id(),
            ]);

            // Update last_transaction_at
            $inventory->update(['last_transaction_at' => now()]);

            return $transaction;
        } catch (\Exception $e) {
            Log::error("Failed to record inventory addition: " . $e->getMessage());
            throw $e;
        }
    }

    /**
     * Record inventory update (when quantity changes)
     */
    public static function recordInventoryUpdate($inventory, $oldQuantity, $newQuantity, $user = null, $notes = null)
    {
        try {
            $difference = $newQuantity - $oldQuantity;

            if ($difference > 0) {
                // Quantity increased - create "In" transaction
                return self::createInTransaction($inventory, abs($difference), [
                    'reference_type' => 'adjustment',
                    'reference_id' => $inventory->id,
                    'batch_id' => $inventory->batch_id ?? null,
                    'branch_id' => $inventory->branch_id,
                    'restaurant_id' => $inventory->restaurant_id,
                    'unit_price' => $inventory->unit_price,
                    'notes' => $notes ?? "Inventory adjustment (increase) for {$inventory->item_name}",
                    'created_by' => $user ? $user->id : auth()->id(),
                ]);
            } elseif ($difference < 0) {
                // Quantity decreased - create "Out" transaction
                return self::createOutTransaction($inventory, abs($difference), [
                    'reference_type' => 'adjustment',
                    'reference_id' => $inventory->id,
                    'batch_id' => $inventory->batch_id ?? null,
                    'branch_id' => $inventory->branch_id,
                    'restaurant_id' => $inventory->restaurant_id,
                    'unit_price' => $inventory->unit_price,
                    'notes' => $notes ?? "Inventory adjustment (decrease) for {$inventory->item_name}",
                    'created_by' => $user ? $user->id : auth()->id(),
                ]);
            }

            // No change
            return null;
        } catch (\Exception $e) {
            Log::error("Failed to record inventory update: " . $e->getMessage());
            throw $e;
        }
    }

    /**
     * Record transfer (when inventory is transferred to branch)
     */
    public static function recordTransfer($inventory, $stockOut, $user = null)
    {
        try {
            // Create "Out" transaction for source inventory
            $outTransaction = self::createOutTransaction($inventory, $stockOut->quantity_transferred, [
                'reference_type' => 'transfer',
                'reference_id' => $stockOut->id,
                'batch_id' => $inventory->batch_id ?? null,
                'branch_id' => $inventory->branch_id,
                'restaurant_id' => $inventory->restaurant_id,
                'unit_price' => $inventory->unit_price,
                'notes' => "Transfer to branch {$stockOut->branch_id} - Stock Out #{$stockOut->id}",
                'created_by' => $user ? $user->id : auth()->id(),
            ]);

            // Optionally create "In" transaction for destination branch if tracking branch inventory
            // This depends on your business logic - whether you track inventory per branch separately
            // For now, we'll only record the "Out" transaction

            // Update last_transaction_at
            $inventory->update(['last_transaction_at' => now()]);

            return $outTransaction;
        } catch (\Exception $e) {
            Log::error("Failed to record transfer: " . $e->getMessage());
            throw $e;
        }
    }

    /**
     * Record supplier bill transaction (when inventory is added from supplier)
     */
    public static function recordSupplierBillTransaction($inventory, $supplierBill, $quantity, $unitPrice, $user = null)
    {
        try {
            return self::createInTransaction($inventory, $quantity, [
                'reference_type' => 'supplier_bill',
                'reference_id' => $supplierBill->id,
                'batch_id' => $supplierBill->batch_id,
                'branch_id' => $inventory->branch_id,
                'restaurant_id' => $inventory->restaurant_id,
                'unit_price' => $unitPrice,
                'notes' => "Supplier bill #{$supplierBill->bill_number} from {$supplierBill->supplier->name}",
                'created_by' => $user ? $user->id : auth()->id(),
            ]);
        } catch (\Exception $e) {
            Log::error("Failed to record supplier bill transaction: " . $e->getMessage());
            throw $e;
        }
    }

    /**
     * Record return (when inventory is returned to original source branch)
     */
    public static function recordReturn($currentInventory, $returnStockOut, $originalStockOut, $sourceInventory, $user = null)
    {
        try {
            // Create "Out" transaction for current branch (where return happens)
            $outTransaction = self::createOutTransaction($currentInventory, $returnStockOut->quantity_transferred, [
                'reference_type' => 'return',
                'reference_id' => $returnStockOut->id,
                'batch_id' => $currentInventory->batch_id ?? null,
                'branch_id' => $currentInventory->branch_id,
                'restaurant_id' => $currentInventory->restaurant_id,
                'unit_price' => $currentInventory->unit_price,
                'notes' => "Return to source branch - Return #{$returnStockOut->id}, Original Transfer #{$originalStockOut->id}. Reason: " . ($returnStockOut->return_reason ?? 'No reason'),
                'created_by' => $user ? $user->id : auth()->id(),
            ]);

            // Create "In" transaction for source branch (where inventory is returned to)
            $inTransaction = self::createInTransaction($sourceInventory, $returnStockOut->quantity_transferred, [
                'reference_type' => 'return',
                'reference_id' => $returnStockOut->id,
                'batch_id' => $sourceInventory->batch_id ?? null,
                'branch_id' => $sourceInventory->branch_id,
                'restaurant_id' => $sourceInventory->restaurant_id,
                'unit_price' => $sourceInventory->unit_price,
                'notes' => "Return from branch - Return #{$returnStockOut->id}, Original Transfer #{$originalStockOut->id}. Reason: " . ($returnStockOut->return_reason ?? 'No reason'),
                'created_by' => $user ? $user->id : auth()->id(),
            ]);

            // Update last_transaction_at for both inventories
            $currentInventory->update(['last_transaction_at' => now()]);
            $sourceInventory->update(['last_transaction_at' => now()]);

            return [
                'out_transaction' => $outTransaction,
                'in_transaction' => $inTransaction,
            ];
        } catch (\Exception $e) {
            Log::error("Failed to record return: " . $e->getMessage());
            throw $e;
        }
    }
}

