<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\PurchaseOrder;
use App\Models\Partner;
use App\Models\Product;
use Illuminate\Support\Str;

class PurchaseOrderController extends Controller
{
    public function index(Request $request)
    {
        $purchaseOrders = PurchaseOrder::with('partner')->latest()->paginate(10);
        return view('purchase_orders.index', compact('purchaseOrders'));
    }

    public function create()
    {
        $partners = Partner::whereIn('type', ['supplier', 'both'])->active()->get();
        $products = Product::all();
        return view('purchase_orders.create', compact('partners', 'products'));
    }

    public function store(Request $request)
    {
        $request->validate([
            'partner_id' => 'required|exists:partners,id',
            'order_date' => 'required|date',
            'items' => 'required|array|min:1',
            'items.*.product_id' => 'required|exists:products,id',
            'items.*.quantity' => 'required|numeric|min:0.0001',
            'items.*.unit_price' => 'required|numeric|min:0',
        ]);

        try {
            \DB::beginTransaction();

            $po = PurchaseOrder::create([
                'po_number' => 'PO-' . strtoupper(Str::random(8)),
                'partner_id' => $request->partner_id,
                'order_date' => $request->order_date,
                'expected_date' => $request->expected_date,
                'notes' => $request->notes,
                'status' => 'draft',
            ]);

            $total = 0;
            foreach ($request->items as $item) {
                $lineTotal = $item['quantity'] * $item['unit_price'];
                $po->items()->create([
                    'product_id' => $item['product_id'],
                    'quantity' => $item['quantity'],
                    'unit_price' => $item['unit_price'],
                    'total_price' => $lineTotal,
                ]);
                $total += $lineTotal;
            }

            $po->update(['total_amount' => $total]);

            \DB::commit();
            return redirect()->route('purchase-orders.show', $po->id)->with('success', 'Purchase Order created.');
        } catch (\Exception $e) {
            \DB::rollBack();
            return back()->with('error', 'Error creating PO: ' . $e->getMessage());
        }
    }

    public function show(PurchaseOrder $purchaseOrder)
    {
        $purchaseOrder->load('partner', 'items.product');
        return view('purchase_orders.show', compact('purchaseOrder'));
    }

    public function update(Request $request, PurchaseOrder $purchaseOrder)
    {
        if ($request->status == 'received' && $purchaseOrder->status != 'received') {
            return $this->receiveGoods($purchaseOrder);
        }

        $purchaseOrder->update($request->only('status', 'notes', 'expected_date'));
        return back()->with('success', 'Purchase Order updated.');
    }

    private function receiveGoods(PurchaseOrder $purchaseOrder)
    {
        try {
            \DB::beginTransaction();

            // Find or create default raw material warehouse
            $warehouse = \App\Models\Warehouse::where('type', 'raw_materials')->first()
                ?? \App\Models\Warehouse::first();

            if (!$warehouse) {
                throw new \Exception("No warehouse found to receive goods.");
            }

            foreach ($purchaseOrder->items as $item) {
                $inventory = \App\Models\Inventory::firstOrNew([
                    'product_id' => $item->product_id,
                    'warehouse_id' => $warehouse->id,
                ]);

                $inventory->quantity += $item['quantity'];
                $inventory->save();

                \App\Models\StockMovement::create([
                    'product_id' => $item->product_id,
                    'warehouse_id' => $warehouse->id,
                    'type' => 'in',
                    'quantity' => $item['quantity'],
                    'reference_type' => 'PurchaseOrder',
                    'reference_id' => $purchaseOrder->id,
                    'user_id' => \Auth::id() ?? 1,
                    'notes' => 'Received from PO: ' . $purchaseOrder->po_number,
                ]);
            }

            $purchaseOrder->update(['status' => 'received']);

            \DB::commit();
            return back()->with('success', 'Goods received and inventory updated.');
        } catch (\Exception $e) {
            \DB::rollBack();
            return back()->with('error', 'Error receiving goods: ' . $e->getMessage());
        }
    }
}
