<?php

namespace App\Http\Controllers\Modules\MasterData;

use App\Http\Controllers\Controller;
use App\Http\Traits\HasRoleViews;
use Illuminate\Support\Facades\Log;
use App\Models\EmployeeDetails;
use App\Models\Machines;
use App\Models\Process;
use App\Models\ProductType;
use App\Services\MasterData\ProcessService;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;

/**
 * Unified Process Controller
 *
 * Handles manufacturing process management for all roles.
 * Views are automatically resolved based on the logged-in user's role.
 */
class ProcessController extends Controller
{
    use HasRoleViews;

    protected ProcessService $processService;

    public function __construct(ProcessService $processService)
    {
        $this->processService = $processService;
    }

    /**
     * Display the process management page
     */
    public function index()
    {
        $productTypes = ProductType::select('id', 'name')->get();
        $machines = Machines::select('id', 'machine_name')->get();
        $employees = EmployeeDetails::select('id', 'name')->get();
        return $this->roleView('master.process', compact('productTypes', 'machines', 'employees'));
    }

    /**
     * Get process list for DataTable/AJAX
     *
     * @deprecated Use list() for consistency with other controllers
     */
    public function api(): JsonResponse
    {
        return $this->list();
    }

    /**
     * Get process list for DataTable/AJAX (standard naming convention)
     */
    public function list(): JsonResponse
    {
        $processes = $this->processService->getAllWithConversionType();
        return response()->json(['data' => $processes]);
    }

    /**
     * Get a single process for editing
     */
    public function show(int $id): JsonResponse
    {
        $process = $this->processService->findById($id);

        if (!$process) {
            return response()->json(['error' => 'Process not found'], 404);
        }

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

    /**
     * Store a newly created process
     */
    public function store(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'product_type_id' => 'required|exists:product_types,id',
            'name' => 'required|string|max:255',
            'order' => 'required|integer|min:1',
        ]);

        $this->processService->create($validated);

        return response()->json([
            'success' => true,
            'message' => 'Process added successfully',
        ]);
    }

    /**
     * Update the specified process
     */
    public function update(Request $request, int $id): JsonResponse
    {
        $validated = $request->validate([
            'product_type_id' => 'required|exists:product_types,id',
            'name' => 'required|string|max:255',
            'order' => 'required|integer|min:1',
        ]);

        $process = $this->processService->findById($id);

        if (!$process) {
            return response()->json(['error' => 'Process not found'], 404);
        }

        $this->processService->update($id, $validated);

        return response()->json([
            'success' => true,
            'message' => 'Process updated successfully',
        ]);
    }

    /**
     * Remove the specified process
     */
    public function destroy(int $id): JsonResponse
    {
        $process = $this->processService->findById($id);

        if (!$process) {
            return response()->json(['error' => 'Process not found'], 404);
        }

        $this->processService->delete($id);

        return response()->json([
            'success' => true,
            'message' => 'Process deleted successfully',
        ]);
    }

    /**
     * Get machines summary with operators
     */
    public function viewMachinesSummary(): JsonResponse
    {
        try {
            $assignments = Process::with(['productType', 'machines', 'machines.operators'])
                ->has('machines', '>', 0)
                ->get();
            return response()->json(['data' => $assignments]);
        } catch (\Throwable $e) {
            \Log::error('viewMachinesSummary error: ' . $e->getMessage());
            return response()->json(['error' => 'Internal Server Error'], 500);
        }
    }

    /**
     * Get operators summary by machine
     */
    public function viewOperatorsSummary(): JsonResponse
    {
        try {
            $assignments = Machines::with('operators')
                ->has('operators', '>', 0)
                ->get();

            $data = $assignments->map(function ($machine) {
                return [
                    'id' => $machine->id,
                    'machine_name' => $machine->machine_name,
                    'operators' => $machine->operators->map(fn($op) => [
                        'id' => $op->id,
                        'name' => $op->name
                    ])
                ];
            });

            return response()->json(['data' => $data]);
        } catch (\Throwable $e) {
            \Log::error('viewOperatorsSummary error: ' . $e->getMessage());
            return response()->json(['error' => 'Internal Server Error'], 500);
        }
    }
    
    /**
     * assign machines
     */
    public function assign(Request $request)
    {
        try {
            // Optional: log the incoming request
            Log::info('Assign request data', $request->all());

            // Validate input
            $request->validate([
                'process_id' => 'required|exists:processes,id',
                'machines' => 'nullable|array',
                'machines.*' => 'exists:machines,id',
            ]);

            // Example: assign machines to the process
            $process = Process::findOrFail($request->process_id);
            $process->machines()->sync($request->machines);

            return response()->json([
                'success' => true,
                'message' => 'Machines assigned successfully'
            ]);
        } catch (\Exception $e) {
            Log::error('Assign failed', ['error' => $e->getMessage()]);
            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 500);
        }
    }
    
    /**
     * assign Operators
     */
    public function assignOperators(Request $request)
    {
        try {

            $validated = $request->validate([
                'machine_id' => 'required|exists:machines,id',
                'operators' => 'nullable|array',
                'operators.*' => 'exists:employees,id', // FIXED
            ]);

            $machine = Machines::findOrFail($validated['machine_id']);

            $machine->operators()->sync($validated['operators'] ?? []);

            return response()->json([
                'success' => true,
                'message' => 'Operators updated successfully'
            ]);

        } catch (\Throwable $e) {

            Log::error('Assign Operators Error: '.$e->getMessage());

            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 500);
        }
    }

    public function dismissOperators($id)
    {
        $machine = Machines::findOrFail($id);
        $machine->operators()->detach();

        return response()->json([
            'success' => true,
            'message' => 'Operators removed successfully'
        ]);
    }
}
