<?php

namespace App\Http\Controllers;

use App\Models\InventoryStock;
use App\Models\InventoryItem;
use App\Models\Warehouse;
use App\Models\InventoryTransaction;
use App\Models\Company;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;

class InventoryStockController extends Controller
{
    /**
     * إعادة حساب أرصدة المخزون بناءً على المعاملات
     *
     * @return \Illuminate\Http\RedirectResponse
     */
    public function recalculateInventory()
    {
        $companyId = auth()->user()->company_id;

        DB::beginTransaction();

        try {
            // إعادة تعيين جميع أرصدة المخزون إلى صفر
            InventoryStock::where('company_id', $companyId)->update([
                'quantity' => 0,
                'reserved_quantity' => 0
            ]);

            // الحصول على جميع معاملات المخزون مرتبة حسب التاريخ
            $transactions = InventoryTransaction::where('company_id', $companyId)
                ->orderBy('created_at')
                ->get();

            // إعادة تطبيق كل معاملة
            foreach ($transactions as $transaction) {
                $itemId = $transaction->item_id;
                $warehouseId = $transaction->warehouse_id;
                $quantity = $transaction->quantity;

                $stock = InventoryStock::firstOrNew([
                    'company_id' => $companyId,
                    'warehouse_id' => $warehouseId,
                    'item_id' => $itemId,
                ]);

                if (!$stock->exists) {
                    $stock->quantity = 0;
                    $stock->reserved_quantity = 0;
                }

                // تحديث الكمية بناءً على نوع المعاملة
                switch ($transaction->transaction_type) {
                    case 'purchase':
                    case 'return_from_customer':
                    case 'adjustment':
                        $stock->quantity += $quantity;
                        break;
                    case 'sale':
                    case 'return_to_supplier':
                    case 'maintenance_usage':
                    case 'write_off':
                        $stock->quantity -= abs($quantity);
                        break;
                    case 'transfer':
                        // معالجة خاصة للتحويلات
                        if ($transaction->to_warehouse_id) {
                            $stock->quantity -= abs($quantity);

                            $toStock = InventoryStock::firstOrNew([
                                'company_id' => $companyId,
                                'warehouse_id' => $transaction->to_warehouse_id,
                                'item_id' => $itemId,
                            ]);

                            if (!$toStock->exists) {
                                $toStock->quantity = 0;
                                $toStock->reserved_quantity = 0;
                            }

                            $toStock->quantity += $quantity;
                            $toStock->save();
                        }
                        break;
                }

                $stock->save();
            }

            DB::commit();

            return redirect()->route('inventory.stock.index')
                ->with('success', 'تم إعادة حساب أرصدة المخزون بنجاح');
        } catch (\Exception $e) {
            DB::rollBack();

            return redirect()->back()
                ->with('error', 'حدث خطأ أثناء إعادة حساب أرصدة المخزون: ' . $e->getMessage());
        }
    }
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $user = Auth::user();
        $company = $user->company;

        $warehouses = Warehouse::where('company_id', $company->id)
            ->where('is_active', true)
            ->orderBy('name')
            ->get();

        $selectedWarehouse = null;
        $warehouseId = $request->input('warehouse_id');

        if ($warehouseId) {
            $selectedWarehouse = Warehouse::where('company_id', $company->id)
                ->where('id', $warehouseId)
                ->first();
        }

        $query = InventoryStock::where('company_id', $company->id)
            ->with(['item.category', 'warehouse']);

        if ($selectedWarehouse) {
            $query->where('warehouse_id', $selectedWarehouse->id);
        }

        $categoryId = $request->input('category_id');
        if ($categoryId) {
            $query->whereHas('item', function ($q) use ($categoryId) {
                $q->where('category_id', $categoryId);
            });
        }

        $search = $request->input('search');
        if ($search) {
            $query->whereHas('item', function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                    ->orWhere('sku', 'like', "%{$search}%")
                    ->orWhere('barcode', 'like', "%{$search}%");
            });
        }

        $stocks = $query->orderBy('id')->get();

        return view('inventory.stock.index', compact('stocks', 'warehouses', 'selectedWarehouse'));
    }

    /**
     * Show the form for adjusting stock.
     *
     * @return \Illuminate\Http\Response
     */
    public function adjustForm()
    {
        $user = Auth::user();
        $company = $user->company;

        $warehouses = Warehouse::where('company_id', $company->id)
            ->where('is_active', true)
            ->orderBy('name')
            ->get();

        $items = InventoryItem::where('company_id', $company->id)
            ->where('is_active', true)
            ->orderBy('name')
            ->get();

        return view('inventory.stock.adjust', compact('warehouses', 'items'));
    }

    /**
     * Adjust stock quantity.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function adjust(Request $request)
    {
        $user = Auth::user();
        $company = $user->company;

        $validator = Validator::make($request->all(), [
            'warehouse_id' => 'required|exists:warehouses,id',
            'item_id' => 'required|exists:inventory_items,id',
            'adjustment_type' => 'required|in:add,subtract,set',
            'quantity' => 'required|numeric|min:0',
            'reason' => 'required|string',
            'notes' => 'nullable|string',
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                ->withErrors($validator)
                ->withInput();
        }

        // Get the stock record
        $stock = InventoryStock::where('company_id', $company->id)
            ->where('warehouse_id', $request->warehouse_id)
            ->where('item_id', $request->item_id)
            ->first();

        if (!$stock) {
            // Create new stock record if it doesn't exist
            $stock = new InventoryStock();
            $stock->company_id = $company->id;
            $stock->warehouse_id = $request->warehouse_id;
            $stock->item_id = $request->item_id;
            $stock->quantity = 0;
            $stock->reserved_quantity = 0;
            $stock->save();
        }

        // Calculate new quantity based on adjustment type
        $oldQuantity = $stock->quantity;
        $newQuantity = $oldQuantity;

        switch ($request->adjustment_type) {
            case 'add':
                $newQuantity = $oldQuantity + $request->quantity;
                $transactionQuantity = $request->quantity;
                break;
            case 'subtract':
                $newQuantity = max(0, $oldQuantity - $request->quantity);
                $transactionQuantity = -$request->quantity;
                break;
            case 'set':
                $newQuantity = $request->quantity;
                $transactionQuantity = $request->quantity - $oldQuantity;
                break;
        }

        // Begin transaction
        DB::beginTransaction();

        try {
            // Update stock quantity
            $stock->quantity = $newQuantity;
            $stock->save();

            // Create inventory transaction
            $transaction = new InventoryTransaction();
            $transaction->company_id = $company->id;
            $transaction->transaction_type = 'adjustment';
            $transaction->item_id = $request->item_id;
            $transaction->warehouse_id = $request->warehouse_id;
            $transaction->quantity = $transactionQuantity;
            $transaction->reference_number = 'ADJ-' . time();
            $transaction->reference_type = 'manual_adjustment';
            $transaction->created_by = $user->id;
            $transaction->notes = $request->reason . ' - ' . $request->notes;
            $transaction->save();

            DB::commit();

            return redirect()->route('inventory.stock.index')
                ->with('success', 'تم تعديل المخزون بنجاح');
        } catch (\Exception $e) {
            DB::rollBack();

            return redirect()->back()
                ->with('error', 'حدث خطأ أثناء تعديل المخزون: ' . $e->getMessage())
                ->withInput();
        }
    }

    /**
     * Show the form for transferring stock.
     *
     * @return \Illuminate\Http\Response
     */
    public function transferForm()
    {
        $user = Auth::user();
        $company = $user->company;

        $warehouses = Warehouse::where('company_id', $company->id)
            ->where('is_active', true)
            ->orderBy('name')
            ->get();

        $items = InventoryItem::where('company_id', $company->id)
            ->where('is_active', true)
            ->orderBy('name')
            ->get();

        return view('inventory.stock.transfer', compact('warehouses', 'items'));
    }

    /**
     * Transfer stock between warehouses.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function transfer(Request $request)
    {
        $user = Auth::user();
        $company = $user->company;

        $validator = Validator::make($request->all(), [
            'from_warehouse_id' => 'required|exists:warehouses,id',
            'to_warehouse_id' => 'required|exists:warehouses,id|different:from_warehouse_id',
            'item_id' => 'required|exists:inventory_items,id',
            'quantity' => 'required|numeric|min:0.01',
            'notes' => 'nullable|string',
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                ->withErrors($validator)
                ->withInput();
        }

        // Get the source stock record
        $sourceStock = InventoryStock::where('company_id', $company->id)
            ->where('warehouse_id', $request->from_warehouse_id)
            ->where('item_id', $request->item_id)
            ->first();

        if (!$sourceStock || $sourceStock->quantity < $request->quantity) {
            return redirect()->back()
                ->with('error', 'الكمية المطلوبة غير متوفرة في المستودع المصدر')
                ->withInput();
        }

        // Get or create the destination stock record
        $destStock = InventoryStock::where('company_id', $company->id)
            ->where('warehouse_id', $request->to_warehouse_id)
            ->where('item_id', $request->item_id)
            ->first();

        if (!$destStock) {
            $destStock = new InventoryStock();
            $destStock->company_id = $company->id;
            $destStock->warehouse_id = $request->to_warehouse_id;
            $destStock->item_id = $request->item_id;
            $destStock->quantity = 0;
            $destStock->reserved_quantity = 0;
        }

        // Begin transaction
        DB::beginTransaction();

        try {
            // Update source stock
            $sourceStock->quantity -= $request->quantity;
            $sourceStock->save();

            // Update destination stock
            $destStock->quantity += $request->quantity;
            $destStock->save();

            // Create inventory transaction
            $transaction = new InventoryTransaction();
            $transaction->company_id = $company->id;
            $transaction->transaction_type = 'transfer';
            $transaction->item_id = $request->item_id;
            $transaction->warehouse_id = $request->from_warehouse_id;
            $transaction->to_warehouse_id = $request->to_warehouse_id;
            $transaction->quantity = $request->quantity;
            $transaction->reference_number = 'TRF-' . time();
            $transaction->reference_type = 'manual_transfer';
            $transaction->created_by = $user->id;
            $transaction->notes = $request->notes;
            $transaction->save();

            DB::commit();

            return redirect()->route('inventory.stock.index')
                ->with('success', 'تم نقل المخزون بنجاح');
        } catch (\Exception $e) {
            DB::rollBack();

            return redirect()->back()
                ->with('error', 'حدث خطأ أثناء نقل المخزون: ' . $e->getMessage())
                ->withInput();
        }
    }
}
