<?php

namespace App\Http\Controllers\Modules\Inventory;

use App\Http\Controllers\Controller;
use App\Http\Traits\HasRoleViews;
use App\Http\Requests\Inventory\StoreStockItemRequest;
use App\Imports\StockItemsImport;
use App\Models\Category;
use App\Models\StockItem;
use App\Services\Inventory\StockItemService;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Maatwebsite\Excel\Facades\Excel;

/**
 * Unified StockItem Controller
 *
 * Handles stock item management for all roles.
 * Views are automatically resolved based on the logged-in user's role.
 */
class StockItemController extends Controller
{
    use HasRoleViews;

    protected StockItemService $stockItemService;

    public function __construct(StockItemService $stockItemService)
    {
        $this->stockItemService = $stockItemService;
    }

    /**
     * Display the stock items management page
     */
    public function index()
    {
        $categories = Category::orderBy('name')->get();
        $stockItems = $this->stockItemService->getAllWithCategory();
        return $this->roleView('master.stockitems', compact('categories', 'stockItems'));
    }

    /**
     * Get stock items list for DataTable/AJAX
     */
    public function list(): JsonResponse
    {
        $stockItems = $this->stockItemService->getAllWithCategory();
        return response()->json(['data' => $stockItems]);
    }

    /**
     * Store a newly created stock item
     */
    public function store(StoreStockItemRequest $request)
    {
        try {
            $data = $request->validated();

            // Generate item code if not provided
            if (empty($data['item_code'])) {
                $data['item_code'] = $this->stockItemService->generateItemCode();
            }

            $data['created_by'] = auth()->id();
            $item = $this->stockItemService->create($data);

            if ($request->ajax() || $request->wantsJson()) {
                return response()->json([
                    'success' => true,
                    'message' => 'Item added successfully!',
                    'data' => $item,
                ]);
            }

            return redirect()->back()->with('success', 'Item added successfully!');
        } catch (\Exception $e) {
            if ($request->ajax() || $request->wantsJson()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Failed to add item: ' . $e->getMessage(),
                ], 500);
            }
            return redirect()->back()->with('error', 'Failed to add item: ' . $e->getMessage());
        }
    }

    /**
     * Update the specified stock item
     */
    public function update(StoreStockItemRequest $request, int $id)
    {
        try {
            $data = $request->validated();
            $data['updated_by'] = auth()->id();

            $item = $this->stockItemService->update($id, $data);

            if ($request->ajax() || $request->wantsJson()) {
                return response()->json([
                    'success' => true,
                    'message' => 'Item updated successfully!',
                    'data' => $item,
                ]);
            }

            return redirect()->back()->with('success', 'Item updated successfully!');
        } catch (\Exception $e) {
            if ($request->ajax() || $request->wantsJson()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Failed to update item: ' . $e->getMessage(),
                ], 500);
            }
            return redirect()->back()->with('error', 'Failed to update item: ' . $e->getMessage());
        }
    }

    /**
     * Remove the specified stock item
     */
    public function destroy(Request $request, int $id)
    {
        if (!$this->isSuperAdmin() && !$this->isManager()) {
            if ($request->ajax() || $request->wantsJson()) {
                return response()->json(['success' => false, 'message' => 'Unauthorized.'], 403);
            }
            abort(403, 'Unauthorized.');
        }

        try {
            $this->stockItemService->delete($id);

            if ($request->ajax() || $request->wantsJson()) {
                return response()->json([
                    'success' => true,
                    'message' => 'Item deleted successfully!',
                ]);
            }

            return redirect()->back()->with('success', 'Item deleted successfully!');
        } catch (\Exception $e) {
            if ($request->ajax() || $request->wantsJson()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Failed to delete item: ' . $e->getMessage(),
                ], 500);
            }
            return redirect()->back()->with('error', 'Failed to delete item: ' . $e->getMessage());
        }
    }

    /**
     * Store a newly created category
     */
    public function storeCategory(Request $request)
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255|unique:categories,name',
            'description' => 'nullable|string|max:500',
        ]);

        try {
            $category = Category::create($validated);

            if ($request->ajax() || $request->wantsJson()) {
                return response()->json([
                    'success' => true,
                    'message' => 'Category added successfully!',
                    'data' => $category,
                ]);
            }

            return redirect()->back()->with('success', 'Category added successfully!');
        } catch (\Exception $e) {
            if ($request->ajax() || $request->wantsJson()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Failed to add category: ' . $e->getMessage(),
                ], 500);
            }
            return redirect()->back()->with('error', 'Failed to add category: ' . $e->getMessage());
        }
    }

    /**
     * Get stock items by category
     */
    public function getByCategory(int $categoryId): JsonResponse
    {
        $items = $this->stockItemService->getByCategory($categoryId);
        return response()->json(['data' => $items]);
    }

    /**
     * Get active stock items
     */
    public function getActive(): JsonResponse
    {
        $items = $this->stockItemService->getActive();
        return response()->json(['data' => $items]);
    }

    /**
     * Get low stock items
     */
    public function getLowStock(): JsonResponse
    {
        $items = $this->stockItemService->getLowStock();
        return response()->json(['data' => $items]);
    }

    /**
     * Adjust stock for an item
     */
    public function adjustStock(Request $request, int $id): JsonResponse
    {
        $validated = $request->validate([
            'quantity' => 'required|numeric|min:0',
            'type' => 'required|in:add,remove',
            'reason' => 'nullable|string|max:500',
        ]);

        try {
            $item = $this->stockItemService->adjustStock(
                $id,
                $validated['quantity'],
                $validated['type'],
                $validated['reason'] ?? null
            );

            return response()->json([
                'success' => true,
                'message' => 'Stock adjusted successfully',
                'data' => $item,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to adjust stock: ' . $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Import stock items from Excel
     */
    public function import(Request $request)
    {
        $request->validate([
            'file' => 'required|mimes:xlsx,xls,csv|max:10240',
        ]);

        try {
            $import = new StockItemsImport();
            Excel::import($import, $request->file('file'));

            $summary = $import->getSummary();

            if ($summary['imported'] > 0) {
                $message = "Successfully imported {$summary['imported']} items.";
                if ($summary['skipped'] > 0) {
                    $message .= " Skipped {$summary['skipped']} items.";
                }
                return redirect()->back()->with('success', $message);
            } else {
                return redirect()->back()->with('warning', 'No items were imported. ' . implode(' ', $summary['errors']));
            }
        } catch (\Exception $e) {
            return redirect()->back()->with('error', 'Import failed: ' . $e->getMessage());
        }
    }

    /**
     * Alias for import - backward compatibility
     */
    public function importExcel(Request $request)
    {
        return $this->import($request);
    }
}
