<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Models\WorkOrder;
use App\Models\Product;
use App\Models\Bom;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;

class WorkOrderController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index(Request $request)
    {
        $workOrders = WorkOrder::with('product', 'bom')->latest()->paginate(10);

        if ($request->wantsJson() || $request->is('api/*')) {
            return response()->json($workOrders);
        }

        return view('work_orders.index', compact('workOrders'));
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        $products = Product::whereHas('activeBom')->get();
        $productionLines = \App\Models\ProductionLine::all();
        $machines = \App\Models\Machine::all();
        return view('work_orders.create', compact('products', 'productionLines', 'machines'));
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'product_id' => 'required|exists:products,id',
            'production_line_id' => 'nullable|exists:production_lines,id',
            'machine_id' => 'nullable|exists:machines,id',
            'quantity' => 'required|numeric|min:1',
            'priority' => 'required|in:low,medium,high,urgent',
            'start_date' => 'required|date',
            'end_date' => 'required|date|after_or_equal:start_date',
        ]);

        if ($validator->fails()) {
            return back()->withErrors($validator)->withInput();
        }

        // Get active BOM
        $product = Product::findOrFail($request->product_id);
        $bom = $product->activeBom;

        if (!$bom) {
            return back()->with('error', 'Product has no active BOM. Cannot create work order.');
        }

        $workOrder = WorkOrder::create([
            'work_order_no' => 'WO-' . strtoupper(Str::random(8)),
            'product_id' => $request->product_id,
            'bom_id' => $bom->id,
            'production_line_id' => $request->production_line_id,
            'machine_id' => $request->machine_id,
            'quantity' => $request->quantity,
            'start_date' => $request->start_date,
            'end_date' => $request->end_date,
            'priority' => $request->priority,
            'status' => 'draft',
            'notes' => $request->notes,
        ]);

        return redirect()->route('work-orders.index')->with('success', 'Work Order ' . $workOrder->work_order_no . ' created.');
    }

    /**
     * Display the specified resource.
     */
    public function show(Request $request, WorkOrder $workOrder)
    {
        $workOrder->load(['product', 'bom.items.component', 'productionLine', 'machine']);

        if ($request->wantsJson() || $request->is('api/*')) {
            return response()->json($workOrder);
        }

        return view('work_orders.show', compact('workOrder'));
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, WorkOrder $workOrder)
    {
        $oldStatus = $workOrder->status;
        $newStatus = $request->status;

        if ($newStatus == 'in_progress' && $oldStatus != 'in_progress') {
            return $this->startProduction($workOrder);
        }

        if ($newStatus == 'completed' && $oldStatus != 'completed') {
            return $this->completeProduction($workOrder);
        }

        $workOrder->update($request->only(['status', 'priority', 'notes', 'start_date', 'end_date', 'production_line_id', 'machine_id']));

        return back()->with('success', 'Work order updated.');
    }

    private function startProduction(WorkOrder $workOrder)
    {
        try {
            \Illuminate\Support\Facades\DB::beginTransaction();

            $bom = $workOrder->bom;
            foreach ($bom->items as $item) {
                $requiredQty = $item->quantity * $workOrder->quantity;
                $requiredQty += ($requiredQty * ($item->waste_percentage / 100));

                // Find stock in any warehouse
                $inventory = \App\Models\Inventory::where('product_id', $item->product_id)
                    ->where('quantity', '>=', $requiredQty)
                    ->first();

                if (!$inventory) {
                    throw new \Exception("Insufficient stock for component: " . $item->component->name);
                }

                $inventory->quantity -= $requiredQty;
                $inventory->save();

                \App\Models\StockMovement::create([
                    'product_id' => $item->product_id,
                    'warehouse_id' => $inventory->warehouse_id,
                    'type' => 'out',
                    'quantity' => $requiredQty,
                    'reference_type' => 'WorkOrder',
                    'reference_id' => $workOrder->id,
                    'user_id' => \Illuminate\Support\Facades\Auth::id() ?? 1,
                    'notes' => 'Consumed for WO: ' . $workOrder->work_order_no,
                ]);
            }

            $workOrder->update(['status' => 'in_progress']);

            \Illuminate\Support\Facades\DB::commit();
            return back()->with('success', 'Production started. Materials consumed from inventory.');
        } catch (\Exception $e) {
            \Illuminate\Support\Facades\DB::rollBack();
            return back()->with('error', $e->getMessage());
        }
    }

    private function completeProduction(WorkOrder $workOrder)
    {
        try {
            \Illuminate\Support\Facades\DB::beginTransaction();

            // Find a finished goods warehouse
            $warehouse = \App\Models\Warehouse::where('type', 'finished_goods')->first();
            if (!$warehouse) {
                throw new \Exception("No finished goods warehouse found. Create one first.");
            }

            $inventory = \App\Models\Inventory::firstOrNew([
                'product_id' => $workOrder->product_id,
                'warehouse_id' => $warehouse->id,
            ]);

            $inventory->quantity += $workOrder->quantity;
            $inventory->save();

            \App\Models\StockMovement::create([
                'product_id' => $workOrder->product_id,
                'warehouse_id' => $warehouse->id,
                'type' => 'in',
                'quantity' => $workOrder->quantity,
                'reference_type' => 'WorkOrder',
                'reference_id' => $workOrder->id,
                'user_id' => \Illuminate\Support\Facades\Auth::id() ?? 1,
                'notes' => 'Finished product from WO: ' . $workOrder->work_order_no,
            ]);

            $workOrder->update(['status' => 'completed']);

            \Illuminate\Support\Facades\DB::commit();
            return back()->with('success', 'Work order completed. Finished goods added to warehouse.');
        } catch (\Exception $e) {
            \Illuminate\Support\Facades\DB::rollBack();
            return back()->with('error', $e->getMessage());
        }
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(WorkOrder $workOrder)
    {
        if ($workOrder->status != 'draft') {
            return back()->with('error', 'Only draft work orders can be deleted.');
        }
        $workOrder->delete();
        return redirect()->route('work-orders.index')->with('success', 'Work order deleted.');
    }
}
