<?php

namespace App\Http\Controllers;

use App\Models\InventoryBatch;
use App\Models\InventoryItem;
use App\Models\Warehouse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class InventoryBatchController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $companyId = auth()->user()->company_id;

        $batches = InventoryBatch::whereHas('item', function ($query) use ($companyId) {
            $query->where('company_id', $companyId);
        })
            ->with(['item', 'warehouse'])
            ->orderBy('expiry_date')
            ->paginate(15);

        return view('inventory.batches.index', compact('batches'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        $companyId = auth()->user()->company_id;
        $items = InventoryItem::where('company_id', $companyId)
            ->where('track_batches', true)
            ->orderBy('name')
            ->get();
        $warehouses = Warehouse::where('company_id', $companyId)
            ->orderBy('name')
            ->get();

        return view('inventory.batches.create', compact('items', 'warehouses'));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $request->validate([
            'item_id' => 'required|exists:inventory_items,id',
            'warehouse_id' => 'required|exists:warehouses,id',
            'batch_number' => 'required|string|max:255',
            'quantity' => 'required|numeric|min:0.01',
            'production_date' => 'nullable|date',
            'expiry_date' => 'nullable|date|after_or_equal:production_date',
            'notes' => 'nullable|string',
        ]);

        // التحقق من أن العنصر والمستودع ينتميان للشركة الحالية
        $item = InventoryItem::findOrFail($request->item_id);
        $warehouse = Warehouse::findOrFail($request->warehouse_id);

        if ($item->company_id != auth()->user()->company_id || $warehouse->company_id != auth()->user()->company_id) {
            return redirect()->back()->with('error', 'لا يمكنك إضافة دفعة لعنصر أو مستودع لا ينتمي لشركتك');
        }

        // التحقق من أن العنصر يتتبع الدفعات
        if (!$item->track_batches) {
            return redirect()->back()->with('error', 'هذا العنصر لا يتتبع الدفعات');
        }

        // التحقق من عدم وجود دفعة بنفس الرقم لنفس العنصر في نفس المستودع
        $existingBatch = InventoryBatch::where('item_id', $request->item_id)
            ->where('warehouse_id', $request->warehouse_id)
            ->where('batch_number', $request->batch_number)
            ->exists();

        if ($existingBatch) {
            return redirect()->back()->with('error', 'توجد دفعة بنفس الرقم لهذا العنصر في هذا المستودع');
        }

        DB::beginTransaction();

        try {
            // إنشاء الدفعة
            $batch = new InventoryBatch();
            $batch->item_id = $request->item_id;
            $batch->warehouse_id = $request->warehouse_id;
            $batch->batch_number = $request->batch_number;
            $batch->quantity = $request->quantity;
            $batch->production_date = $request->production_date;
            $batch->expiry_date = $request->expiry_date;
            $batch->notes = $request->notes;
            $batch->created_by = Auth::id();
            $batch->save();

            // تحديث مخزون العنصر في المستودع
            $this->updateItemStock($item->id, $warehouse->id, $request->quantity);

            // إنشاء حركة مخزون
            $this->createInventoryTransaction($item->id, $warehouse->id, $request->quantity, 'batch_added', $batch->id);

            DB::commit();

            return redirect()->route('inventory-batches.index')
                ->with('success', 'تم إضافة الدفعة بنجاح');
        } catch (\Exception $e) {
            DB::rollBack();
            return redirect()->back()->with('error', 'حدث خطأ أثناء إضافة الدفعة: ' . $e->getMessage());
        }
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\InventoryBatch  $inventoryBatch
     * @return \Illuminate\Http\Response
     */
    public function show(InventoryBatch $inventoryBatch)
    {
        // التحقق من أن الدفعة تنتمي للشركة الحالية
        if ($inventoryBatch->item->company_id != auth()->user()->company_id) {
            return redirect()->route('inventory-batches.index')
                ->with('error', 'لا يمكنك عرض دفعة لا تنتمي لشركتك');
        }

        $inventoryBatch->load(['item', 'warehouse', 'createdBy']);

        // الحصول على حركات المخزون المرتبطة بهذه الدفعة
        $transactions = \App\Models\InventoryTransaction::where('batch_id', $inventoryBatch->id)
            ->with(['createdBy'])
            ->orderBy('created_at', 'desc')
            ->get();

        return view('inventory.batches.show', compact('inventoryBatch', 'transactions'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\InventoryBatch  $inventoryBatch
     * @return \Illuminate\Http\Response
     */
    public function edit(InventoryBatch $inventoryBatch)
    {
        // التحقق من أن الدفعة تنتمي للشركة الحالية
        if ($inventoryBatch->item->company_id != auth()->user()->company_id) {
            return redirect()->route('inventory-batches.index')
                ->with('error', 'لا يمكنك تعديل دفعة لا تنتمي لشركتك');
        }

        $companyId = auth()->user()->company_id;
        $items = InventoryItem::where('company_id', $companyId)
            ->where('track_batches', true)
            ->orderBy('name')
            ->get();
        $warehouses = Warehouse::where('company_id', $companyId)
            ->orderBy('name')
            ->get();

        return view('inventory.batches.edit', compact('inventoryBatch', 'items', 'warehouses'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\InventoryBatch  $inventoryBatch
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, InventoryBatch $inventoryBatch)
    {
        // التحقق من أن الدفعة تنتمي للشركة الحالية
        if ($inventoryBatch->item->company_id != auth()->user()->company_id) {
            return redirect()->route('inventory-batches.index')
                ->with('error', 'لا يمكنك تعديل دفعة لا تنتمي لشركتك');
        }

        $request->validate([
            'batch_number' => 'required|string|max:255',
            'production_date' => 'nullable|date',
            'expiry_date' => 'nullable|date|after_or_equal:production_date',
            'notes' => 'nullable|string',
        ]);

        // التحقق من عدم وجود دفعة أخرى بنفس الرقم لنفس العنصر في نفس المستودع
        $existingBatch = InventoryBatch::where('item_id', $inventoryBatch->item_id)
            ->where('warehouse_id', $inventoryBatch->warehouse_id)
            ->where('batch_number', $request->batch_number)
            ->where('id', '!=', $inventoryBatch->id)
            ->exists();

        if ($existingBatch) {
            return redirect()->back()->with('error', 'توجد دفعة أخرى بنفس الرقم لهذا العنصر في هذا المستودع');
        }

        $inventoryBatch->batch_number = $request->batch_number;
        $inventoryBatch->production_date = $request->production_date;
        $inventoryBatch->expiry_date = $request->expiry_date;
        $inventoryBatch->notes = $request->notes;
        $inventoryBatch->save();

        return redirect()->route('inventory-batches.index')
            ->with('success', 'تم تحديث الدفعة بنجاح');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\InventoryBatch  $inventoryBatch
     * @return \Illuminate\Http\Response
     */
    public function destroy(InventoryBatch $inventoryBatch)
    {
        // التحقق من أن الدفعة تنتمي للشركة الحالية
        if ($inventoryBatch->item->company_id != auth()->user()->company_id) {
            return redirect()->route('inventory-batches.index')
                ->with('error', 'لا يمكنك حذف دفعة لا تنتمي لشركتك');
        }

        // التحقق من عدم وجود حركات مخزون مرتبطة بهذه الدفعة غير حركة الإضافة الأولية
        $transactionsCount = \App\Models\InventoryTransaction::where('batch_id', $inventoryBatch->id)
            ->where('transaction_type', '!=', 'batch_added')
            ->count();

        if ($transactionsCount > 0) {
            return redirect()->route('inventory-batches.index')
                ->with('error', 'لا يمكن حذف الدفعة لأنها مرتبطة بحركات مخزون');
        }

        DB::beginTransaction();

        try {
            // تحديث مخزون العنصر في المستودع
            $this->updateItemStock($inventoryBatch->item_id, $inventoryBatch->warehouse_id, -$inventoryBatch->quantity);

            // حذف حركة المخزون المرتبطة بإضافة الدفعة
            \App\Models\InventoryTransaction::where('batch_id', $inventoryBatch->id)
                ->where('transaction_type', 'batch_added')
                ->delete();

            // حذف الدفعة
            $inventoryBatch->delete();

            DB::commit();

            return redirect()->route('inventory-batches.index')
                ->with('success', 'تم حذف الدفعة بنجاح');
        } catch (\Exception $e) {
            DB::rollBack();
            return redirect()->back()->with('error', 'حدث خطأ أثناء حذف الدفعة: ' . $e->getMessage());
        }
    }

    /**
     * تحديث كمية العنصر في المستودع
     *
     * @param  int  $itemId
     * @param  int  $warehouseId
     * @param  float  $quantity
     * @return void
     */
    private function updateItemStock($itemId, $warehouseId, $quantity)
    {
        $stock = \App\Models\InventoryStock::firstOrNew([
            'item_id' => $itemId,
            'warehouse_id' => $warehouseId,
        ]);

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

        $stock->quantity += $quantity;
        $stock->save();
    }

    /**
     * إنشاء حركة مخزون
     *
     * @param  int  $itemId
     * @param  int  $warehouseId
     * @param  float  $quantity
     * @param  string  $transactionType
     * @param  int|null  $batchId
     * @return \App\Models\InventoryTransaction
     */
    private function createInventoryTransaction($itemId, $warehouseId, $quantity, $transactionType, $batchId = null)
    {
        $transaction = new \App\Models\InventoryTransaction();
        $transaction->item_id = $itemId;
        $transaction->warehouse_id = $warehouseId;
        $transaction->quantity = $quantity;
        $transaction->transaction_type = $transactionType;
        $transaction->batch_id = $batchId;
        $transaction->created_by = Auth::id();
        $transaction->save();

        return $transaction;
    }

    /**
     * عرض الدفعات منتهية الصلاحية أو قريبة من انتهاء الصلاحية
     *
     * @return \Illuminate\Http\Response
     */
    public function expiringSoon()
    {
        $companyId = auth()->user()->company_id;

        // الدفعات منتهية الصلاحية
        $expiredBatches = InventoryBatch::whereHas('item', function ($query) use ($companyId) {
            $query->where('company_id', $companyId);
        })
            ->where('quantity', '>', 0)
            ->where('expiry_date', '<', now())
            ->with(['item', 'warehouse'])
            ->orderBy('expiry_date')
            ->get();

        // الدفعات التي ستنتهي صلاحيتها خلال 30 يوم
        $expiringSoonBatches = InventoryBatch::whereHas('item', function ($query) use ($companyId) {
            $query->where('company_id', $companyId);
        })
            ->where('quantity', '>', 0)
            ->where('expiry_date', '>=', now())
            ->where('expiry_date', '<=', now()->addDays(30))
            ->with(['item', 'warehouse'])
            ->orderBy('expiry_date')
            ->get();

        return view('inventory.batches.expiring', compact('expiredBatches', 'expiringSoonBatches'));
    }

    /**
     * تعديل كمية الدفعة
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\InventoryBatch  $inventoryBatch
     * @return \Illuminate\Http\Response
     */
    public function adjustQuantity(Request $request, InventoryBatch $inventoryBatch)
    {
        // التحقق من أن الدفعة تنتمي للشركة الحالية
        if ($inventoryBatch->item->company_id != auth()->user()->company_id) {
            return redirect()->route('inventory-batches.index')
                ->with('error', 'لا يمكنك تعديل دفعة لا تنتمي لشركتك');
        }

        $request->validate([
            'new_quantity' => 'required|numeric|min:0',
            'reason' => 'required|string',
        ]);

        $oldQuantity = $inventoryBatch->quantity;
        $newQuantity = $request->new_quantity;
        $difference = $newQuantity - $oldQuantity;

        DB::beginTransaction();

        try {
            // تحديث كمية الدفعة
            $inventoryBatch->quantity = $newQuantity;
            $inventoryBatch->save();

            // تحديث مخزون العنصر في المستودع
            $this->updateItemStock($inventoryBatch->item_id, $inventoryBatch->warehouse_id, $difference);

            // إنشاء حركة مخزون
            $transactionType = $difference > 0 ? 'quantity_increase' : 'quantity_decrease';
            $transaction = $this->createInventoryTransaction(
                $inventoryBatch->item_id,
                $inventoryBatch->warehouse_id,
                abs($difference),
                $transactionType,
                $inventoryBatch->id
            );

            // إضافة سبب التعديل
            $transaction->notes = $request->reason;
            $transaction->save();

            DB::commit();

            return redirect()->route('inventory-batches.show', $inventoryBatch)
                ->with('success', 'تم تعديل كمية الدفعة بنجاح');
        } catch (\Exception $e) {
            DB::rollBack();
            return redirect()->back()->with('error', 'حدث خطأ أثناء تعديل كمية الدفعة: ' . $e->getMessage());
        }
    }
}
