<?php

namespace App\Http\Controllers\Modules\Inventory;

use App\Http\Controllers\Controller;
use App\Http\Traits\HasRoleViews;
use App\Http\Requests\Inventory\StoreRawMaterialRequest;
use App\Models\RawMaterial;
use App\Services\Inventory\RawMaterialService;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;

/**
 * Unified RawMaterial Controller
 *
 * Handles raw material management for all roles.
 * Views are automatically resolved based on the logged-in user's role.
 */
class RawMaterialController extends Controller
{
    use HasRoleViews;

    protected RawMaterialService $rawMaterialService;

    public function __construct(RawMaterialService $rawMaterialService)
    {
        $this->rawMaterialService = $rawMaterialService;
    }

    /**
     * Display the raw materials management page
     */
    public function index()
    {
        return $this->roleView('master.rawmaterials');
    }

    /**
     * Get raw materials list for DataTable/AJAX
     */
    public function list(): JsonResponse
    {
        $materials = RawMaterial::with('files')
            ->select('id', 'code', 'name', 'rm_grade', 'iso_specification', 'density', 'raw_material_type', 'quantity', 'status')
            ->orderBy('name', 'asc')
            ->get();

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

    /**
     * Get a single raw material for editing
     */
    public function show(RawMaterial $rawmaterial): JsonResponse
    {
        $rawmaterial->load('files');
        return response()->json($rawmaterial);
    }

    /**
     * Store a newly created raw material
     */
    public function store(StoreRawMaterialRequest $request): JsonResponse
    {
        try {
            $data = $request->validated();

            // Generate code if not provided
            if (empty($data['code'])) {
                $data['code'] = $this->rawMaterialService->generateCode();
            }

            // Handle file uploads
            $files = $request->file('files', []);

            $material = $this->rawMaterialService->createWithFiles($data, $files);

            return response()->json([
                'success' => true,
                'message' => 'Raw Material added successfully',
                'data' => $material,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to create raw material: ' . $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Update the specified raw material
     */
    public function update(StoreRawMaterialRequest $request, RawMaterial $rawmaterial): JsonResponse
    {
        try {
            $data = $request->validated();

            $rawmaterial->update($data);

            // Handle new file uploads
            $files = $request->file('files', []);
            if (!empty($files)) {
                foreach ($files as $file) {
                    $path = $file->store('raw-material-files', 'public');
                    $rawmaterial->files()->create([
                        'file_path' => $path,
                        'file_name' => $file->getClientOriginalName(),
                        'file_type' => $file->getMimeType(),
                        'file_size' => $file->getSize(),
                    ]);
                }
            }

            return response()->json([
                'success' => true,
                'message' => 'Raw Material updated successfully',
                'data' => $rawmaterial->fresh('files'),
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to update raw material: ' . $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Remove the specified raw material
     */
    public function destroy(RawMaterial $rawmaterial): JsonResponse
    {
        try {
            $rawmaterial->delete();

            return response()->json([
                'success' => true,
                'message' => 'Raw Material deleted successfully',
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to delete raw material: ' . $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Alias for destroy() - backward compatibility with old routes
     */
    public function delete(RawMaterial $rawmaterial): JsonResponse
    {
        return $this->destroy($rawmaterial);
    }

    /**
     * Delete a file attachment
     */
    public function deleteFile(int $id): JsonResponse
    {
        try {
            $this->rawMaterialService->deleteFile($id);

            return response()->json([
                'success' => true,
                'message' => 'File deleted successfully',
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to delete file: ' . $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Get active raw materials for dropdowns
     */
    public function getActive(): JsonResponse
    {
        $materials = $this->rawMaterialService->getActive();
        return response()->json(['data' => $materials]);
    }

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

    /**
     * Adjust stock for a raw material
     */
    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 {
            $material = $this->rawMaterialService->adjustStock(
                $id,
                $validated['quantity'],
                $validated['type'],
                $validated['reason'] ?? null
            );

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