<?php

namespace App\Http\Controllers\SuperAdmin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Models\PurchaseOrder;
use App\Models\PurchaseOrderItem;
use App\Models\CustomerVendor;

use App\Models\PurchaseQuotation as Quotation;
use App\Models\RfqType;
use App\Models\StockItem;


class SuperAdminPurchaseController extends Controller
{
    // Show the PO create form
    public function purchasePage()
    {
        Log::info("SuperAdmin accessed Purchase Order Form");
        
        $rfqTypes = RfqType::all();
        $stock_items = StockItem::all();
        
        return view('superadmin.purchase.purchaseorder', compact('rfqTypes','stock_items'));
    }
    
    public function print($id)
    {
        $po = \App\Models\PurchaseOrder::with(['items', 'vendor'])->findOrFail($id);
        return view('superadmin.purchase.print', compact('po'));
    }
    
    // List all purchase orders
    public function purchaseDetails()
    {
        Log::info("SuperAdmin accessed Purchase Details Page");
        $purchaseOrders = PurchaseOrder::with('vendor')->orderBy('id', 'desc')->get();
        return view('superadmin.purchase.purchasedetails', compact('purchaseOrders'));
    }
    
    // Approve PO
    public function approve($id)
    {
        try {
            $po = PurchaseOrder::findOrFail($id);
            $po->status = 'approved';
            $po->save();
    
            return response()->json(['message' => 'Purchase Order approved successfully']);
        } catch (\Exception $e) {
            return response()->json(['error' => 'Failed to approve order'], 500);
        }
    }
    
    // Reject PO
    public function reject($id)
    {
        try {
            $po = PurchaseOrder::findOrFail($id);
            $po->status = 'rejected';
            $po->save();
    
            return response()->json(['message' => 'Purchase Order rejected']);
        } catch (\Exception $e) {
            return response()->json(['error' => 'Failed to reject order'], 500);
        }
    }

    // Show PO details (view page)
    public function show($id)
    {
        $po = PurchaseOrder::with(['items', 'vendor','items.stockItem'])->findOrFail($id);
        return view('superadmin.purchase.show', compact('po'));
    }

    // Get PO details as JSON (for AJAX/edit)
    public function getPurchaseOrderById($id)
    {
        $order = PurchaseOrder::with(['items', 'vendor'])->findOrFail($id);
        return response()->json($order);
    }

    // Get all vendor quotations (for dropdown)
    public function getQuotations()
    {
        $quotations = Quotation::where('status', 'approved')
            ->whereDoesntHave('PurchaseOrder')
            ->orderBy('id', 'desc')
            ->get(['id', 'quotation_no']);
    
        return response()->json($quotations);
    }

    // Get single vendor quotation by id (for autofill)
    public function getQuotationById($id)
    {
        $quotation = Quotation::with('items')->find($id);
    
        if (!$quotation) {
            return response()->json(['error' => 'Quotation not found'], 404);
        }
    
        return response()->json($quotation);
    }

    // Generate the next PO ID
    public function generatePOId()
    {
        try {
            $lastPo = PurchaseOrder::orderByDesc('id')->first();
            if ($lastPo && isset($lastPo->purchase_order_no)) {
                $lastId = intval(preg_replace('/[^0-9]/', '', substr($lastPo->purchase_order_no, -4)));
            } else {
                $lastId = 0;
            }
            $newId = str_pad($lastId + 1, 4, '0', STR_PAD_LEFT);
            $poId = "UEPL/PO/{$newId}";
            return response()->json(['so_id' => $poId]);
        } catch (\Exception $e) {
            return response()->json(['so_id' => 'UEPL/PO/0001']);
        }
    }

    // Store new PO
    public function store(Request $request)
    {
        Log::info('[PurchaseOrder] Store called');
        try {
            Log::info('[PurchaseOrder] Incoming request data:', $request->all());
    
            $validated = $request->validate([
                'sOrderNo' => 'required|unique:purchase_orders,purchase_order_no',
                'sOrderDate' => 'required|date',
                'soCompanyName' => 'required|string',
                'grandTotal' => 'required|numeric',
            ]);
            Log::info('[PurchaseOrder] Validation passed', $validated);
    
            DB::beginTransaction();
    
            
    
            $purchaseOrder = PurchaseOrder::create([
                'purchase_order_no'   => $request->input('sOrderNo'),
                'purchase_order_date' => $request->input('sOrderDate'),
                'quotation_no'        => $request->input('quotationNo2') ?? null,
                'quotation_date'      => $request->input('quotationDate') ?? null,
                'customer_ref_no'     => $request->input('custRefNo') ?? null,
                'company_name'        => $request->input('soCompanyName'),
                'vendor_id'           => $request->input('soCompanyId'),
                'company_address'     => $request->input('soCompanyAddress'),
                'company_gstn'        => $request->input('soCompanyGSTN'),
                'company_phone'       => $request->input('soCompanyPhone'),
                'company_email'       => $request->input('soCompanyEmail'),
                'bill_address'        => $request->input('billAddress') ?? null,
                'ship_address'        => $request->input('shipAddress') ?? null,
                'inr_in_words'        => $request->input('inr_in_words') ?? null,
                'subtotal'            => $request->input('totalAmount'),
                'sgst_amount'         => $request->input('sgstA'),
                'cgst_amount'         => $request->input('cgstA'),
                'igst_amount'         => $request->input('IgstA'),
                'round_up'            => $request->input('roundUp'),
                'grand_total'         => $request->input('grandTotal'),
                'rfq_no'              => $request->input('rfqNo') ?? null,
                'rfq_date'            => $request->input('rfqDate') ?? null,
                'description'         => $request->input('projectDescription') ?? null,
                'delivery_terms'      => $request->input('deliveryTerms') ?? null,
                'additional_charges'  => $request->input('additionalCharges') ?? null,
                'note'                => $request->input('note') ?? null,
            ]);
    
            Log::info('[PurchaseOrder] PurchaseOrder created', ['id' => $purchaseOrder->id]);
    
            $items = $request->input('tableProducts');
            Log::info('[PurchaseOrder] tableProducts received:', ['tableProducts' => $items]);
    
            if (!is_array($items)) {
                throw new \Exception("Invalid or missing 'tableProducts' array in request");
            }
    
            foreach ($items as $item) {
                PurchaseOrderItem::create([
                    'purchase_order_id'     => $purchaseOrder->id,
                    'sl_no'                 => $item['slNo'] ?? null,
                    'item'                  => $item['item'] ?? null,
                    'description'           => $item['description'] ?? null,
                    'req_by_date'           => $item['req_by_date'] ?? null,
                    'quantity'              => $item['quantity'] ?? 0,
                    'uom'                   => $item['uom'] ?? null,
                    'unit_rate'             => $item['unit_rate'] ?? 0,
                    'tds'                   => $item['tds'] ?? 0,
                    'discount'              => $item['discount'] ?? 0,
                    'value'                 => $item['value'] ?? 0,
                    'sgst'                  => $item['sgst'] ?? 0,
                    'cgst'                  => $item['cgst'] ?? 0,
                    'igst'                  => $item['igst'] ?? 0,
                    'amount'                => $item['amount'] ?? 0,
                ]);
            }
    
            DB::commit();
            Log::info('[PurchaseOrder] Purchase order saved successfully', ['id' => $purchaseOrder->id]);
    
            return response()->json([
                'message' => 'Purchase Order saved successfully!',
                'id' => $purchaseOrder->id
            ], 201);
    
        } catch (\Illuminate\Validation\ValidationException $e) {
            DB::rollBack();
            Log::error('[PurchaseOrder] Validation failed', [
                'errors' => $e->validator->getMessageBag(),
            ]);
            return response()->json([
                'error' => 'Validation failed',
                'details' => $e->validator->getMessageBag()
            ], 422);
    
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('[PurchaseOrder] Exception occurred', [
                'message' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
                'request_data' => $request->all()
            ]);
            return response()->json([
                'error' => 'Server error occurred',
                'message' => $e->getMessage()
            ], 500);
        }
    }

    // Edit purchase order (returns view)
    public function edit($id)
    {
        $stock_items = StockItem::all();
        $po = PurchaseOrder::with('items', 'vendor')->findOrFail($id);
        $vendors = CustomerVendor::where('company_role', 'Vendor')->select('id', 'company')->get();
        $editOrderId = $id;
        return view('superadmin.purchase.edit', compact('po', 'vendors', 'editOrderId','stock_items'));
    }

    // Update existing purchase order
    public function update(Request $request, $id)
    {
        Log::info("[PurchaseOrder] Update called for ID: $id");
    
        try {
            Log::info("[PurchaseOrder] Incoming request data:", $request->all());
    
            $validated = $request->validate([
                'soNo1'          => 'required|unique:purchase_orders,purchase_order_no,' . $id,
                'soDate'         => 'required|date',
                'soCompanyName'  => 'required|string',
                'grandTotal'     => 'required|numeric',
            ]);
            Log::info("[PurchaseOrder] Validation passed", $validated);
    
            DB::beginTransaction();
    
            $purchaseOrder = PurchaseOrder::findOrFail($id);
    
            $purchaseOrder->update([
                'purchase_order_no'   => $request->input('soNo1'),
                'purchase_order_date' => $request->input('soDate'),
                'company_name'        => $request->input('soCompanyName'),
                'vendor_id'           => $request->input('soCompanyId'),
                'quotation_no'        => $request->input('quotationId') ?? null,
                'quotation_date'      => $request->input('quotationDate') ?? null,
                'customer_ref_no'     => $request->input('custRefNo') ?? null,
                'company_address'     => $request->input('soCompanyAddress'),
                'company_gstn'        => $request->input('soCompanyGSTN'),
                'company_phone'       => $request->input('soCompanyPhone'),
                'company_email'       => $request->input('soCompanyEmail'),
                'bill_address'        => $request->input('billAddress') ?? null,
                'ship_address'        => $request->input('shipAddress') ?? null,
                'inr_in_words'        => $request->input('inr_in_words') ?? null,
                'subtotal'            => $request->input('totalAmount'),
                'sgst_amount'         => $request->input('sgstA'),
                'cgst_amount'         => $request->input('cgstA'),
                'igst_amount'         => $request->input('IgstA'),
                'round_up'            => $request->input('roundUp'),
                'grand_total'         => $request->input('grandTotal'),
                'rfq_no'              => $request->input('rfqNo') ?? null,
                'rfq_date'            => $request->input('rfqDate') ?? null,
                'description'         => $request->input('projectDescription') ?? null,
                'delivery_terms'      => $request->input('deliveryTerms') ?? null,
                'additional_charges'  => $request->input('additionalCharges') ?? null,
                'note'                => $request->input('note') ?? null,
            ]);
    
            Log::info("[PurchaseOrder] PurchaseOrder updated", ['id' => $purchaseOrder->id]);
    
            // Replace existing items
            $purchaseOrder->items()->delete();
    
            $items = $request->input('tableProducts');
            Log::info("[PurchaseOrder] tableProducts received:", ['tableProducts' => $items]);
    
            if (!is_array($items)) {
                throw new \Exception("Invalid or missing 'tableProducts' array in request");
            }
    
            foreach ($items as $item) {
                PurchaseOrderItem::create([
                    'purchase_order_id' => $purchaseOrder->id,
                    'sl_no'             => $item['sl_no'] ?? null,
                    'item'              => $item['item'] ?? null,
                    'description'       => $item['description'] ?? null,
                    'req_by_date'       => $item['req_by_date'] ?? null,
                    'quantity'          => $item['quantity'] ?? 0,
                    'uom'               => $item['uom'] ?? null,
                    'unit_rate'         => $item['unit_rate'] ?? 0,
                    'tds'               => $item['tds'] ?? 0,
                    'discount'          => $item['discount'] ?? 0,
                    'value'             => $item['value'] ?? 0,
                    'sgst'              => $item['sgst'] ?? 0,
                    'cgst'              => $item['cgst'] ?? 0,
                    'igst'              => $item['igst'] ?? 0,
                    'amount'            => $item['amount'] ?? 0,
                ]);
            }

    
            DB::commit();
            Log::info('[PurchaseOrder] Purchase order updated successfully', ['id' => $purchaseOrder->id]);
    
            return response()->json([
                'message' => 'Purchase Order updated successfully!',
                'id' => $purchaseOrder->id
            ], 200);
    
        } catch (\Illuminate\Validation\ValidationException $e) {
            DB::rollBack();
            Log::error('[PurchaseOrder] Validation failed', [
                'errors' => $e->validator->getMessageBag(),
            ]);
            return response()->json([
                'error' => 'Validation failed',
                'details' => $e->validator->getMessageBag()
            ], 422);
    
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('[PurchaseOrder] Exception occurred', [
                'message' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
                'request_data' => $request->all()
            ]);
            return response()->json([
                'error' => 'Server error occurred',
                'message' => $e->getMessage()
            ], 500);
        }
    }

    // Delete purchase order
    public function destroy($id)
    {
        try {
            $order = PurchaseOrder::findOrFail($id);
            $order->items()->delete();
            $order->delete();

            return response()->json(['message' => 'Purchase Order deleted successfully']);
        } catch (\Exception $e) {
            return response()->json(['error' => 'Failed to delete order'], 500);
        }
    }
}
