<?php

namespace App\Http\Controllers\Inventory;

use App\Http\Controllers\Controller;
use App\Models\InventoryItem;
use App\Models\InventorySerial;
use App\Models\InventoryBatch;
use App\Models\InventoryTransaction;
use App\Models\Warehouse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
use SimpleSoftwareIO\QrCode\Facades\QrCode;
use Milon\Barcode\Facades\DNS1D;
use Milon\Barcode\Facades\DNS2D;

class BarcodeController extends Controller
{
    /**
     * عرض صفحة إدارة الباركود
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        // التحقق من الصلاحيات
        if (!Auth::user()->can('view_inventory_barcodes')) {
            return redirect()->route('dashboard')->with('error', 'ليس لديك صلاحية للوصول إلى هذه الصفحة');
        }

        $items = InventoryItem::where('company_id', Auth::user()->company_id)
            ->where('is_active', true)
            ->whereNotNull('barcode')
            ->orderBy('name')
            ->paginate(15);

        $itemsWithoutBarcode = InventoryItem::where('company_id', Auth::user()->company_id)
            ->where('is_active', true)
            ->where(function ($query) {
                $query->whereNull('barcode')
                    ->orWhere('barcode', '');
            })
            ->orderBy('name')
            ->take(10)
            ->get();

        return view('inventory.barcodes.index', compact('items', 'itemsWithoutBarcode'));
    }

    /**
     * عرض صفحة إنشاء باركود لعنصر
     *
     * @param int $id
     * @return \Illuminate\Http\Response
     */
    public function generateItemBarcode($id)
    {
        // التحقق من الصلاحيات
        if (!Auth::user()->can('generate_inventory_barcodes')) {
            return redirect()->route('inventory.barcodes.index')->with('error', 'ليس لديك صلاحية لإنشاء الباركود');
        }

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

        $warehouses = Warehouse::where('company_id', Auth::user()->company_id)
            ->where('is_active', true)
            ->get();

        return view('inventory.barcodes.generate_item', compact('item', 'warehouses'));
    }

    /**
     * إنشاء باركود لعنصر
     *
     * @param Request $request
     * @param int $id
     * @return \Illuminate\Http\Response
     */
    public function storeItemBarcode(Request $request, $id)
    {
        // التحقق من الصلاحيات
        if (!Auth::user()->can('generate_inventory_barcodes')) {
            return redirect()->route('inventory.barcodes.index')->with('error', 'ليس لديك صلاحية لإنشاء الباركود');
        }

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

        $validated = $request->validate([
            'barcode_type' => 'required|in:ean13,code128,qrcode',
            'quantity' => 'required|integer|min:1|max:100',
            'include_price' => 'sometimes|boolean',
            'warehouse_id' => 'nullable|exists:warehouses,id',
        ]);

        // إنشاء الباركود
        $barcodeData = [
            'item_id' => $item->id,
            'name' => $item->name,
            'sku' => $item->sku,
            'price' => $validated['include_price'] ? $item->selling_price : null,
            'warehouse_id' => $validated['warehouse_id'] ?? null,
        ];

        // تحديث رمز الباركود للعنصر إذا لم يكن موجودًا
        if (empty($item->barcode)) {
            $item->barcode = $this->generateBarcodeNumber();
            $item->save();
        }

        $barcodeData['barcode'] = $item->barcode;

        // إنشاء ملف الباركود
        $barcodeImage = $this->generateBarcodeImage($item->barcode, $validated['barcode_type']);
        $barcodeFilename = 'barcode_' . $item->id . '_' . time() . '.png';
        Storage::disk('public')->put('barcodes/' . $barcodeFilename, $barcodeImage);

        return view('inventory.barcodes.print_item', [
            'item' => $item,
            'barcode_type' => $validated['barcode_type'],
            'quantity' => $validated['quantity'],
            'include_price' => $validated['include_price'],
            'barcode_image' => 'storage/barcodes/' . $barcodeFilename,
            'barcode_data' => $barcodeData,
        ]);
    }

    /**
     * عرض صفحة مسح الباركود
     *
     * @return \Illuminate\Http\Response
     */
    public function scanBarcode()
    {
        // التحقق من الصلاحيات
        if (!Auth::user()->can('scan_inventory_barcodes')) {
            return redirect()->route('dashboard')->with('error', 'ليس لديك صلاحية لمسح الباركود');
        }

        $warehouses = Warehouse::where('company_id', Auth::user()->company_id)
            ->where('is_active', true)
            ->get();

        return view('inventory.barcodes.scan', compact('warehouses'));
    }

    /**
     * معالجة مسح الباركود
     *
     * @param Request $request
     * @return \Illuminate\Http\Response
     */
    public function processScan(Request $request)
    {
        // التحقق من الصلاحيات
        if (!Auth::user()->can('scan_inventory_barcodes')) {
            return response()->json(['error' => 'ليس لديك صلاحية لمسح الباركود'], 403);
        }

        $validated = $request->validate([
            'barcode' => 'required|string',
            'warehouse_id' => 'required|exists:warehouses,id',
        ]);

        // البحث عن العنصر بواسطة الباركود
        $item = InventoryItem::where('company_id', Auth::user()->company_id)
            ->where(function ($query) use ($validated) {
                $query->where('barcode', $validated['barcode'])
                    ->orWhere('sku', $validated['barcode']);
            })
            ->first();

        if (!$item) {
            // البحث عن الرقم التسلسلي
            $serial = InventorySerial::where('company_id', Auth::user()->company_id)
                ->where('serial_number', $validated['barcode'])
                ->first();

            if ($serial) {
                return response()->json([
                    'success' => true,
                    'type' => 'serial',
                    'data' => $serial->load('item'),
                ]);
            }

            // البحث عن الدفعة
            $batch = InventoryBatch::where('company_id', Auth::user()->company_id)
                ->where('batch_number', $validated['barcode'])
                ->first();

            if ($batch) {
                return response()->json([
                    'success' => true,
                    'type' => 'batch',
                    'data' => $batch->load('item'),
                ]);
            }

            return response()->json(['error' => 'لم يتم العثور على عنصر بهذا الباركود'], 404);
        }

        // الحصول على معلومات المخزون
        $stock = $item->stocks()
            ->where('warehouse_id', $validated['warehouse_id'])
            ->first();

        return response()->json([
            'success' => true,
            'type' => 'item',
            'data' => $item,
            'stock' => $stock,
        ]);
    }

    /**
     * إنشاء معاملة مخزون بناءً على مسح الباركود
     *
     * @param Request $request
     * @return \Illuminate\Http\Response
     */
    public function createTransaction(Request $request)
    {
        // التحقق من الصلاحيات
        if (!Auth::user()->can('create_inventory_transactions')) {
            return response()->json(['error' => 'ليس لديك صلاحية لإنشاء معاملة مخزون'], 403);
        }

        $validated = $request->validate([
            'item_id' => 'required|exists:inventory_items,id',
            'warehouse_id' => 'required|exists:warehouses,id',
            'transaction_type' => 'required|in:purchase,sale,transfer,adjustment,maintenance_usage,return_from_customer,return_to_supplier,write_off',
            'quantity' => 'required|numeric|min:0.01',
            'to_warehouse_id' => 'required_if:transaction_type,transfer|exists:warehouses,id',
            'batch_id' => 'nullable|exists:inventory_batches,id',
            'serial_id' => 'nullable|exists:inventory_serials,id',
            'notes' => 'nullable|string|max:500',
        ]);

        DB::beginTransaction();
        try {
            // إنشاء المعاملة
            $transaction = new InventoryTransaction();
            $transaction->company_id = Auth::user()->company_id;
            $transaction->transaction_type = $validated['transaction_type'];
            $transaction->item_id = $validated['item_id'];
            $transaction->warehouse_id = $validated['warehouse_id'];
            $transaction->to_warehouse_id = $validated['to_warehouse_id'] ?? null;
            $transaction->quantity = $validated['quantity'];
            $transaction->batch_id = $validated['batch_id'] ?? null;
            $transaction->serial_id = $validated['serial_id'] ?? null;
            $transaction->created_by = Auth::id();
            $transaction->notes = $validated['notes'] ?? null;
            $transaction->save();

            // تحديث المخزون
            $this->updateStock($transaction);

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'تم إنشاء المعاملة بنجاح',
                'transaction' => $transaction,
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json(['error' => 'حدث خطأ أثناء إنشاء المعاملة: ' . $e->getMessage()], 500);
        }
    }

    /**
     * عرض صفحة طباعة الباركود المتعدد
     *
     * @return \Illuminate\Http\Response
     */
    public function printMultiple()
    {
        // التحقق من الصلاحيات
        if (!Auth::user()->can('generate_inventory_barcodes')) {
            return redirect()->route('inventory.barcodes.index')->with('error', 'ليس لديك صلاحية لطباعة الباركود');
        }

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

        return view('inventory.barcodes.print_multiple', compact('items'));
    }

    /**
     * معالجة طباعة الباركود المتعدد
     *
     * @param Request $request
     * @return \Illuminate\Http\Response
     */
    public function processPrintMultiple(Request $request)
    {
        // التحقق من الصلاحيات
        if (!Auth::user()->can('generate_inventory_barcodes')) {
            return redirect()->route('inventory.barcodes.index')->with('error', 'ليس لديك صلاحية لطباعة الباركود');
        }

        $validated = $request->validate([
            'items' => 'required|array',
            'items.*.id' => 'required|exists:inventory_items,id',
            'items.*.quantity' => 'required|integer|min:1|max:100',
            'barcode_type' => 'required|in:ean13,code128,qrcode',
            'include_price' => 'sometimes|boolean',
        ]);

        $barcodeItems = [];
        foreach ($validated['items'] as $itemData) {
            $item = InventoryItem::where('company_id', Auth::user()->company_id)
                ->findOrFail($itemData['id']);

            // تحديث رمز الباركود للعنصر إذا لم يكن موجودًا
            if (empty($item->barcode)) {
                $item->barcode = $this->generateBarcodeNumber();
                $item->save();
            }

            // إنشاء ملف الباركود
            $barcodeImage = $this->generateBarcodeImage($item->barcode, $validated['barcode_type']);
            $barcodeFilename = 'barcode_' . $item->id . '_' . time() . '.png';
            Storage::disk('public')->put('barcodes/' . $barcodeFilename, $barcodeImage);

            $barcodeItems[] = [
                'item' => $item,
                'quantity' => $itemData['quantity'],
                'barcode_image' => 'storage/barcodes/' . $barcodeFilename,
            ];
        }

        return view('inventory.barcodes.print_result', [
            'barcode_items' => $barcodeItems,
            'barcode_type' => $validated['barcode_type'],
            'include_price' => $validated['include_price'] ?? false,
        ]);
    }

    /**
     * إنشاء رقم باركود فريد
     *
     * @return string
     */
    private function generateBarcodeNumber()
    {
        // إنشاء رقم EAN-13 فريد
        $prefix = '200'; // رمز مخصص للشركة
        $randomPart = mt_rand(100000000, 999999999);
        $barcode = $prefix . $randomPart;

        // حساب رقم التحقق
        $sum = 0;
        for ($i = 0; $i < 12; $i++) {
            $sum += (int)$barcode[$i] * ($i % 2 == 0 ? 1 : 3);
        }
        $checkDigit = (10 - ($sum % 10)) % 10;

        return $barcode . $checkDigit;
    }

    /**
     * إنشاء صورة الباركود
     *
     * @param string $barcode
     * @param string $type
     * @return string
     */
    private function generateBarcodeImage($barcode, $type)
    {
        switch ($type) {
            case 'ean13':
                return base64_decode(DNS1D::getBarcodePNG($barcode, 'EAN13', 2, 60));
            case 'code128':
                return base64_decode(DNS1D::getBarcodePNG($barcode, 'C128', 2, 60));
            case 'qrcode':
                return QrCode::format('png')
                    ->size(200)
                    ->margin(1)
                    ->generate($barcode);
            default:
                return base64_decode(DNS1D::getBarcodePNG($barcode, 'C128', 2, 60));
        }
    }

    /**
     * تحديث المخزون بناءً على المعاملة
     *
     * @param InventoryTransaction $transaction
     * @return void
     */
    private function updateStock(InventoryTransaction $transaction)
    {
        $itemId = $transaction->item_id;
        $warehouseId = $transaction->warehouse_id;
        $quantity = $transaction->quantity;

        // الحصول على سجل المخزون أو إنشاء واحد جديد
        $stock = InventoryStock::firstOrNew([
            'company_id' => $transaction->company_id,
            'warehouse_id' => $warehouseId,
            'item_id' => $itemId,
        ]);

        if (!$stock->exists) {
            $stock->quantity = 0;
            $stock->reserved_quantity = 0;
            $stock->company_id = $transaction->company_id;
            $stock->warehouse_id = $warehouseId;
            $stock->item_id = $itemId;
        }

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

                // زيادة الكمية في المستودع الهدف
                $toStock = InventoryStock::firstOrNew([
                    'company_id' => $transaction->company_id,
                    'warehouse_id' => $transaction->to_warehouse_id,
                    'item_id' => $itemId,
                ]);

                if (!$toStock->exists) {
                    $toStock->quantity = 0;
                    $toStock->reserved_quantity = 0;
                    $toStock->company_id = $transaction->company_id;
                    $toStock->warehouse_id = $transaction->to_warehouse_id;
                    $toStock->item_id = $itemId;
                }

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

        $stock->save();

        // تحديث الرقم التسلسلي إذا كان موجودًا
        if ($transaction->serial_id) {
            $serial = InventorySerial::find($transaction->serial_id);
            if ($serial) {
                if ($transaction->transaction_type == 'transfer') {
                    $serial->warehouse_id = $transaction->to_warehouse_id;
                } elseif (in_array($transaction->transaction_type, ['sale', 'maintenance_usage'])) {
                    $serial->status = 'sold';
                } elseif ($transaction->transaction_type == 'return_from_customer') {
                    $serial->status = 'in_stock';
                    $serial->warehouse_id = $transaction->warehouse_id;
                }
                $serial->save();
            }
        }

        // تحديث الدفعة إذا كانت موجودة
        if ($transaction->batch_id) {
            $batch = InventoryBatch::find($transaction->batch_id);
            if ($batch) {
                if ($transaction->transaction_type == 'transfer') {
                    $batch->warehouse_id = $transaction->to_warehouse_id;
                }
                $batch->save();
            }
        }
    }
}
