<?php

namespace App\Http\Controllers\Modules\Manufacturing;

use App\Http\Controllers\Controller;
use App\Http\Traits\HasRoleViews;
use App\Models\RouteCard;
use App\Models\RouteCardProcess;
use App\Models\QcApproval;
use App\Models\EmployeeDetails;
use App\Models\SkuMaster;
use App\Models\SkuMovement;
use App\Models\MachineLog;
use App\Models\Machines;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;

/**
 * Unified Production Controller
 *
 * Handles production board, process control, QC approvals, and material consumption.
 * Reference: SuperAdminProductionController
 */
class ProductionController extends Controller
{
    use HasRoleViews;

    /**
     * Display the production board for a route card
     */
    public function productionBoard(int $rcId)
    {
        $routeCard = RouteCard::with(['processes.qcApprovals'])->findOrFail($rcId);
        $employees = EmployeeDetails::pluck('name', 'id');
        $skus = SkuMaster::select('id', 'item_name', 'current_stock')->get();

        return $this->roleView('manufacturing.production_board', compact('routeCard', 'employees', 'skus'));
    }

    /**
     * Display list of in-progress route cards
     */
    public function inProgressList()
    {
        $routeCards = RouteCard::whereIn('status', ['production', 'In Production'])->get();
        return $this->roleView('manufacturing.production_inprogress_list', compact('routeCards'));
    }

    /**
     * Start a process (with QC before check)
     *
     * Logic:
     * 1. If pending → create 'Before' QC and set status to 'qc_before'
     * 2. If 'qc_before' → check QC status before allowing start
     * 3. If QC approved → set status to 'in_progress'
     */
    public function startProcess(Request $request, int $processId): JsonResponse
    {
        $process = RouteCardProcess::findOrFail($processId);

        // Dependency Check
        if ($process->previous_process_id) {
            $prev = RouteCardProcess::find($process->previous_process_id);
            if ($prev && $prev->status != 'approved') {
                return response()->json(['error' => 'Previous process not completely approved yet.'], 422);
            }
        }

        // 1. Initial State -> Request Before QC
        if ($process->status == 'pending') {
            $qc = $process->qcApprovals()->where('stage', 'before')->first();
            if (!$qc) {
                $process->qcApprovals()->create([
                    'level' => 1,
                    'stage' => 'before',
                    'status' => 'pending',
                ]);
            }
            $process->status = 'qc_before';
            $process->operator = $request->operator ?? auth()->id();
            $process->save();

            return response()->json([
                'success' => true,
                'message' => 'Before-Process QC Requested',
                'process' => $process,
                'status' => 'qc_before',
            ]);
        }

        // 2. QC Before Phase
        if ($process->status == 'qc_before') {
            $qc = $process->qcApprovals()->where('stage', 'before')->latest()->first();

            if ($qc && $qc->status == 'pending') {
                return response()->json(['error' => 'Waiting for Before-Production QC Approval.'], 422);
            }
            if ($qc && $qc->status == 'rejected') {
                return response()->json(['error' => 'Before-Production QC Rejected. Please fix and re-request.'], 422);
            }
            if ($qc && $qc->status == 'approved') {
                // QC Passed, NOW start production
                $process->actual_start = now();
                $process->status = 'in_progress';
                $process->operator = $request->operator ?? auth()->id();
                $process->save();

                return response()->json([
                    'success' => true,
                    'message' => 'Production Started',
                    'process' => $process,
                    'status' => 'in_progress',
                ]);
            }
        }

        // 3. Already Started?
        if ($process->status == 'in_progress') {
            return response()->json(['error' => 'Process already in progress.'], 422);
        }

        return response()->json(['error' => 'Invalid status transition from ' . $process->status], 422);
    }

    /**
     * End a process (creates 'After' QC)
     */
    public function endProcess(Request $request, int $processId): JsonResponse
    {
        $process = RouteCardProcess::findOrFail($processId);

        if ($process->status != 'in_progress') {
            return response()->json(['error' => 'Process must be In Progress to end.'], 422);
        }

        if ($process->actual_end) {
            return response()->json(['error' => 'Process already ended.'], 422);
        }

        // Create 'After' QC
        $qc = $process->qcApprovals()->where('stage', 'after')->where('status', 'pending')->first();
        if (!$qc) {
            $process->qcApprovals()->create([
                'level' => 1,
                'stage' => 'after',
                'status' => 'pending',
            ]);
        }

        $process->actual_end = now();
        $process->status = 'qc_after';
        $process->save();

        return response()->json([
            'success' => true,
            'message' => 'Process Ended. Sent for Final QC.',
            'process' => $process,
            'status' => 'qc_after',
        ]);
    }

    /**
     * Request a random QC check during production
     */
    public function requestDuringQC(Request $request, int $processId): JsonResponse
    {
        $process = RouteCardProcess::findOrFail($processId);

        if ($process->status != 'in_progress') {
            return response()->json(['error' => 'Process must be In Progress to request Random QC.'], 422);
        }

        $process->qcApprovals()->create([
            'level' => 1,
            'stage' => 'during',
            'status' => 'pending',
        ]);

        return response()->json(['success' => true, 'message' => 'Random QC Requested']);
    }

    /**
     * Approve a QC request (SuperAdmin and Manager only)
     */
    public function approveQC(Request $request, int $qcId): JsonResponse
    {
        // Authorization check - only SuperAdmin and Manager can approve QC
        if (!$this->isSuperAdmin() && !$this->isManager()) {
            return response()->json([
                'success' => false,
                'error' => 'Unauthorized. Only SuperAdmin and Manager can approve QC.'
            ], 403);
        }

        $qc = QcApproval::find($qcId);
        if (!$qc) {
            return response()->json(['error' => 'QC not found'], 404);
        }

        $qc->status = 'approved';
        $qc->approved_by = auth()->id();
        $qc->approved_at = now();
        $qc->remarks = $request->remarks;
        $qc->save();

        // Update Process Status based on Stage
        $process = $qc->process;
        if ($process) {
            if ($qc->stage == 'after') {
                // Final approval -> Process Complete
                $process->status = 'approved';
                $process->save();

                // Check if all processes on the route card are approved
                $routeCard = RouteCard::with('processes')->find($process->route_card_id);
                if ($routeCard) {
                    $allApproved = $routeCard->processes->every(fn($p) => $p->status === 'approved');
                    if ($allApproved) {
                        $routeCard->status = 'completed';
                        $routeCard->save();

                        // Add produced goods to inventory if matching SKU exists
                        $sku = SkuMaster::where('item_name', $routeCard->description)
                            ->orWhere('item_name', $routeCard->part_no)
                            ->first();

                        if ($sku) {
                            $sku->addStock(
                                1, // Default to 1 unit per route card
                                'PROD-RC-' . $routeCard->route_no,
                                'Production completed: Route Card ' . $routeCard->route_no
                            );

                            Log::info('[Production] Route card completed and stock updated', [
                                'route_card' => $routeCard->route_no,
                                'sku' => $sku->item_name,
                            ]);
                        }
                    }
                }
            }
            // For 'before' and 'during', no automatic status change
        }

        return response()->json(['success' => true]);
    }

    /**
     * Reject a QC request (SuperAdmin and Manager only)
     */
    public function rejectQC(Request $request, int $qcId): JsonResponse
    {
        // Authorization check - only SuperAdmin and Manager can reject QC
        if (!$this->isSuperAdmin() && !$this->isManager()) {
            return response()->json([
                'success' => false,
                'error' => 'Unauthorized. Only SuperAdmin and Manager can reject QC.'
            ], 403);
        }

        $qc = QcApproval::find($qcId);
        if (!$qc) {
            return response()->json(['error' => 'QC not found'], 404);
        }

        $qc->status = 'rejected';
        $qc->approved_by = auth()->id();
        $qc->approved_at = now();
        $qc->remarks = $request->remarks;
        $qc->rejection_reason = $request->rejection_reason;
        $qc->save();

        $process = $qc->process;
        if ($process) {
            $process->status = 'rework';
            $process->save();
        }

        return response()->json(['success' => true]);
    }

    /**
     * Log a machine breakdown
     */
    public function logMachineBreakdown(Request $request): JsonResponse
    {
        $request->validate([
            'machine_id' => 'required',
            'reason' => 'required',
            'start_time' => 'required|date',
        ]);

        // Lookup machine ID if the input is a string (Name)
        $machineId = $request->machine_id;
        if (!is_numeric($machineId)) {
            $machine = Machines::where('machine_name', $machineId)
                ->orWhere('machine_id', $machineId)
                ->first();
            if ($machine) {
                $machineId = $machine->id;
            }
        }

        MachineLog::create([
            'machine_id' => $machineId,
            'reason' => $request->reason,
            'start_time' => $request->start_time,
            'reported_by' => auth()->id(),
        ]);

        return response()->json(['success' => true]);
    }

    /**
     * Consume material from SKU
     */
    public function consumeMaterial(Request $request): JsonResponse
    {
        $request->validate([
            'sku_id' => 'required|exists:skumaster,id',
            'quantity' => 'required|numeric|min:0.01',
            'process_id' => 'required',
        ]);

        $sku = SkuMaster::find($request->sku_id);

        if ($sku->current_stock < $request->quantity) {
            return response()->json([
                'success' => false,
                'message' => 'Insufficient Stock! Available: ' . $sku->current_stock,
            ]);
        }

        $sku->current_stock -= $request->quantity;
        $sku->save();

        // Log Movement
        SkuMovement::create([
            'reference' => 'PROD-' . $request->process_id,
            'sku_id' => $sku->id,
            'product' => $sku->item_name,
            'type' => 'outbound',
            'quantity' => $request->quantity,
            'from_location' => 'Inventory',
            'to_location' => 'Production',
            'date' => now(),
            'status' => 'completed',
            'notes' => 'Consumed in Process #' . $request->process_id,
        ]);

        return response()->json([
            'success' => true,
            'message' => 'Material Consumed',
            'new_stock' => $sku->current_stock,
        ]);
    }
}
