<?php

namespace App\Http\Controllers;

use App\Models\InstallationProject;
use App\Models\InventoryItem;
use App\Models\ProjectInventoryRequest;
use App\Models\ProjectInventoryRequestItem;
use App\Models\ProjectPhase;
use App\Models\ProjectTask;
use App\Models\Warehouse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;

class ProjectInventoryRequestController extends Controller
{
    /**
     * عرض قائمة طلبات المخزون للمشروع
     */
    public function index(Request $request, $projectId)
    {
        $project = InstallationProject::findOrFail($projectId);

        // التحقق من الصلاحيات
        $this->authorize('view', $project);

        $requests = ProjectInventoryRequest::where('installation_project_id', $projectId)
            ->with(['requester', 'approver', 'phase'])
            ->orderBy('created_at', 'desc')
            ->paginate(10);

        return view('projects.inventory.index', compact('project', 'requests'));
    }

    /**
     * عرض نموذج إنشاء طلب مخزون جديد
     */
    public function create($projectId)
    {
        $project = InstallationProject::findOrFail($projectId);

        // التحقق من الصلاحيات
        $this->authorize('update', $project);

        $phases = $project->phases;
        $warehouses = Warehouse::where('company_id', $project->company_id)->get();
        $inventoryItems = InventoryItem::where('company_id', $project->company_id)
            ->where('is_active', true)
            ->get();

        return view('projects.inventory.create', compact('project', 'phases', 'warehouses', 'inventoryItems'));
    }

    /**
     * حفظ طلب مخزون جديد
     */
    public function store(Request $request, $projectId)
    {
        $project = InstallationProject::findOrFail($projectId);

        // التحقق من الصلاحيات
        $this->authorize('update', $project);

        // التحقق من البيانات
        $validator = Validator::make($request->all(), [
            'phase_id' => 'nullable|exists:project_phases,id',
            'required_date' => 'required|date|after:today',
            'notes' => 'nullable|string|max:1000',
            'items' => 'required|array|min:1',
            'items.*.item_id' => 'required|exists:inventory_items,id',
            'items.*.warehouse_id' => 'required|exists:warehouses,id',
            'items.*.quantity' => 'required|numeric|min:0.01',
            'items.*.priority' => 'required|in:low,medium,high,critical',
            'items.*.task_id' => 'nullable|exists:project_tasks,id',
            'items.*.notes' => 'nullable|string|max:500',
        ]);

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

        // إنشاء رقم الطلب
        $requestNumber = 'PIR-' . date('Ymd') . '-' . str_pad(ProjectInventoryRequest::count() + 1, 4, '0', STR_PAD_LEFT);

        DB::beginTransaction();

        try {
            // إنشاء طلب المخزون
            $inventoryRequest = ProjectInventoryRequest::create([
                'company_id' => $project->company_id,
                'installation_project_id' => $project->id,
                'project_phase_id' => $request->phase_id,
                'request_number' => $requestNumber,
                'status' => 'pending',
                'requested_by' => Auth::id(),
                'requested_date' => now(),
                'required_date' => $request->required_date,
                'notes' => $request->notes,
            ]);

            // إضافة عناصر الطلب
            foreach ($request->items as $item) {
                ProjectInventoryRequestItem::create([
                    'project_inventory_request_id' => $inventoryRequest->id,
                    'inventory_item_id' => $item['item_id'],
                    'warehouse_id' => $item['warehouse_id'],
                    'quantity' => $item['quantity'],
                    'status' => 'pending',
                    'priority' => $item['priority'],
                    'task_id' => $item['task_id'] ?? null,
                    'notes' => $item['notes'] ?? null,
                ]);
            }

            DB::commit();

            return redirect()->route('projects.inventory.show', [$project->id, $inventoryRequest->id])
                ->with('success', 'تم إنشاء طلب المخزون بنجاح');
        } catch (\Exception $e) {
            DB::rollBack();
            return redirect()->back()
                ->with('error', 'حدث خطأ أثناء إنشاء طلب المخزون: ' . $e->getMessage())
                ->withInput();
        }
    }

    /**
     * عرض تفاصيل طلب مخزون
     */
    public function show($projectId, $requestId)
    {
        $project = InstallationProject::findOrFail($projectId);
        $request = ProjectInventoryRequest::where('installation_project_id', $projectId)
            ->with(['requester', 'approver', 'phase', 'items.item', 'items.warehouse', 'items.task'])
            ->findOrFail($requestId);

        // التحقق من الصلاحيات
        $this->authorize('view', $project);

        return view('projects.inventory.show', compact('project', 'request'));
    }

    /**
     * عرض نموذج تعديل طلب مخزون
     */
    public function edit($projectId, $requestId)
    {
        $project = InstallationProject::findOrFail($projectId);
        $request = ProjectInventoryRequest::where('installation_project_id', $projectId)
            ->with(['items.item', 'items.warehouse', 'items.task'])
            ->findOrFail($requestId);

        // التحقق من الصلاحيات
        $this->authorize('update', $project);

        // لا يمكن تعديل الطلبات المعتمدة أو المكتملة
        if (in_array($request->status, ['approved', 'partially_fulfilled', 'fulfilled'])) {
            return redirect()->route('projects.inventory.show', [$project->id, $request->id])
                ->with('error', 'لا يمكن تعديل الطلب بعد اعتماده أو تنفيذه');
        }

        $phases = $project->phases;
        $warehouses = Warehouse::where('company_id', $project->company_id)->get();
        $inventoryItems = InventoryItem::where('company_id', $project->company_id)
            ->where('is_active', true)
            ->get();

        return view('projects.inventory.edit', compact('project', 'request', 'phases', 'warehouses', 'inventoryItems'));
    }

    /**
     * تحديث طلب مخزون
     */
    public function update(Request $request, $projectId, $requestId)
    {
        $project = InstallationProject::findOrFail($projectId);
        $inventoryRequest = ProjectInventoryRequest::where('installation_project_id', $projectId)
            ->findOrFail($requestId);

        // التحقق من الصلاحيات
        $this->authorize('update', $project);

        // لا يمكن تعديل الطلبات المعتمدة أو المكتملة
        if (in_array($inventoryRequest->status, ['approved', 'partially_fulfilled', 'fulfilled'])) {
            return redirect()->route('projects.inventory.show', [$project->id, $inventoryRequest->id])
                ->with('error', 'لا يمكن تعديل الطلب بعد اعتماده أو تنفيذه');
        }

        // التحقق من البيانات
        $validator = Validator::make($request->all(), [
            'phase_id' => 'nullable|exists:project_phases,id',
            'required_date' => 'required|date',
            'notes' => 'nullable|string|max:1000',
            'items' => 'required|array|min:1',
            'items.*.id' => 'nullable|exists:project_inventory_request_items,id',
            'items.*.item_id' => 'required|exists:inventory_items,id',
            'items.*.warehouse_id' => 'required|exists:warehouses,id',
            'items.*.quantity' => 'required|numeric|min:0.01',
            'items.*.priority' => 'required|in:low,medium,high,critical',
            'items.*.task_id' => 'nullable|exists:project_tasks,id',
            'items.*.notes' => 'nullable|string|max:500',
        ]);

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

        DB::beginTransaction();

        try {
            // تحديث طلب المخزون
            $inventoryRequest->update([
                'project_phase_id' => $request->phase_id,
                'required_date' => $request->required_date,
                'notes' => $request->notes,
            ]);

            // تحديث عناصر الطلب
            $currentItemIds = [];

            foreach ($request->items as $item) {
                if (isset($item['id']) && $item['id']) {
                    // تحديث العنصر الموجود
                    $requestItem = ProjectInventoryRequestItem::find($item['id']);
                    if ($requestItem && $requestItem->project_inventory_request_id == $inventoryRequest->id) {
                        $requestItem->update([
                            'inventory_item_id' => $item['item_id'],
                            'warehouse_id' => $item['warehouse_id'],
                            'quantity' => $item['quantity'],
                            'priority' => $item['priority'],
                            'task_id' => $item['task_id'] ?? null,
                            'notes' => $item['notes'] ?? null,
                        ]);
                        $currentItemIds[] = $requestItem->id;
                    }
                } else {
                    // إضافة عنصر جديد
                    $requestItem = ProjectInventoryRequestItem::create([
                        'project_inventory_request_id' => $inventoryRequest->id,
                        'inventory_item_id' => $item['item_id'],
                        'warehouse_id' => $item['warehouse_id'],
                        'quantity' => $item['quantity'],
                        'status' => 'pending',
                        'priority' => $item['priority'],
                        'task_id' => $item['task_id'] ?? null,
                        'notes' => $item['notes'] ?? null,
                    ]);
                    $currentItemIds[] = $requestItem->id;
                }
            }

            // حذف العناصر غير الموجودة في الطلب الجديد
            ProjectInventoryRequestItem::where('project_inventory_request_id', $inventoryRequest->id)
                ->whereNotIn('id', $currentItemIds)
                ->delete();

            // تحديث حالة الطلب
            $inventoryRequest->updateStatus();

            DB::commit();

            return redirect()->route('projects.inventory.show', [$project->id, $inventoryRequest->id])
                ->with('success', 'تم تحديث طلب المخزون بنجاح');
        } catch (\Exception $e) {
            DB::rollBack();
            return redirect()->back()
                ->with('error', 'حدث خطأ أثناء تحديث طلب المخزون: ' . $e->getMessage())
                ->withInput();
        }
    }

    /**
     * حذف طلب مخزون
     */
    public function destroy($projectId, $requestId)
    {
        $project = InstallationProject::findOrFail($projectId);
        $request = ProjectInventoryRequest::where('installation_project_id', $projectId)
            ->findOrFail($requestId);

        // التحقق من الصلاحيات
        $this->authorize('update', $project);

        // لا يمكن حذف الطلبات المعتمدة أو المكتملة
        if (in_array($request->status, ['approved', 'partially_fulfilled', 'fulfilled'])) {
            return redirect()->route('projects.inventory.show', [$project->id, $request->id])
                ->with('error', 'لا يمكن حذف الطلب بعد اعتماده أو تنفيذه');
        }

        $request->delete();

        return redirect()->route('projects.inventory.index', $project->id)
            ->with('success', 'تم حذف طلب المخزون بنجاح');
    }

    /**
     * اعتماد طلب مخزون
     */
    public function approve($projectId, $requestId)
    {
        $project = InstallationProject::findOrFail($projectId);
        $request = ProjectInventoryRequest::where('installation_project_id', $projectId)
            ->findOrFail($requestId);

        // التحقق من الصلاحيات (يجب أن يكون المستخدم مدير مشروع أو لديه صلاحيات إدارية)
        $this->authorize('approveInventoryRequests', $project);

        // لا يمكن اعتماد الطلبات المعتمدة أو المكتملة
        if (in_array($request->status, ['approved', 'partially_fulfilled', 'fulfilled'])) {
            return redirect()->route('projects.inventory.show', [$project->id, $request->id])
                ->with('error', 'تم اعتماد الطلب مسبقاً');
        }

        DB::beginTransaction();

        try {
            // تحديث حالة الطلب
            $request->update([
                'status' => 'approved',
                'approved_by' => Auth::id(),
                'approval_date' => now(),
            ]);

            // تحديث حالة العناصر
            foreach ($request->items as $item) {
                $item->update(['status' => 'approved']);

                // حجز الكمية في المخزون إذا كانت متوفرة
                $item->reserve();
            }

            DB::commit();

            return redirect()->route('projects.inventory.show', [$project->id, $request->id])
                ->with('success', 'تم اعتماد طلب المخزون بنجاح');
        } catch (\Exception $e) {
            DB::rollBack();
            return redirect()->back()
                ->with('error', 'حدث خطأ أثناء اعتماد طلب المخزون: ' . $e->getMessage());
        }
    }

    /**
     * رفض طلب مخزون
     */
    public function reject(Request $request, $projectId, $requestId)
    {
        $project = InstallationProject::findOrFail($projectId);
        $inventoryRequest = ProjectInventoryRequest::where('installation_project_id', $projectId)
            ->findOrFail($requestId);

        // التحقق من الصلاحيات (يجب أن يكون المستخدم مدير مشروع أو لديه صلاحيات إدارية)
        $this->authorize('approveInventoryRequests', $project);

        // لا يمكن رفض الطلبات المكتملة
        if (in_array($inventoryRequest->status, ['partially_fulfilled', 'fulfilled'])) {
            return redirect()->route('projects.inventory.show', [$project->id, $inventoryRequest->id])
                ->with('error', 'لا يمكن رفض الطلب بعد تنفيذه');
        }

        // التحقق من البيانات
        $validator = Validator::make($request->all(), [
            'rejection_reason' => 'required|string|max:1000',
        ]);

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

        DB::beginTransaction();

        try {
            // تحديث حالة الطلب
            $inventoryRequest->update([
                'status' => 'rejected',
                'rejection_reason' => $request->rejection_reason,
            ]);

            // تحديث حالة العناصر
            foreach ($inventoryRequest->items as $item) {
                $item->update([
                    'status' => 'rejected',
                    'rejection_reason' => $request->rejection_reason,
                ]);
            }

            DB::commit();

            return redirect()->route('projects.inventory.show', [$project->id, $inventoryRequest->id])
                ->with('success', 'تم رفض طلب المخزون بنجاح');
        } catch (\Exception $e) {
            DB::rollBack();
            return redirect()->back()
                ->with('error', 'حدث خطأ أثناء رفض طلب المخزون: ' . $e->getMessage());
        }
    }

    /**
     * تنفيذ طلب مخزون
     */
    public function fulfill(Request $request, $projectId, $requestId)
    {
        $project = InstallationProject::findOrFail($projectId);
        $inventoryRequest = ProjectInventoryRequest::where('installation_project_id', $projectId)
            ->with('items.item', 'items.warehouse')
            ->findOrFail($requestId);

        // التحقق من الصلاحيات (يجب أن يكون المستخدم مسؤول مخزون أو لديه صلاحيات إدارية)
        $this->authorize('fulfillInventoryRequests', $project);

        // لا يمكن تنفيذ الطلبات غير المعتمدة أو المرفوضة
        if (!in_array($inventoryRequest->status, ['approved', 'partially_fulfilled'])) {
            return redirect()->route('projects.inventory.show', [$project->id, $inventoryRequest->id])
                ->with('error', 'يجب اعتماد الطلب قبل تنفيذه');
        }

        // التحقق من البيانات
        $validator = Validator::make($request->all(), [
            'items' => 'required|array',
            'items.*.id' => 'required|exists:project_inventory_request_items,id',
            'items.*.fulfill_quantity' => 'required|numeric|min:0',
        ]);

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

        DB::beginTransaction();

        try {
            $allFulfilled = true;
            $anyFulfilled = false;

            foreach ($request->items as $itemData) {
                $item = ProjectInventoryRequestItem::find($itemData['id']);

                if (!$item || $item->project_inventory_request_id != $inventoryRequest->id) {
                    continue;
                }

                $fulfillQuantity = floatval($itemData['fulfill_quantity']);

                if ($fulfillQuantity <= 0) {
                    continue;
                }

                // التحقق من توفر الكمية في المخزون
                $stock = $item->checkAvailability();

                if ($stock < $fulfillQuantity) {
                    throw new \Exception('الكمية المطلوبة غير متوفرة في المخزون للعنصر: ' . $item->item->name);
                }

                // تنفيذ الطلب (صرف المواد من المخزون)
                $item->fulfill($fulfillQuantity, Auth::id());

                $anyFulfilled = true;

                // التحقق مما إذا كانت جميع العناصر مكتملة
                if ($item->remaining_quantity > 0) {
                    $allFulfilled = false;
                }
            }

            // تحديث حالة الطلب
            if ($anyFulfilled) {
                $status = $allFulfilled ? 'fulfilled' : 'partially_fulfilled';
                $inventoryRequest->update([
                    'status' => $status,
                    'fulfillment_date' => $allFulfilled ? now() : $inventoryRequest->fulfillment_date,
                ]);
            }

            DB::commit();

            return redirect()->route('projects.inventory.show', [$project->id, $inventoryRequest->id])
                ->with('success', 'تم تنفيذ طلب المخزون بنجاح');
        } catch (\Exception $e) {
            DB::rollBack();
            return redirect()->back()
                ->with('error', 'حدث خطأ أثناء تنفيذ طلب المخزون: ' . $e->getMessage());
        }
    }

    /**
     * الحصول على معلومات توفر المخزون
     */
    public function checkAvailability(Request $request)
    {
        $itemId = $request->item_id;
        $warehouseId = $request->warehouse_id;

        if (!$itemId || !$warehouseId) {
            return response()->json(['available' => 0]);
        }

        $stock = \App\Models\InventoryStock::where('item_id', $itemId)
            ->where('warehouse_id', $warehouseId)
            ->first();

        $available = $stock ? $stock->available_quantity : 0;

        return response()->json([
            'available' => $available,
            'unit' => $stock && $stock->item ? $stock->item->unit : '',
        ]);
    }
}
