<?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\SalesOrder;
use App\Models\Process;
use App\Models\Machines;
use App\Models\ProductType;
use App\Models\CustomerVendor;
use App\Models\EmployeeDetails;
use App\Services\Manufacturing\RouteCardService;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

/**
 * Unified RouteCard Controller
 *
 * Handles route card management for all roles.
 * Views are automatically resolved based on the logged-in user's role.
 */
class RouteCardController extends Controller
{
    use HasRoleViews;

    protected RouteCardService $routeCardService;

    public function __construct(RouteCardService $routeCardService)
    {
        $this->routeCardService = $routeCardService;
    }

    /**
     * Display the route card creation form
     * Alias: routeCardPage() for backward compatibility
     */
    public function routeCardPage()
    {
        return $this->create();
    }

    /**
     * Display the route card list page
     * Alias: routeCardDetails() for backward compatibility
     */
    public function routeCardDetails()
    {
        return $this->index();
    }

    /**
     * Display the route card creation form
     */
    public function create()
    {
        $saleOrders = SalesOrder::where('status', 'approved')->get();
        $processes = Process::orderBy('order')->get();
        $machines = Machines::where('status', 'active')->get();
        $productTypes = ProductType::active()->orderByName()->get();
        $saleOrder = null; // For new route cards, no pre-selected order

        $nextRouteNo = $this->routeCardService->generateRouteCardNumber();

        return $this->roleView('routecard.routecardorder', compact(
            'saleOrders',
            'saleOrder',
            'processes',
            'machines',
            'productTypes',
            'nextRouteNo'
        ));
    }

    /**
     * Generate route card number (AJAX)
     */
    public function generateNumber(): JsonResponse
    {
        $number = $this->routeCardService->generateRouteCardNumber();
        return response()->json(['route_no' => $number]);
    }

    /**
     * Store a newly created route card
     */
    public function store(Request $request)
    {
        try {
            $validated = $request->validate([
                'route_no' => 'required|string|unique:route_cards,route_no',
                'sales_order_id' => 'required|exists:sales_orders,id',
                'date' => 'required|date',
                'processes' => 'required|array|min:1',
            ]);

            DB::beginTransaction();

            $routeCard = RouteCard::create([
                'route_no' => $request->route_no,
                'sales_order_id' => $request->sales_order_id,
                'date' => $request->date,
                'remarks' => $request->remarks,
                'status' => 'pending',
            ]);

            foreach ($request->processes as $index => $processData) {
                RouteCardProcess::create([
                    'route_card_id' => $routeCard->id,
                    'process_id' => $processData['process_id'],
                    'machine_id' => $processData['machine_id'] ?? null,
                    'sequence' => $index + 1,
                    'estimated_time' => $processData['estimated_time'] ?? null,
                    'instructions' => $processData['instructions'] ?? null,
                    'status' => 'pending',
                ]);
            }

            DB::commit();

            return $this->redirectToRoute('manufacturing.routecard.index')
                ->with('success', 'Route Card created successfully.');

        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Route Card Store Error: ' . $e->getMessage());
            return back()->with('error', 'Something went wrong while creating Route Card.');
        }
    }

    /**
     * Display the route card list page
     */
    public function index()
    {
        $cards = RouteCard::with(['salesOrder', 'processes'])->latest()->get();
        return $this->roleView('routecard.routecarddetails', compact('cards'));
    }

    /**
     * Display the specified route card
     */
    public function show(int $id)
    {
        $routeCard = RouteCard::with(['salesOrder', 'processes.process', 'processes.machine'])->findOrFail($id);
        $routeCardProcesses = $routeCard->processes;
        return $this->roleView('routecard.show', compact('routeCard', 'routeCardProcesses'));
    }

    /**
     * Display the edit form
     */
    public function edit(int $id)
    {
        $card = RouteCard::with('processes')->findOrFail($id);
        $salesOrders = SalesOrder::where('status', 'approved')->get();
        $processes = Process::orderBy('order')->get();
        $machines = Machines::where('status', 'active')->get();
        $companies = CustomerVendor::all();
        $productTypes = ProductType::active()->orderByName()->get();
        $machineAvailability = []; // Machine availability status lookup
        $employees = EmployeeDetails::all();
        $operatorAvailability = []; // Operator availability status lookup
        $processAssignments = []; // Process assignments lookup
        $productTypeNameToId = $productTypes->pluck('id', 'name')->toArray();

        return $this->roleView('routecard.edit', compact(
            'card',
            'salesOrders',
            'processes',
            'machines',
            'companies',
            'productTypes',
            'machineAvailability',
            'employees',
            'operatorAvailability',
            'processAssignments',
            'productTypeNameToId'
        ));
    }

    /**
     * Update the specified route card
     */
    public function update(Request $request, int $id)
    {
        try {
            $routeCard = RouteCard::findOrFail($id);

            $validated = $request->validate([
                'route_no' => 'required|string|unique:route_cards,route_no,' . $id,
                'sales_order_id' => 'required|exists:sales_orders,id',
                'date' => 'required|date',
                'processes' => 'required|array|min:1',
            ]);

            DB::beginTransaction();

            $routeCard->update([
                'route_no' => $request->route_no,
                'sales_order_id' => $request->sales_order_id,
                'date' => $request->date,
                'remarks' => $request->remarks,
            ]);

            // Update processes
            $routeCard->processes()->delete();
            foreach ($request->processes as $index => $processData) {
                RouteCardProcess::create([
                    'route_card_id' => $routeCard->id,
                    'process_id' => $processData['process_id'],
                    'machine_id' => $processData['machine_id'] ?? null,
                    'sequence' => $index + 1,
                    'estimated_time' => $processData['estimated_time'] ?? null,
                    'instructions' => $processData['instructions'] ?? null,
                    'status' => $processData['status'] ?? 'pending',
                ]);
            }

            DB::commit();

            return $this->redirectToRoute('manufacturing.routecard.index')
                ->with('success', 'Route Card updated successfully.');

        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Route Card Update Error: ' . $e->getMessage());
            return back()->with('error', 'Something went wrong while updating Route Card.');
        }
    }

    /**
     * Remove the specified route card
     */
    public function destroy(int $id): JsonResponse
    {
        // Authorization check - only SuperAdmin and Manager can delete
        if (!$this->isSuperAdmin() && !$this->isManager()) {
            return response()->json([
                'success' => false,
                'message' => 'Unauthorized. Only SuperAdmin and Manager can delete route cards.'
            ], 403);
        }

        try {
            $routeCard = RouteCard::findOrFail($id);

            // Prevent deletion of approved or in-progress route cards by non-SuperAdmin
            if (in_array($routeCard->status, [RouteCard::STATUS_APPROVED, RouteCard::STATUS_IN_PROGRESS, RouteCard::STATUS_COMPLETED])
                && !$this->isSuperAdmin()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Cannot delete approved or in-progress route cards. Contact SuperAdmin.'
                ], 403);
            }

            $routeCard->processes()->delete();
            $routeCard->delete();

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

    /**
     * Approve a route card (SuperAdmin only)
     */
    public function approve(int $id): JsonResponse
    {
        if (!$this->isSuperAdmin()) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

        $routeCard = RouteCard::findOrFail($id);
        $routeCard->status = 'approved';
        $routeCard->save();

        return response()->json(['success' => true, 'message' => 'Route Card approved!']);
    }

    /**
     * Start a process in route card
     */
    public function startProcess(int $routeCardId, int $processId): JsonResponse
    {
        try {
            $process = RouteCardProcess::where('route_card_id', $routeCardId)
                ->where('id', $processId)
                ->firstOrFail();

            $process->update([
                'status' => 'in_progress',
                'started_at' => now(),
            ]);

            return response()->json(['success' => true, 'message' => 'Process started.']);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => 'Failed to start process.'], 500);
        }
    }

    /**
     * Complete a process in route card
     */
    public function completeProcess(int $routeCardId, int $processId): JsonResponse
    {
        try {
            $process = RouteCardProcess::where('route_card_id', $routeCardId)
                ->where('id', $processId)
                ->firstOrFail();

            $process->update([
                'status' => 'completed',
                'completed_at' => now(),
            ]);

            // Check if all processes are completed
            $routeCard = RouteCard::findOrFail($routeCardId);
            $pendingProcesses = $routeCard->processes()->where('status', '!=', 'completed')->count();

            if ($pendingProcesses === 0) {
                $routeCard->update(['status' => 'completed']);
            }

            return response()->json(['success' => true, 'message' => 'Process completed.']);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => 'Failed to complete process.'], 500);
        }
    }

    /**
     * Print route card
     */
    public function print(int $id)
    {
        $routeCard = RouteCard::with(['salesOrder', 'processes.process', 'processes.machine'])->findOrFail($id);
        return $this->roleView('routecard.print', compact('routeCard'));
    }

    /**
     * Get sales order details (AJAX)
     */
    public function getSalesOrderDetails(int $id): JsonResponse
    {
        $salesOrder = SalesOrder::with('customer')->find($id);

        if (!$salesOrder) {
            return response()->json(['success' => false, 'message' => 'Sales Order not found'], 404);
        }

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

    /**
     * Get process list (AJAX)
     */
    public function getProcessList(): JsonResponse
    {
        $processes = Process::orderBy('order')->get();
        return response()->json(['success' => true, 'processes' => $processes]);
    }

    /**
     * Get planned route cards list (AJAX)
     */
    public function plannedList(): JsonResponse
    {
        $cards = RouteCard::with(['salesOrder', 'processes'])
            ->where('status', 'planned')
            ->latest()
            ->get();
        return response()->json(['success' => true, 'data' => $cards]);
    }

    /**
     * Get ready for production route cards list (AJAX)
     */
    public function readyToProductionList(): JsonResponse
    {
        $cards = RouteCard::with(['salesOrder', 'processes'])
            ->where('status', 'ready_for_production')
            ->latest()
            ->get();
        return response()->json(['success' => true, 'data' => $cards]);
    }
}
