<?php

namespace App\Http\Controllers;

use App\Models\InventoryItem;
use App\Models\InventoryItemUnit;
use App\Models\InventoryUnit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Validator;

class InventoryItemUnitController extends Controller
{
    /**
     * عرض جميع وحدات الأصناف
     *
     * @return \Illuminate\Http\Response
     */
    public function indexAll()
    {
        // عرض جميع وحدات الأصناف مباشرة
        $itemUnits = InventoryItemUnit::with(['inventory_unit', 'inventory_item', 'inventory_item.category'])
            ->whereHas('inventory_item', function ($query) {
                $query->where('company_id', Auth::user()->company_id);
            })
            ->get();

        // تحقق من وجود أصناف للشركة الحالية
        $items = InventoryItem::where('company_id', Auth::user()->company_id)
            ->orderBy('name')
            ->get();

        return view('inventory.items.units.index_all', compact('itemUnits', 'items'));
    }

    /**
     * عرض وحدات صنف محدد
     *
     * @param  int  $itemId
     * @return \Illuminate\Http\Response
     */
    public function index($itemId)
    {
        // إذا كان معرف الصنف هو 0، نعرض جميع وحدات الأصناف
        if ($itemId == 0) {
            $itemUnits = InventoryItemUnit::with(['inventory_unit', 'inventory_item', 'inventory_item.category'])
                ->whereHas('inventory_item', function ($query) {
                    $query->where('company_id', Auth::user()->company_id);
                })
                ->get();

            // تحقق من وجود أصناف للشركة الحالية
            $items = InventoryItem::where('company_id', Auth::user()->company_id)
                ->orderBy('name')
                ->get();

            return view('inventory.items.units.index_all', compact('itemUnits', 'items'));
        }

        // غير ذلك، نعرض وحدات الصنف المحدد
        $item = InventoryItem::where('company_id', Auth::user()->company_id)
            ->findOrFail($itemId);

        $itemUnits = InventoryItemUnit::where('item_id', $itemId)
            ->with('inventory_unit')
            ->get();

        return view('inventory.items.units.index', compact('item', 'itemUnits'));
    }

    /**
     * عرض نموذج إضافة وحدة لصنف
     *
     * @param  int  $itemId
     * @return \Illuminate\Http\Response
     */
    public function create($itemId)
    {
        // إذا جئنا من صفحة ربط وحدة، نحفظ ذلك في الجلسة
        if (request()->has('link_unit') || request()->route()->getName() == 'inventory.item-units.create') {
            session(['from_link_unit' => true]);
            \Log::info('Setting from_link_unit session variable');
        }

        $item = InventoryItem::where('company_id', Auth::user()->company_id)
            ->findOrFail($itemId);

        // الحصول على الوحدات النشطة التي لم يتم ربطها بالصنف بعد
        $existingUnitIds = InventoryItemUnit::where('item_id', $itemId)
            ->pluck('unit_id')
            ->toArray();

        $units = InventoryUnit::where('company_id', Auth::user()->company_id)
            ->where('is_active', true)
            ->whereNotIn('id', $existingUnitIds)
            ->orderBy('is_base', 'desc')
            ->orderBy('name')
            ->get();

        return view('inventory.items.units.create', compact('item', 'units'));
    }

    /**
     * تخزين وحدة جديدة للصنف
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $itemId
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request, $itemId)
    {
        // تسجيل معلومات الطلب للتشخيص
        \Log::info('Store method called with itemId: ' . $itemId);
        \Log::info('Request data: ' . json_encode($request->all()));
        \Log::info('Route name: ' . $request->route()->getName());

        $item = InventoryItem::where('company_id', Auth::user()->company_id)
            ->findOrFail($itemId);

        // تحويل قيم الحقول المنطقية من "on" إلى true
        $data = $request->all();
        $data['is_default'] = $request->has('is_default') ? true : false;
        $data['is_purchase_unit'] = $request->has('is_purchase_unit') ? true : false;
        $data['is_sales_unit'] = $request->has('is_sales_unit') ? true : false;
        $data['is_inventory_unit'] = $request->has('is_inventory_unit') ? true : false;

        \Log::info('Transformed request data: ' . json_encode($data));

        $validator = Validator::make($data, [
            'unit_id' => 'required|exists:inventory_units,id',
            'conversion_factor' => 'required|numeric|min:0.0001',
            'is_default' => 'boolean',
            'is_purchase_unit' => 'boolean',
            'is_sales_unit' => 'boolean',
            'is_inventory_unit' => 'boolean',
            'purchase_price' => 'nullable|numeric|min:0',
            'selling_price' => 'nullable|numeric|min:0',
        ]);

        if ($validator->fails()) {
            \Log::error('Validation failed: ' . json_encode($validator->errors()->toArray()));
            return redirect()->back()
                ->withErrors($validator)
                ->withInput();
        }

        \Log::info('Validation passed');

        // التحقق من أن الوحدة تنتمي لنفس الشركة
        try {
            $unit = InventoryUnit::where('id', $request->unit_id)
                ->where('company_id', Auth::user()->company_id)
                ->firstOrFail();

            \Log::info('Unit found: ' . $unit->id . ' - ' . $unit->name);
        } catch (\Exception $e) {
            \Log::error('Unit not found: ' . $request->unit_id . ' - ' . $e->getMessage());
            return redirect()->back()
                ->with('error', 'الوحدة غير موجودة أو لا تنتمي لشركتك')
                ->withInput();
        }

        // التحقق من عدم وجود الوحدة مسبقاً للصنف
        $existingUnit = InventoryItemUnit::where('item_id', $itemId)
            ->where('unit_id', $request->unit_id)
            ->first();

        if ($existingUnit) {
            \Log::error('Unit already exists for this item: Item ID ' . $itemId . ', Unit ID ' . $request->unit_id);
            return redirect()->back()
                ->with('error', 'هذه الوحدة مرتبطة بالفعل بهذا الصنف')
                ->withInput();
        }

        \Log::info('Unit validation passed');

        // إذا كانت هذه الوحدة الافتراضية، نقوم بإلغاء تعيين الوحدة الافتراضية السابقة
        if ($request->has('is_default') && $request->is_default) {
            InventoryItemUnit::where('item_id', $itemId)
                ->where('is_default', true)
                ->update(['is_default' => false]);
        }

        // إذا كانت هذه وحدة الشراء، نقوم بإلغاء تعيين وحدة الشراء السابقة
        if ($request->has('is_purchase_unit') && $request->is_purchase_unit) {
            InventoryItemUnit::where('item_id', $itemId)
                ->where('is_purchase_unit', true)
                ->update(['is_purchase_unit' => false]);
        }

        // إذا كانت هذه وحدة البيع، نقوم بإلغاء تعيين وحدة البيع السابقة
        if ($request->has('is_sales_unit') && $request->is_sales_unit) {
            InventoryItemUnit::where('item_id', $itemId)
                ->where('is_sales_unit', true)
                ->update(['is_sales_unit' => false]);
        }

        // إذا كانت هذه وحدة المخزون، نقوم بإلغاء تعيين وحدة المخزون السابقة
        if ($request->has('is_inventory_unit') && $request->is_inventory_unit) {
            InventoryItemUnit::where('item_id', $itemId)
                ->where('is_inventory_unit', true)
                ->update(['is_inventory_unit' => false]);
        }

        try {
            $itemUnit = new InventoryItemUnit();
            $itemUnit->item_id = $itemId;
            $itemUnit->unit_id = $request->unit_id;
            $itemUnit->conversion_factor = $request->conversion_factor;
            $itemUnit->is_default = $data['is_default']; // استخدام البيانات المحولة
            $itemUnit->is_purchase_unit = $data['is_purchase_unit']; // استخدام البيانات المحولة
            $itemUnit->is_sales_unit = $data['is_sales_unit']; // استخدام البيانات المحولة
            $itemUnit->is_inventory_unit = $data['is_inventory_unit']; // استخدام البيانات المحولة
            $itemUnit->purchase_price = $request->purchase_price ?? 0;
            $itemUnit->selling_price = $request->selling_price ?? 0;

            \Log::info('Saving item unit: ' . json_encode($itemUnit->toArray()));
            $itemUnit->save();
            \Log::info('Item unit saved successfully with ID: ' . $itemUnit->id);
        } catch (\Exception $e) {
            \Log::error('Error saving item unit: ' . $e->getMessage());
            \Log::error('Error trace: ' . $e->getTraceAsString());
            return redirect()->back()
                ->with('error', 'حدث خطأ أثناء حفظ وحدة الصنف: ' . $e->getMessage())
                ->withInput();
        }

        try {
            // إذا كانت هذه أول وحدة للصنف، نجعلها الوحدة الافتراضية ووحدة الشراء والبيع والمخزون
            $unitCount = InventoryItemUnit::where('item_id', $itemId)->count();
            \Log::info('Unit count for item ' . $itemId . ': ' . $unitCount);

            if ($unitCount == 1) {
                \Log::info('Setting as default unit');
                $itemUnit->is_default = true;
                $itemUnit->is_purchase_unit = true;
                $itemUnit->is_sales_unit = true;
                $itemUnit->is_inventory_unit = true;
                $itemUnit->save();
            }

            // إذا كانت هذه وحدة أساسية، نقوم بتعيينها كوحدة أساسية للصنف
            if ($unit->is_base) {
                \Log::info('Setting as base unit for item');
                // تحقق من وجود العمود قبل محاولة التحديث
                if (Schema::hasColumn('inventory_items', 'base_unit_id')) {
                    $item->base_unit_id = $unit->id;
                    $item->save();
                } else {
                    \Log::warning('Column base_unit_id does not exist in inventory_items table');
                }
            }
        } catch (\Exception $e) {
            \Log::error('Error updating item or unit: ' . $e->getMessage());
            // لا نعيد توجيه هنا لأن الوحدة تم حفظها بالفعل
        }

        // التحقق من المسار الذي جاء منه الطلب
        \Log::info('Redirecting after save. Route name: ' . request()->route()->getName());
        \Log::info('Session has from_link_unit: ' . (session()->has('from_link_unit') ? 'Yes' : 'No'));

        // تم الحفظ بنجاح، نعيد التوجيه إلى صفحة وحدات الأصناف
        \Log::info('Redirecting to inventory.item-units.index');
        session()->forget('from_link_unit');
        return redirect()->route('inventory.item-units.index')
            ->with('success', 'تم إضافة الوحدة للصنف بنجاح');
    }

    /**
     * عرض نموذج تعديل وحدة صنف
     *
     * @param  int  $itemId
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($itemId, $id)
    {
        $item = InventoryItem::where('company_id', Auth::user()->company_id)
            ->findOrFail($itemId);

        $itemUnit = InventoryItemUnit::where('item_id', $itemId)
            ->where('id', $id)
            ->with('inventory_unit')
            ->firstOrFail();

        return view('inventory.items.units.edit', compact('item', 'itemUnit'));
    }

    /**
     * تحديث وحدة صنف
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $itemId
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $itemId, $id)
    {
        $item = InventoryItem::where('company_id', Auth::user()->company_id)
            ->findOrFail($itemId);

        $itemUnit = InventoryItemUnit::where('item_id', $itemId)
            ->where('id', $id)
            ->firstOrFail();

        // تحويل قيم الحقول المنطقية من "on" إلى true
        $data = $request->all();
        $data['is_default'] = $request->has('is_default') ? true : false;
        $data['is_purchase_unit'] = $request->has('is_purchase_unit') ? true : false;
        $data['is_sales_unit'] = $request->has('is_sales_unit') ? true : false;
        $data['is_inventory_unit'] = $request->has('is_inventory_unit') ? true : false;

        \Log::info('Transformed request data (update): ' . json_encode($data));

        $validator = Validator::make($data, [
            'conversion_factor' => 'required|numeric|min:0.0001',
            'is_default' => 'boolean',
            'is_purchase_unit' => 'boolean',
            'is_sales_unit' => 'boolean',
            'is_inventory_unit' => 'boolean',
            'purchase_price' => 'nullable|numeric|min:0',
            'selling_price' => 'nullable|numeric|min:0',
        ]);

        if ($validator->fails()) {
            \Log::error('Validation failed (update): ' . json_encode($validator->errors()->toArray()));
            return redirect()->back()
                ->withErrors($validator)
                ->withInput();
        }

        \Log::info('Validation passed (update)');

        try {
            // إذا كانت هذه الوحدة الافتراضية، نقوم بإلغاء تعيين الوحدة الافتراضية السابقة
            if ($data['is_default'] && !$itemUnit->is_default) {
                \Log::info('Unsetting previous default unit');
                InventoryItemUnit::where('item_id', $itemId)
                    ->where('is_default', true)
                    ->update(['is_default' => false]);
            }

            // إذا كانت هذه وحدة الشراء، نقوم بإلغاء تعيين وحدة الشراء السابقة
            if ($data['is_purchase_unit'] && !$itemUnit->is_purchase_unit) {
                \Log::info('Unsetting previous purchase unit');
                InventoryItemUnit::where('item_id', $itemId)
                    ->where('is_purchase_unit', true)
                    ->update(['is_purchase_unit' => false]);
            }

            // إذا كانت هذه وحدة البيع، نقوم بإلغاء تعيين وحدة البيع السابقة
            if ($data['is_sales_unit'] && !$itemUnit->is_sales_unit) {
                \Log::info('Unsetting previous sales unit');
                InventoryItemUnit::where('item_id', $itemId)
                    ->where('is_sales_unit', true)
                    ->update(['is_sales_unit' => false]);
            }

            // إذا كانت هذه وحدة المخزون، نقوم بإلغاء تعيين وحدة المخزون السابقة
            if ($data['is_inventory_unit'] && !$itemUnit->is_inventory_unit) {
                \Log::info('Unsetting previous inventory unit');
                InventoryItemUnit::where('item_id', $itemId)
                    ->where('is_inventory_unit', true)
                    ->update(['is_inventory_unit' => false]);
            }
        } catch (\Exception $e) {
            \Log::error('Error updating unit flags: ' . $e->getMessage());
            // لا نعيد توجيه هنا لأننا سنحاول تحديث الوحدة على أي حال
        }

        try {
            $itemUnit->conversion_factor = $request->conversion_factor;
            $itemUnit->is_default = $data['is_default'];
            $itemUnit->is_purchase_unit = $data['is_purchase_unit'];
            $itemUnit->is_sales_unit = $data['is_sales_unit'];
            $itemUnit->is_inventory_unit = $data['is_inventory_unit'];
            $itemUnit->purchase_price = $request->purchase_price ?? 0;
            $itemUnit->selling_price = $request->selling_price ?? 0;

            \Log::info('Updating item unit: ' . json_encode($itemUnit->toArray()));
            $itemUnit->save();
            \Log::info('Item unit updated successfully');

            return redirect()->route('inventory.items.units.index', $itemId)
                ->with('success', 'تم تحديث وحدة الصنف بنجاح');
        } catch (\Exception $e) {
            \Log::error('Error updating item unit: ' . $e->getMessage());
            \Log::error('Error trace: ' . $e->getTraceAsString());
            return redirect()->back()
                ->with('error', 'حدث خطأ أثناء تحديث وحدة الصنف: ' . $e->getMessage())
                ->withInput();
        }
    }

    /**
     * حذف وحدة صنف
     *
     * @param  int  $itemId
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($itemId, $id)
    {
        $item = InventoryItem::where('company_id', Auth::user()->company_id)
            ->findOrFail($itemId);

        $itemUnit = InventoryItemUnit::where('item_id', $itemId)
            ->where('id', $id)
            ->firstOrFail();

        // التحقق من عدم حذف الوحدة الأساسية للصنف
        if (Schema::hasColumn('inventory_items', 'base_unit_id') && $item->base_unit_id == $itemUnit->unit_id) {
            return redirect()->back()
                ->with('error', 'لا يمكن حذف الوحدة الأساسية للصنف');
        }

        // التحقق من عدد الوحدات المتبقية
        $remainingUnits = InventoryItemUnit::where('item_id', $itemId)
            ->where('id', '!=', $id)
            ->count();

        if ($remainingUnits == 0) {
            return redirect()->back()
                ->with('error', 'لا يمكن حذف الوحدة الوحيدة للصنف');
        }

        // إذا كانت هذه الوحدة الافتراضية أو وحدة الشراء أو البيع أو المخزون
        // نقوم بتعيين وحدة أخرى كبديل
        if (
            $itemUnit->is_default || $itemUnit->is_purchase_unit ||
            $itemUnit->is_sales_unit || $itemUnit->is_inventory_unit
        ) {

            $alternativeUnit = InventoryItemUnit::where('item_id', $itemId)
                ->where('id', '!=', $id)
                ->first();

            if ($itemUnit->is_default) {
                $alternativeUnit->is_default = true;
            }

            if ($itemUnit->is_purchase_unit) {
                $alternativeUnit->is_purchase_unit = true;
            }

            if ($itemUnit->is_sales_unit) {
                $alternativeUnit->is_sales_unit = true;
            }

            if ($itemUnit->is_inventory_unit) {
                $alternativeUnit->is_inventory_unit = true;
            }

            $alternativeUnit->save();
        }

        $itemUnit->delete();

        return redirect()->route('inventory.items.units.index', $itemId)
            ->with('success', 'تم حذف وحدة الصنف بنجاح');
    }
}
