<?php

namespace Modules\SystemCore\App\Http\Controllers;

use App\Helpers\FormattingHelper;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Modules\SystemCore\App\Enums\ProductStatus;
use Modules\SystemCore\App\Http\Requests\StoreProductRequest;
use Modules\SystemCore\App\Http\Requests\UpdateProductRequest;
use Modules\SystemCore\App\Models\CoreProduct;
use Modules\SystemCore\App\Models\CoreProductCategory;

class ProductController extends Controller
{
    public function index()
    {
        $this->authorize('systemcore.view-products');

        $categories = CoreProductCategory::all();

        $warehouses = collect();
        if (moduleExists('WMSInventoryCore') && class_exists(\Modules\WMSInventoryCore\App\Models\Warehouse::class)) {
            $warehouses = \Modules\WMSInventoryCore\App\Models\Warehouse::all();
        }

        return view('systemcore::products.index', [
            'categories' => $categories,
            'warehouses' => $warehouses,
        ]);
    }

    public function indexAjax(Request $request)
    {
        $this->authorize('systemcore.view-products');

        $query = CoreProduct::with(['category', 'tax', 'inventories'])
            ->select('core_products.*');

        // Search (DataTables sends search.value)
        if ($request->filled('search.value')) {
            $search = $request->input('search.value');
            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                    ->orWhere('sku', 'like', "%{$search}%")
                    ->orWhere('product_code', 'like', "%{$search}%")
                    ->orWhere('barcode', 'like', "%{$search}%");
            });
        }

        // Filter by category
        if ($request->filled('category_id')) {
            $query->where('category_id', $request->category_id);
        }

        // Filter by status
        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }

        // Filter by warehouse
        if ($request->filled('warehouse_id')) {
            $query->whereHas('inventories', function ($q) use ($request) {
                $q->where('warehouse_id', $request->warehouse_id);
            });
        }

        return datatables($query)
            ->addColumn('actions', function ($product) {
                return view('components.datatable-actions', [
                    'id' => $product->id,
                    'actions' => [
                        ['label' => __('View'), 'icon' => 'bx bx-show', 'url' => route('systemcore.products.show', $product->id)],
                        ['label' => __('Edit'), 'icon' => 'bx bx-edit', 'url' => route('systemcore.products.edit', $product->id)],
                        ['label' => __('Delete'), 'icon' => 'bx bx-trash', 'onclick' => "deleteProduct({$product->id})"],
                    ],
                ])->render();
            })
            ->addColumn('image_display', function ($product) {
                if ($product->thumbnail) {
                    return '<img src="'.asset('storage/'.$product->thumbnail).'" alt="'.e($product->name).'" class="rounded" width="50" height="50" style="object-fit: cover;">';
                }

                return '-';
            })
            ->addColumn('stock', function ($product) {
                return $product->inventories->sum('stock_level');
            })
            ->editColumn('category', fn ($product) => $product->category?->name ?? '-')
            ->editColumn('base_price', fn ($product) => number_format($product->base_price, 2))
            ->editColumn('selling_price', fn ($product) => number_format($product->selling_price, 2))
            ->editColumn('status', fn ($product) => "<span class='badge bg-{$product->status->color()}'>{$product->status->label()}</span>")
            ->rawColumns(['status', 'actions', 'image_display'])
            ->make(true);
    }

    public function create()
    {
        $this->authorize('systemcore.create-product');

        $categories = CoreProductCategory::all();

        $units = collect();
        if (moduleExists('WMSInventoryCore') && class_exists(\Modules\WMSInventoryCore\App\Models\Unit::class)) {
            $units = \Modules\WMSInventoryCore\App\Models\Unit::all();
        }

        return view('systemcore::products.create', [
            'categories' => $categories,
            'units' => $units,
        ]);
    }

    public function store(StoreProductRequest $request)
    {
        $validated = $request->validated();

        try {
            $product = null;
            DB::transaction(function () use ($validated, $request, &$product) {
                // Auto-generate SKU if WMS module provides this
                if (moduleExists('WMSInventoryCore')
                    && class_exists(\Modules\WMSInventoryCore\App\Services\WMSInventoryCoreSettingsService::class)
                    && \Modules\WMSInventoryCore\App\Services\WMSInventoryCoreSettingsService::isAutoGenerateSku()
                    && empty($validated['sku'])) {
                    $validated['sku'] = \Modules\WMSInventoryCore\App\Services\WMSInventoryCoreSettingsService::generateNextSku();
                }

                $product = CoreProduct::create([
                    'name' => $validated['name'],
                    'product_code' => $validated['product_code'] ?? null,
                    'sku' => $validated['sku'] ?? null,
                    'barcode' => $validated['barcode'] ?? null,
                    'category_id' => $validated['category_id'] ?? null,
                    'brand' => $validated['brand'] ?? null,
                    'description' => $validated['description'] ?? null,
                    'base_price' => $validated['base_price'],
                    'cost_price' => $validated['cost_price'] ?? null,
                    'selling_price' => $validated['selling_price'],
                    'tax_id' => $validated['tax_id'] ?? null,
                    'unit_of_measure' => $validated['unit_of_measure'] ?? null,
                    'weight' => $validated['weight'] ?? null,
                    'weight_unit' => $validated['weight_unit'] ?? null,
                    'min_stock_level' => $validated['min_stock_level'] ?? null,
                    'max_stock_level' => $validated['max_stock_level'] ?? null,
                    'reorder_level' => $validated['reorder_level'] ?? null,
                    'thumbnail' => $validated['thumbnail'] ?? null,
                    'is_trackable' => $request->boolean('is_trackable'),
                    'status' => $validated['status'],
                    'created_by_id' => auth()->id(),
                    'updated_by_id' => auth()->id(),
                ]);
            });

            return redirect()->route('systemcore.products.show', $product->id)
                ->with('success', __('Product created successfully'));
        } catch (\Exception $e) {
            Log::error('Failed to create product: '.$e->getMessage());

            return redirect()->back()
                ->with('error', __('Failed to create product'))
                ->withInput();
        }
    }

    public function show(CoreProduct $product)
    {
        $this->authorize('systemcore.view-products');

        $product->load([
            'category',
            'tax',
            'variants',
            'pricingRules',
            'inventories.warehouse',
        ]);

        // Calculate statistics
        $totalStock = $product->inventories->sum('stock_level');
        $totalValue = FormattingHelper::formatCurrency($totalStock * $product->base_price);

        $stats = [
            'variants_count' => $product->variants()->count(),
            'base_price' => $product->base_price,
            'cost_price' => $product->cost_price,
            'selling_price' => $product->selling_price,
            'profit_margin' => $product->cost_price > 0 ? (($product->selling_price - $product->cost_price) / $product->cost_price) * 100 : 0,
        ];

        // Get warehouse stock information
        $warehouseStock = $product->inventories->map(function ($inventory) use ($product) {
            return (object) [
                'warehouse' => $inventory->warehouse,
                'available_quantity' => $inventory->available_quantity ?? $inventory->stock_level,
                'reserved_quantity' => $inventory->reserved_quantity ?? 0,
                'value' => FormattingHelper::formatCurrency($inventory->stock_level * $product->base_price),
            ];
        });

        // Get recent transactions (only if WMS module exists)
        $transactions = collect();
        if (moduleExists('WMSInventoryCore')) {
            $transactions = DB::table('inventory_transactions as it')
                ->join('warehouses as w', 'it.warehouse_id', '=', 'w.id')
                ->where('it.core_product_id', $product->id)
                ->whereNull('it.deleted_at')
                ->select([
                    'it.*',
                    'w.name as warehouse_name',
                ])
                ->orderBy('it.created_at', 'desc')
                ->limit(10)
                ->get()
                ->map(function ($transaction) {
                    $transaction->warehouse = (object) ['name' => $transaction->warehouse_name];

                    return $transaction;
                });
        }

        return view('systemcore::products.show', compact(
            'product',
            'stats',
            'totalStock',
            'totalValue',
            'warehouseStock',
            'transactions'
        ));
    }

    public function edit(CoreProduct $product)
    {
        $this->authorize('systemcore.edit-product');

        $categories = CoreProductCategory::all();

        $units = collect();
        if (moduleExists('WMSInventoryCore') && class_exists(\Modules\WMSInventoryCore\App\Models\Unit::class)) {
            $units = \Modules\WMSInventoryCore\App\Models\Unit::all();
        }

        return view('systemcore::products.edit', compact('product', 'categories', 'units'));
    }

    public function update(UpdateProductRequest $request, CoreProduct $product)
    {
        $validated = $request->validated();

        try {
            DB::transaction(function () use ($product, $validated, $request) {
                $product->update([
                    'name' => $validated['name'],
                    'product_code' => $validated['product_code'] ?? $product->product_code,
                    'sku' => $validated['sku'] ?? $product->sku,
                    'barcode' => $validated['barcode'] ?? null,
                    'category_id' => $validated['category_id'] ?? null,
                    'brand' => $validated['brand'] ?? null,
                    'description' => $validated['description'] ?? null,
                    'base_price' => $validated['base_price'],
                    'cost_price' => $validated['cost_price'] ?? null,
                    'selling_price' => $validated['selling_price'],
                    'tax_id' => $validated['tax_id'] ?? null,
                    'unit_of_measure' => $validated['unit_of_measure'] ?? null,
                    'weight' => $validated['weight'] ?? null,
                    'weight_unit' => $validated['weight_unit'] ?? null,
                    'min_stock_level' => $validated['min_stock_level'] ?? null,
                    'max_stock_level' => $validated['max_stock_level'] ?? null,
                    'reorder_level' => $validated['reorder_level'] ?? null,
                    'thumbnail' => $validated['thumbnail'] ?? $product->thumbnail,
                    'is_trackable' => $request->boolean('is_trackable'),
                    'status' => $validated['status'],
                    'updated_by_id' => auth()->id(),
                ]);
            });

            return redirect()->route('systemcore.products.show', $product->id)
                ->with('success', __('Product updated successfully'));
        } catch (\Exception $e) {
            Log::error('Failed to update product: '.$e->getMessage());

            return redirect()->back()
                ->with('error', __('Failed to update product'))
                ->withInput();
        }
    }

    public function destroy(CoreProduct $product)
    {
        $this->authorize('systemcore.delete-product');

        try {
            // Check if product has active inventory
            if ($product->inventories()->where('stock_level', '>', 0)->exists()) {
                return response()->json([
                    'success' => false,
                    'message' => __('Cannot delete product with active inventory. Please clear all stock first.'),
                ], 422);
            }

            DB::transaction(function () use ($product) {
                // Delete related inventory records (zero-stock)
                $product->inventories()->delete();

                // Delete variant records
                $product->variants()->delete();

                // Delete pricing rules
                $product->pricingRules()->delete();

                // Delete the product
                $product->delete();
            });

            return response()->json([
                'success' => true,
                'message' => __('Product deleted successfully'),
            ]);
        } catch (\Exception $e) {
            Log::error('Failed to delete product: '.$e->getMessage());

            return response()->json([
                'success' => false,
                'message' => __('Failed to delete product'),
            ], 500);
        }
    }

    /**
     * Upload product image via Dropzone
     */
    public function uploadImage(Request $request)
    {
        $request->validate([
            'file' => ['required', 'image', 'max:2048'],
        ]);

        $path = $request->file('file')->store('products', 'public');

        return response()->json(['path' => $path]);
    }

    /**
     * Search products for AJAX (Select2)
     */
    public function search(Request $request)
    {
        $query = CoreProduct::where('status', ProductStatus::Active->value);

        // Support both 'q' (Select2) and 'search' parameters
        $searchTerm = $request->input('q') ?? $request->input('search', '');

        if ($searchTerm) {
            $query->where(function ($q) use ($searchTerm) {
                $q->where('name', 'like', "%{$searchTerm}%")
                    ->orWhere('sku', 'like', "%{$searchTerm}%")
                    ->orWhere('product_code', 'like', "%{$searchTerm}%")
                    ->orWhere('barcode', 'like', "%{$searchTerm}%");
            });
        }

        // Pagination for Select2
        $page = $request->input('page', 1);
        $perPage = 20;

        $products = $query->with('taxConfiguration:id,name,rate')
            ->select([
                'id',
                'name',
                'sku',
                'product_code',
                'base_price',
                'cost_price',
                'selling_price',
                'tax_id',
            ])
            ->orderBy('name')
            ->skip(($page - 1) * $perPage)
            ->take($perPage)
            ->get();

        return response()->json($products);
    }
}
