<?php
namespace App\Http\Controllers\SuperAdmin;

use App\Http\Controllers\Controller;
use App\Models\EmployeeDetails;
use App\Models\Machines;
use App\Models\Process;
use App\Models\ProductType;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;

class SuperAdminProcessController extends Controller
{
    // Return the Blade view with necessary data
    public function index()
    {
        $productTypes = ProductType::select('id', 'name')->get();
        $machines     = Machines::with('operators')->get();
        // dd(json_encode($machines));
        $employees = EmployeeDetails::all();
        return view('superadmin.master.process', compact('productTypes', 'machines', 'employees'));
    }

    // Return process data for the DataTable (API)
    public function api(Request $request)
    {
        $query = Process::with('productType');
        if ($request->has('product_type_id')) {
            $query->where('product_type_id', $request->product_type_id);
        }
        $processes = $query->get();
        return response()->json(['data' => $processes]);
    }

    // Store a new process
    public function store(Request $request)
    {
        try {
            $request->validate([
                'product_type_id' => 'required|exists:product_types,id',
                'name'            => 'required|string|max:255',
                'order'           => 'required|integer',
                'machines'        => 'nullable|exists:machines,id',
                'operators'       => 'nullable|exists:employees,employee_id',
            ]);

            $process = Process::create($request->only(['product_type_id', 'name', 'order']));

            if ($request->machines) {
                $process->machines()->sync([$request->machines]);
            } else {
                $process->machines()->sync([]); // Unassign if not provided
            }

            if ($request->operators) {
                $process->operators()->sync([$request->operators]);
            } else {
                $process->operators()->sync([]); // Unassign if not provided
            }

            Log::info('Process created successfully', [
                'process_id' => $process->id,
                'data'       => $request->all(),
                'machines'   => $request->machines,
                'operators'  => $request->operators,
                'user_id'    => auth()->id(),
            ]);

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

        } catch (\Illuminate\Validation\ValidationException $e) {
            Log::error('Validation failed in Process@store', [
                'errors'  => $e->validator->errors(),
                'data'    => $request->all(),
                'user_id' => auth()->id(),
            ]);
            return response()->json(['success' => false, 'message' => 'Validation error', 'errors' => $e->validator->errors()], 422);

        } catch (\Exception $e) {
            Log::error('Exception in Process@store', [
                'error'   => $e->getMessage(),
                'trace'   => $e->getTraceAsString(),
                'data'    => $request->all(),
                'user_id' => auth()->id(),
            ]);
            return response()->json(['success' => false, 'message' => 'An unexpected error occurred.'], 500);
        }
    }

    public function assignOperators(Request $request)
    {
        $request->validate([
            'machine_id'  => 'required|exists:machines,id',
            'operators.*' => 'exists:employees,id',
        ]);
        $machine = Machines::findOrFail($request->machine_id);
        $machine->operators()->sync($request->operators ?? []);
        return response()->json(['success' => true, 'message' => 'Machines and operators assigned successfully']);
    }

    public function dismissOperators(Request $request, $id)
    {
        try {
            $machine = Machines::findOrFail($id);
            $machine->operators()->sync([]);
            return response()->json(['success' => true, 'message' => 'Operators dismissed successfully']);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => 'An unexpected error occurred.'], 500);
        }
    }

    public function assign(Request $request)
    {
        try {

            $request->validate([
                'process_id'  => 'required|exists:processes,id',
                'machines.*'  => 'exists:machines,id',
                'operators.*' => 'exists:employees,id',
                // 'assignment_mode' => 'required|in:m2o,o2m',
            ]);

            if ($request->assignment_mode === 'm2o') {
                // Multiple machines → one operator
                $request->validate([
                    'machines'   => 'required|array',
                    'machines.*' => 'exists:machines,id',
                    'operators'  => 'required|exists:employees,id',
                ]);
            } elseif ($request->assignment_mode === 'o2m') {
                // Multiple operators → one machine
                $request->validate([
                    'operators'   => 'required|array',
                    'operators.*' => 'exists:employees,id',
                    'machines'    => 'required|exists:machines,id',
                ]);
            }

            $machines  = is_array($request->machines) ? $request->machines : [$request->machines];
            $operators = is_array($request->operators) ? $request->operators : [$request->operators];

            $process = Process::findOrFail($request->process_id);

            // These will both be single-value arrays, that's OK for sync
            // $process->machines()->sync($request->machines ?? []);
            if (! empty($machines)) {
                $process->machines()->sync($machines ?? []);
            }

            if (! empty($operators)) {
                $process->operators()->sync($operators ?? []);
            }

            Log::info('Machines/Operators assigned successfully', [
                'process_id' => $process->id,
                'machines'   => $request->machines,
                'operators'  => $request->operators,
                'user_id'    => auth()->id(),
            ]);

            return response()->json(['success' => true, 'message' => 'Machines and operators assigned successfully']);

        } catch (\Illuminate\Validation\ValidationException $e) {
            Log::error('Validation failed in Process@assign', [
                'errors'  => $e->validator->errors(),
                'data'    => $request->all(),
                'user_id' => auth()->id(),
            ]);
            return response()->json(['success' => false, 'message' => 'Validation error', 'errors' => $e->validator->errors()], 422);

        } catch (\Exception $e) {
            Log::error('Exception in Process@assign', [
                'error'   => $e->getMessage(),
                'trace'   => $e->getTraceAsString(),
                'data'    => $request->all(),
                'user_id' => auth()->id(),
            ]);
            return response()->json(['success' => false, 'message' => 'An unexpected error occurred.'], 500);
        }
    }
// public function assignmentsApi()
// {
//     // eager load relationships to avoid N+1
//     $assignments = Process::with(['productType', 'machines', 'operators'])->get();

//     // Build data for the DataTable
//     $data = [];
//     foreach ($assignments as $process) {
//         // For single assignment, use first or null (or '' if null)
//         $machine = $process->machines->first();
//         $operator = $process->operators->first();
//         Log::Info("Operator Data: ". $operator);
//         $data[] = [
//             'process_name' => $process->name,
//             'product_type' => $process->productType ? $process->productType->name : '',
//             'machine' => $machine ? $machine->machine_name : '',
//             'operator' => $operator ? $operator->name : '',
//         ];
//     }

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

public function assignmentsApi()
{
    $assignments = Process::with(['productType', 'machines', 'operators'])->get();

    $data = [];

    foreach ($assignments as $process) {
        $productType = $process->productType ? $process->productType->name : '';

        // Loop through each machine
        foreach ($process->machines as $machine) {
            $machineName = $machine->machine_name;

            // Loop through each operator
            foreach ($process->operators as $operator) {
                $data[] = [
                    'process_name' => $process->name,
                    'product_type' => $productType,
                    'machine' => $machineName,
                    'operator' => $operator->name,
                ];
            }
        }
    }

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


    public function update(Request $request, $id)
    {
        $request->validate([
            'product_type_id' => 'required|exists:product_types,id',
            'name'            => 'required|string|max:255',
            'order'           => 'required|integer',
            'machines'        => 'array',
            'machines.*'      => 'exists:machines,id',
            'operators'       => 'array',
            'operators.*'     => 'exists:employees,employee_id',
        ]);

        $process = Process::findOrFail($id);
        $process->update($request->all());
        $process->machines()->sync($request->machines ?? []);
        $process->operators()->sync($request->operators ?? []);

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

    public function show($id)
    {
        $process = Process::with(['machines', 'operators'])->findOrFail($id);
        return response()->json($process);
    }

    // Delete a process
    public function destroy($id)
    {
        $process = Process::findOrFail($id);
        $process->delete();

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

//     public function viewMachines()
// {
//     $assignments = DB::table('process_machine')
//         ->join('processes', 'process_machine.process_id', '=', 'processes.id')
//         ->join('machines', 'process_machine.machine_id', '=', 'machines.id')
//         ->join('product_types', 'processes.product_type_id', '=', 'product_types.id')
//         ->select('processes.name as process_name', 'product_types.name as product_type', 'machines.machine_name as machine')
//         ->paginate(10);

//     return response()->json($assignments);
// }

public function viewMachinesSummary()
{
    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);
    }
}


// public function viewOperators()
// {
//     $assignments = DB::table('machine_operator')
//         ->join('machines', 'machine_operator.machine_id', '=', 'machines.id')
//         ->join('employee_details', 'machine_operator.employee_id', '=', 'employee_details.id')
//         ->join('process_machine', 'process_machine.machine_id', '=', 'machines.id')
//         ->join('processes', 'process_machine.process_id', '=', 'processes.id')
//         ->select('processes.name as process_name', 'machines.machine_name as machine', 'employee_details.name as operator')
//         ->paginate(10);

//     return response()->json($assignments);
// }

public function viewOperatorsSummary()
{
    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);
    }
}

}
